ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Secondary NameNode不是备机?一文讲透NameNode与Checkpoint协同机制

Secondary NameNode不是备机?一文讲透NameNode与Checkpoint协同机制 1. 先拆一个流传已久的老误区Secondary NameNode不是“备用机”有一次我们集群的NameNode进程异常退出一个刚接手项目的同事直接问“那我们把服务切到Secondary NameNode上行不行”我当时赶紧叫停了。这个想法很危险因为Secondary NameNode从设计上就不具备接管能力它不接收客户端读写请求不接收DataNode心跳也不保存实时的元数据镜像更不会在主节点故障时自动顶上去。很多人被“Secondary”这个单词带偏了以为它类似数据库的备机、Redis的Slave。实际上HDFS官方对它的定位非常明确Checkpoint Server翻译过来就是“检查点服务器”。它的唯一核心职责是定期把NameNode磁盘上的edits日志合并进fsimage快照让NameNode在重启时不用回放一个膨胀到几GB的流水账。我们可以用一个生活化的类比来理解NameNode是营业厅里全天候接待客户、实时办理业务的柜员Secondary NameNode则是每天下班后悄无声息把当天流水整理成总账的会计。这个“整理总账”的动作就是HDFS集群元数据高可用的幕后功臣。1.1 它不能接管故障一次错误failover尝试的教训我见过不止一个团队尝试在NameNode挂了之后直接修改客户端配置指向Secondary NameNode的地址结果当然是服务完全不可用。根本原因有两点第一Secondary NameNode的内存里没有实时元数据。NameNode所有关于文件、目录、数据块与DataNode映射的关键信息都在内存中Secondary NameNode只是在周期性的merge周期里拿到一份fsimage增量副本它的数据新鲜度最多追上上一次checkpoint之后新产生的所有操作它根本不知道。你把流量切过去它连当前集群有哪些文件、每个文件对应哪些block都说不清楚。第二Secondary NameNode不接收DataNode的心跳和块报告。DataNode只向NameNode的RPC地址8020/9820等端口注册Secondary NameNode在集群拓扑里根本不在这个位置上。即便强行改了客户端地址整个数据链路也建立不起来。所以请记住在非HA架构的传统HDFS集群里NameNode依然是单点。Secondary NameNode能被动救急但绝不是一个能主动接管服务的“备机”。1.2 官方定位Checkpoint Server而非BackupNode早期的HDFS设计文档里确实认真考虑过一种叫做BackupNode的角色它持有完整的内存镜像理论上可以更快地完成故障恢复。但后来的实现里这个角色没有成为主流我们看到的是Secondary NameNode以“checkpoint节点”的身份出现。它的工作过程简单说就是定期从NameNode拉取fsimage和edits文件在本地合并生成新的fsimage再传回NameNode。至于NameNode当前内存里有哪些文件、哪些block正在写入、哪些租约还没过期它完全不接触。理解这一点之后再回头看“Secondary NameNode有没有用”这个问题答案就会变成它不是一个热备节点但它是HDFS元数据文件系统里非常重要的“健康维护者”。2. NameNode的元数据宇宙fsimage、edits与内存镜像为何缺一不可要理解NameNode和Secondary NameNode的协同先得把NameNode的元数据存储机制吃透。HDFS元数据管理最核心的“三件套”是内存镜像、fsimage文件和edits日志这三者缺一不可。2.1 三个“账本”的分工与数据流向先说内存镜像。NameNode运行期间所有文件和目录的树形结构、文件属性、每个文件对应的block列表、block大小、副本因子以及DataNode上报上来的“block位置映射”全部保存在JVM堆内存里。为什么必须放内存因为HDFS每一次读写路径都要查元数据如果每次都去磁盘上翻性能会低到无法接受。可以说内存镜像就是NameNode对外服务时的“工作底稿”。再说fsimage。这是内存镜像在某个时间点的完整持久化快照保存着整个文件系统的命名空间信息包括文件、目录、副本数、block ID和block大小。注意fsimage里没有“block落在哪几台DataNode上”这种映射关系因为DataNode的位置信息是DataNode启动后、运行中动态上报给NameNode内存的这块数据天然就是易变的。最后是edits日志。它像数据库的WAL日志一样记录从最近一次fsimage之后所有的写操作比如创建文件、删除目录、修改副本因子、追加写等。HDFS的做法是任何一次元数据变更先追加写入edits日志成功后再更新内存视图。这样即使进程崩溃重启时靠fsimage加edits也能把状态恢复到崩溃前的那一刻。2.2 客户端写入时NameNode到底先动哪个文件拿最常见的“创建文件”举例。客户端调用create接口后NameNode会做这几件事在内存中锁定目标路径检查父目录是否存在、权限是否允许。生成一条“创建文件”的事务记录分配一个递增的txid也就是事务编号。把这条事务记录追加到当前正在写的edits_inprogress文件中并调用fsync确保落盘。落盘成功后才真正修改内存镜像把新的文件或目录节点加进命名空间树。这个过程有一个很容易被忽略但很关键的顺序问题必须先落edits再改内存顺序不能反。因为如果进程在步骤2和3之间崩溃内存里还没有这次操作日志也没有系统状态依然一致反过来如果先改了内存再写日志一旦日志没落盘就崩溃就会出现“内存里有、磁盘上没有”的孤儿状态恢复时头都大了。2.3 为什么不能让fsimage频繁落盘有人会问既然fsimage是完整快照直接把内存镜像频繁刷进fsimage不行吗当然不行。fsimage是整个文件系统的一个全量快照文件数量到了几千万上亿之后一次全量序列化极其耗CPU、耗内存、耗磁盘IO而且序列化过程中还得保证文件系统树不被并发修改业务会被拖死。所以HDFS采用了一个非常务实的折中平时所有细微变更都写在轻量的edits流水账里每隔一段时间才用checkpoint机制把账本合并一次生成一个全新的fsimage。这个“每隔一段时间”的活在传统架构里就是交给Secondary NameNode去干的。3. Checkpoint协同流程Secondary NameNode如何“替主节点整理内务”现在终于到核心问题NameNode和Secondary NameNode具体是怎么协同的这里面的细节很容易被官方文档一句“定期合并”带过但真正理解之后你会对HDFS的启动速度、安全模式、edits膨胀等问题都有全新的认识。3.1 触发条件一小时与一百万笔谁先到算谁Secondary NameNode不是没头没脑每分钟都去合并它有非常明确的触发条件。老版本里我们看fs.checkpoint.period和fs.checkpoint.size新版本则重点关注这几个参数dfs.namenode.checkpoint.period默认3600秒也就是1个小时。dfs.namenode.checkpoint.txns默认1000000也就是100万笔事务。dfs.namenode.checkpoint.check.period默认60秒Secondary NameNode每隔60秒去检查一次是否满足触发条件。触发逻辑很简单时间超过1小时或者edits里的事务数超过100万满足任一条件就触发checkpoint。这样设计的意图很清晰如果集群业务量很低1小时一次足够如果业务量大哪怕还没到1小时edits涨到100万笔就必须合并防止日志膨胀得太快。3.2 六步协同细节从滚动edits到原子替换真正执行一次checkpoint时两个节点的配合大约分六步Secondary NameNode决定触发checkpoint先向NameNode发起一个HTTP请求告诉它“我要开始合并了”。NameNode收到请求后会先做一次edits滚动把当前正在写的edits_inprogress_00000000000xxx改名封闭成edits_00000000000xxx同时立刻新建一个空的edits_inprogress_00000000000yyy后续的新事务继续往新的inprogress文件里写。这一步是协同的基石它相当于给合并动作划了一个清晰的时间线Secondary NameNode要合并的是滚动点之前的日志滚动点之后的新操作不受影响。Secondary NameNode通过HTTP从NameNode下载已经封闭的edits文件段以及当前最新的fsimage文件。Secondary NameNode在本地把这堆文件加载进自己的JVM内存逐条回放edits把这段时间的所有增量操作合并到基础镜像上。合并完成后Secondary NameNode在本地生成一个新的fsimage.checkpoint文件再通过HTTP回传给NameNode。NameNode收到新的fsimage后用原子重命名的方式替换掉磁盘上旧fsimage然后清理已经合并过的edits段更新seen_txid记录。至此一次完整的checkpoint协同结束。3.3 版本一致性、目录隔离与常见的兼容性问题协同过程里最容易踩的坑是Secondary NameNode和NameNode的软件版本不一致。我见过有人拿Hadoop 2.7的Secondary NameNode去配合Hadoop 3.1的NameNode使用结果合并时直接报layout version不兼容fsimage加载失败。另外Secondary NameNode本地配置的目录必须和NameNode磁盘目录隔离。把dfs.namenode.name.dir和dfs.namenode.checkpoint.dir配在同一块磁盘是新手常犯的错误。想象一下checkpoint是一场高强度合并工作如果它和NameNode正在进行的edits落盘写IO抢同一块物理盘两边都会变慢更极端的情况是磁盘故障时两份关键数据一起报废。所以生产环境里这两份目录最好放在不同的磁盘甚至不同的机器物理路径上。4. 全维度对比职责、IO、故障响应、恢复耗时一次看穿很多人背了一堆HDFS概念但真要让他说清NameNode和Secondary NameNode的区别又只能说出“一个主一个备”。这里我把它们放进一张表从职责到IO再到故障响应逐项对比看完基本不会再混淆。4.1 一张表格对比两者的“人设”对比维度NameNodeSecondary NameNode处理客户端读写请求是所有元数据操作的权威入口否完全透明接收DataNode心跳和块报告是实时维护block映射否不参与数据面保存内存实时元数据是运行时的唯一权威否只有合并时临时加载快照保存fsimage是最终落地文件在NameNode本地是但只是周期性拉取的副本保存edits日志是实时追加写入是但仅保留最近一次合并需要的副本自动接管故障否除非配置HA否天生不具备CPU和内存压力高持续服务所有请求中只在合并窗口内集中消耗关键配置项dfs.namenode.name.dirdfs.namenode.checkpoint.dir一眼就能看出NameNode是全天候在线的中枢而Secondary NameNode更像是定时上岗的“整理工”。4.2 为什么启动时间差的本质是edits合并频率NameNode启动时要做的事有两步加载fsimage到内存然后回放此后所有的edits。如果上一次checkpoint发生在1小时前启动时只需要回放这1小时的增量如果集群的checkpoint机制坏了、或者Secondary NameNode一直没跑edits可能积压几十个小时、几十GB启动时间自然从几分钟变成几十分钟。这点我在生产环境里深有体会。有次一个集群NameNode重启花了35分钟日志里全是“Loading edits file”的记录最后发现是Secondary NameNode已经默默死了一个多月没人发现。直观理解就是总账本越旧流水账就越厚重新入账就越慢。Secondary NameNode的checkpoint频率直接决定了NameNode的“开机速度”。4.3 从“checkpoint时间戳”看协同留下的痕迹平时进NameNode的元数据目录你会看到fsimage_000000000000001234、edits_000000000000001234这类带数字后缀的文件。这些数字就是事务ID。观察这些文件能直接判断协同节奏。比如NameNode上fsimage_...的txid长期不往前走就看到Secondary NameNode日志里有没有“Checkpoint complete”如果完全没有说明协同链路早就断了。所以说这两个节点的协同不是抽象的它肉眼可见地反映在元数据文件的编号推进里。5. 回到热搜现场SafeMode、startup加载页、fsck未授权到底怎么回事单看机制容易晕我们把几个高频搜索词一起拿过来串一遍很多网上搜到的问题其实都能从NameNode与Secondary NameNode的协同机制里找到答案。5.1 SafeMode不是“故障”是NameNode启动时的自我保护很多人一看到“NameNode处于安全模式”就紧张。其实安全模式是NameNode启动流程中的正常阶段。它加载完fsimage、回放完edits之后需要等待DataNode一个个汇报自己持有block的位置信息同时检查这些block是否满足最小副本数的要求。在安全模式下整个文件系统对外是只读的任何写操作都会被拒绝SafeModeException就是这么来的。不少同学遇到这种情况直接执行hdfs dfsadmin -safemode leave强行退出这是有风险的。正确操作是先看hdfs dfsadmin -safemode get确认状态再看hdfs dfsadmin -report确认缺失block数量和DataNode的连接数量。如果大量block还没上报完强行退出安全模式只会让集群带着残缺的元数据对外服务。5.2 「namenode is still loading」出现后我的排查顺序“namenode is still loading. redirecting to the startup progress page.”这句话经常出现在浏览器访问NameNode Web界面时。它说明NameNode进程虽然起来了但还处在加载元数据的阶段HTTP服务尚未完全就绪。遇到这种情况我的排查顺序一般是先看NameNode运行日志注意$HADOOP_HOME/logs/hadoop-hdfs-namenode-$(hostname).log。重点搜索Loading edits file、Number of transactions这些行确认现在回放到哪个阶段。如果长时间卡在同一个edits文件上要么是那个文件太大要么是磁盘IO出问题。接下来检查Secondary NameNode的日志hadoop-hdfs-secondarynamenode-*.log看最近有没有“Checkpoint complete”。如果压根没有那就说明fsimage长期没更新这次启动要把积压的日志都回放一遍自然慢。还有一个高效的应急手段如果edits膨胀已经非常严重在维护窗口内把集群进入安全模式执行hdfs dfsadmin -saveNamespace强制让NameNode自己做一次checkpoint把edits合并掉然后再退出安全模式。这样下次重启的速度会明显改善。5.3 hdfs fsck被拒也要分级超管权限、网关地址与Web fsck“hdfs fsck未授权”这个词被搜索的频率很高很多人是在自己电脑上直接跑hdfs fsck / -files -blocks -locations然后被AccessControlException拒绝。这个问题通常不是命令语法错而是权限模型在起作用。fsck命令本质上是一个NameNode服务端操作它要求执行者具备特定权限。最简单的处理办法是到集群里用HDFS超级用户执行或者在命令里显式指定-fs hdfs://namenode-host:8020。如果只是想快速看健康状态可以直接用NameNode Web界面内置的fsck页面http://namenode-host:9870/fsck?path/files1blocks1用浏览器打开就能看到按块统计的健康报告完全绕开客户端权限配置的麻烦。当然这只适合只读检查真要修复问题还是得在服务端处理。6. 生产环境进阶元数据备份、手动Checkpoint与HA替代理解机制只是第一步最终都要落到生产运维上。这里把几个重要的进阶操作和思考一一说清楚。6.1 手动触发检查点saveNamespace的正确时机与风险集群运行正常时Secondary NameNode会自动执行checkpoint。但有两类场景需要手动介入一是Secondary NameNode已经坏了而edits日志还在快速膨胀二是准备对集群做重要变更想先制造一份新鲜的fsimage。手动触发hdfs的命名空间保存可以用hdfs dfsadmin -safemode enter hdfs dfsadmin -saveNamespace hdfs dfsadmin -safemode leave注意saveNamespace要求NameNode处于安全模式而进入安全模式意味着所有写请求都会被拒绝。所以这个操作必须选在业务低峰或者明确维护窗口里做否则就是在用业务中断换元数据安全。执行完以后去元数据目录看一眼会发现fsimage的txid已经跳到最新位置了。6.2 元数据备份的双保险策略了解了fsimage和edits的分工之后备份策略就会清晰很多。单纯备份fsimage不够没有对应的edits元数据会丢失窗口期内的所有变更。单纯备份edits也不够没有基础镜像回放无从谈起。我的做法是NameNode本机的dfs.namenode.name.dir配置多个目录尽量分散到不同磁盘同时用定时任务把最近的fsimage定期拉到另一台机器上归档配合Secondary NameNode的checkpoint目录形成“双保险”。最理想的情况是NameNode本机一份、Secondary NameNode一份、远程归档一份。这样即便NameNode所在机器磁盘彻底报废也能用Secondary NameNode的那份新镜像加尽可能找回的edits拼凑出最近的状态。6.3 HA架构为什么把Secondary NameNode请出了场聊到最后必须提一下现代HDFS集群为什么越来越少看到Secondary NameNode的踪影。因为HDFS HA架构里引入了Standby NameNode它通过JournalNodes实时同步主NameNode的事务日志内存中始终有一份几乎实时更新的元数据镜像。Standby NameNode既能随时接替Active节点又能顺带承担checkpoint职责把合并后的fsimage直接分发回Active节点。相比之下Secondary NameNode既不能实时同步所有操作也不能自动切换唯一的价值就只剩下“远程合并edits”。所以在新集群规划里两节点HA加上JournalNodes基本已经是标配Secondary NameNode正式退居历史舞台。但如果你问我现在还值不值得学Secondary NameNode机制我的答案依然是值得。因为这一整套“fsimage加edits、滚动日志、checkpoint协同、安全模式启动”的思想至今仍然是HDFS元数据管理的地基理解了它你再看HA、看Federation、看Ozone那些新东西都会顺畅得多。我在实际运维中最深的体会就是元数据问题大多不是突然爆炸的而是从一次被忽略的Checkpoint complete消失开始的。早一点看懂协同日志就能晚一点在深夜抢修。
返回列表