Secondary NameNode 主要用于辅助 NameNode 进行元数据的管理和检查点(Checkpoint)的生成。
Secondary NameNode 的工作机制可以分为以下步骤:
Secondary NameNode 会定期(由 dfs.namenode.checkpoint.period 和 dfs.namenode.checkpoint.txns 配置决定)向 NameNode 发送请求,询问是否需要执行 Checkpoint。
NameNode 会根据 edits 日志的大小和操作数量决定是否需要 Checkpoint。
如果 NameNode 决定执行 Checkpoint,Secondary NameNode 会向 NameNode 发送 Checkpoint 请求。
NameNode 停止向当前的 edits 日志文件写入新的操作,并创建一个新的 edits 日志文件用于记录后续操作。
旧的 edits 日志文件被标记为只读,并重命名为一个普通的 edits 日志文件。
NameNode 将滚动前的 edits 日志文件和当前的 fsimage 文件拷贝到 Secondary NameNode。
Secondary NameNode 将拷贝的 edits 日志文件和 fsimage 文件加载到内存中。
将 edits 日志中的操作应用到 fsimage 上,生成一个新的、包含最新元数据的 fsimage 文件。
Secondary NameNode 将合并后的元数据写入一个新的 fsimage 文件(如 fsimage.chkpoint)。
Secondary NameNode 将生成的 fsimage.chkpoint 文件拷贝回 NameNode。
NameNode 将 fsimage.chkpoint 重命名为 fsimage,替换旧的 fsimage 文件。
同时,NameNode 会删除已经合并的 edits 日志文件,因为它们的操作已经被应用到新的 fsimage 中。
在 HDFS 中,NameNode 负责管理文件系统的元数据(如文件目录结构、文件块信息等)。为了保证元数据的一致性,NameNode 会将所有的元数据修改操作(如创建文件、删除文件等)记录到一个称为 edits 日志 的文件中。
由于 edits 日志会不断增长,为了避免日志文件过大,HDFS 会定期将 edits 日志中的操作合并到 fsimage 中,这个过程称为 Checkpoint。
在 Secondary NameNode 执行 Checkpoint 的过程中, “滚动正在写的 edits 日志” 主要是如下过程:
这个过程称为 日志滚动(Log Rolling),目的是将当前的 edits 日志文件冻结,以便 Secondary NameNode 可以安全地将其拷贝走并进行合并操作。
滚动 edits 日志的目的是为了确保 Checkpoint 的一致性。
可以恢复部分元数据。Secondary NameNode 保存了上一次 Checkpoint 的 fsimage 和 edits 日志文件,可以恢复上一次 Checkpoint 时的元数据。
无法恢复全部元数据。从上一次 Checkpoint 到 NameNode 崩溃期间,NameNode 可能接收了新的元数据修改请求,这些请求记录在 NameNode 正在写的 edits 日志文件中。由于这些 edits 日志文件没有被拷贝到 Secondary NameNode,因此这部分元数据无法恢复。
随着时间的推移,edits 日志文件会变得非常大,导致以下问题:
Secondary NameNode 的作用就是定期将 edits 日志中的操作合并到 fsimage 中,生成一个新的 fsimage 文件,从而减少 edits 日志的大小,优化 NameNode 的性能。
Secondary NameNode 会定期(由配置参数 dfs.namenode.checkpoint.period 和 dfs.namenode.checkpoint.txns 决定)触发 Checkpoint 过程。
在 Checkpoint 过程中,Secondary NameNode 会从 NameNode 获取当前的 fsimage 和 edits 日志文件,将它们加载到内存中,合并生成一个新的 fsimage 文件。
新的 fsimage 文件会被传回 NameNode,替换旧的 fsimage 文件,同时删除已经合并的 edits 日志文件。
尽管 Secondary NameNode 在元数据管理中起到了重要作用,但它并不是 NameNode 的高可用(HA)解决方案,存在以下局限性:
Secondary NameNode 只是定期合并 fsimage 和 edits 日志,生成新的 fsimage 文件,并不能实时备份 NameNode 的元数据。
如果 NameNode 崩溃,Secondary NameNode 只能提供上一次 Checkpoint 的元数据,无法恢复从上一次 Checkpoint 到崩溃期间的数据(这些数据记录在 NameNode 正在写的 edits 日志文件中)。
Secondary NameNode 并不能接管 NameNode 的工作,它只是一个辅助工具。
在 Hadoop 2.x 及更高版本中,引入了 NameNode 高可用(HA) 方案,通过以下方式解决 Secondary NameNode 的局限性:
两个 NameNode 同时运行,一个处于 Active 状态,负责处理客户端请求;另一个处于 Standby 状态,实时同步 Active NameNode 的元数据。
Active NameNode 将 edits 日志写入共享存储,Standby NameNode 从共享存储读取 edits 日志并应用到自己的内存中,保持元数据的实时同步。
如果 Active NameNode 崩溃,Standby NameNode 会立即接管工作,确保系统的高可用性。