基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

HDFS NameNode启动时的详细流程是怎样的?

知识点图片

HDFS NameNode 的启动流程是 Hadoop 体系中最核心的机制之一。为了保证数据的强一致性和高可用性,启动过程设计得非常严密。

我们可以将 NameNode 的启动全流程划分为以下 五个核心阶段


第一阶段:初始化与配置加载 (Initialization)

  1. 加载配置文件:NameNode 进程启动后,首先读取 core-site.xmlhdfs-site.xml 中的配置信息(如目录路径、RPC 端口、HTTP 端口、HA 配置等)。
  2. 环境校验:检查配置的本地数据目录(dfs.namenode.name.dir)是否存在且具有读写权限。如果是高可用(HA)模式,还会初始化与 JournalNode 集群的连接配置。
  3. 实例化核心组件:创建 FSNamesystem(管理文件系统元数据)、BlockManager(管理数据块与 DataNode 的映射关系)等核心对象。

第二阶段:元数据加载 (Metadata Loading) —— 【最核心步骤】

NameNode 并不把“文件存在哪个 DataNode 上”的信息持久化到磁盘,磁盘上只存文件目录树(Namespace)。

  1. 读取 FsImage(镜像文件)
    • NameNode 找到本地磁盘上最新的 fsimage 文件(例如 fsimage_0000000000000000100)。
    • 将该文件加载到内存中,构建出文件系统的目录树(Namespace)。此时内存中的状态是系统在某一个历史时间点的快照。
  2. 回放 EditLog(编辑日志)
    • 仅有 FsImage 是不够的,NameNode 会查找生成该 FsImage 之后的所有 edits 日志文件(例如 edits_0000000000000000101-0000000000000000200)。
    • 如果是 HA 架构,NameNode 会从 JournalNode 集群拉取尚未合并的 edits 日志。
    • 将这些日志在内存中逐条执行(回放),将内存中的目录树更新到系统关闭前最新的状态。
  3. 保存新的 Checkpoint(可选操作)
    • 元数据合并完成后,NameNode 会将内存中最新的目录树生成一个新的 fsimage 文件保存到本地磁盘,并生成一个新的、空的 edits 日志文件,更新 Transaction ID(事务ID)。

第三阶段:启动网络服务 (Service Startup)

元数据在内存中构建完毕后,NameNode 准备好对外通信:

  1. 启动 RPC Server:开启 RPC 服务(默认端口 8020 或 9000),开始接收 DataNode 的注册和心跳,以及客户端的请求。
  2. 启动 HTTP Server:开启 Web UI 服务(Hadoop 2.x 默认 50070 端口,Hadoop 3.x 默认 9870 端口),提供可视化管理界面。

第四阶段:进入安全模式与块汇报 (Safe Mode & Block Report)

此时的 NameNode 知道系统中有哪些文件,以及每个文件由哪些 Block 组成,但它 不知道这些 Block 实际存储在哪些 DataNode 上。因此必须进入安全模式

  1. 进入安全模式 (Safe Mode)
    • 在此模式下,文件系统是只读的。客户端无法进行上传、删除、修改副本数等操作,只能浏览目录或下载文件。
  2. DataNode 注册与心跳
    • 各个 DataNode 启动,通过 RPC 向 NameNode 注册自己,并开始周期性发送心跳(默认3秒一次)。
  3. 全量块汇报 (Block Report)
    • DataNode 扫描本地磁盘,将自己拥有的所有 Block 信息打包,发送给 NameNode。
    • NameNode 接收到汇报后,在内存的 BlockManager 中动态构建 Block -> DataNode 列表 的映射关系(BlockMap)。
  4. 校验与退出安全模式
    • NameNode 会不断统计已汇报的、满足最小副本数(dfs.namenode.replication.min,默认是 1)的 Block 数量。
    • 安全块比例 达到阈值(dfs.namenode.safemode.threshold-pct,默认 0.999,即 99.9% 的数据块都已经找到了至少一个副本)时。
    • 达到阈值后,NameNode 会再等待一段缓冲时间(dfs.namenode.safemode.extension,默认 30 秒),以期收到更多的 DataNode 汇报。
    • 缓冲时间结束后,自动退出安全模式
  5. 处理异常数据块:退出安全模式后,NameNode 会立即检查哪些块副本不足(触发复制)或哪些块副本过多(触发删除)。

第五阶段:HA 状态选举 (仅限 HA 模式)

如果在集群中配置了高可用(HA):

  1. NameNode 启动后初始状态均为 Standby(备用状态)。
  2. ZKFC(ZooKeeper Failover Controller)进程会参与 ZooKeeper 的排他锁选举。
  3. 选举成功的 NameNode 被切换为 Active(活跃状态),开始对外提供写入服务,并将后续的操作日志写入 JournalNode。
  4. 选举失败的 NameNode 保持 Standby 状态,持续从 JournalNode 读取 EditLog,充当热备和 Checkpoint(替代 SecondaryNameNode 功能)的角色。

总结:一图胜千言(流程精简版)

加载配置 ➡️ 读 FsImage 到内存 ➡️ 回放 EditLog 更新内存 ➡️ 启动 RPC/HTTP 服务 ➡️ 进入安全模式 ➡️ 接收 DataNode 块汇报 ➡️ 构建 BlockMap ➡️ 达到 99.9% 阈值并等待 30 秒 ➡️ 退出安全模式 ➡️ 正常对外服务 (或进行 HA 选举)

面试常考点提示

  • 为什么进入安全模式? 因为 NameNode 磁盘上不存 Block 位置信息,需要等 DataNode 汇报上来,期间为防数据误判丢失,必须只读。
  • Namespace 和 BlockMap 的区别? Namespace 是文件目录树(持久化在 FsImage),BlockMap 是块和节点映射关系(纯内存,每次启动靠 DataNode 汇报动态生成)。
00:00
00:00