订阅更新

NameNode挂了整个集群瘫痪——HDFS高可用和元数据管理

Hadoop手册 第 3 题 约 8 分钟读完

本文目录
  1. 先说结论
  2. NameNode存了什么?——FsImage和EditLog
  3. NameNode HA架构——双节点+JournalNode
  4. Checkpoint机制——防止EditLog无限增长
  5. 故障切换流程——Active挂了怎么办?
  6. 实战踩坑:NameNode Full GC导致的集群抖动
  7. 面试高频追问
  8. 总结

先说结论

NameNode高可用(HA)通过Active/Standby双节点实现:Active NameNode处理所有读写请求,Standby NameNode实时同步元数据随时接管。两者通过JournalNode集群共享EditLog(操作日志)。如果Active挂了,Standby在秒级内自动切换为Active,客户端几乎无感知。

面试核心概念:① NameNode存了什么(FsImage+EditLog);② HA怎么实现(JournalNode+ZooKeeper);③ 元数据的持久化流程(Checkpoint机制)。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

NameNode是HDFS的'大脑'——所有文件的元数据(文件名、目录结构、Block位置)都存在NameNode的内存里。如果NameNode挂了,整个HDFS就瘫痪了,所有读写操作都会失败。在某知名出海硬件品牌用EMR时,有一次NameNode因为内存不足触发了Full GC,暂停了30秒,导致大量Spark作业报错'Connection refused'。虽然GC完自动恢复了,但这30秒的抖动让下游几十个作业都需要重跑。从那以后我深刻理解了NameNode高可用的重要性。

NameNode存了什么?——FsImage和EditLog

# NameNode的元数据由两部分组成
#
# FsImage(文件系统镜像):
#   整个文件系统的完整快照
#   包含:目录树、文件属性、每个文件的Block列表
#   存在NameNode本地磁盘上
#   启动时加载到内存
#
# EditLog(操作日志):
#   记录所有对文件系统的变更操作
#   比如:createFile、deleteFile、mkdir、addBlock等
#   每次操作先写EditLog再修改内存
#   类似MySQL的Binlog
#
# NameNode启动流程:
# 1. 加载FsImage到内存(恢复上次的完整状态)
# 2. 回放EditLog(应用上次之后的所有变更)
# 3. 进入SafeMode等待DataNode汇报Block信息
# 4. 退出SafeMode,开始服务

NameNode HA架构——双节点+JournalNode

# NameNode HA架构
#
#  ┌──────────┐    ┌──────────┐
#  │ Active   │    │ Standby  │
#  │ NameNode │    │ NameNode │
#  └────┬─────┘    └────┬─────┘
#       │               │
#       │  EditLog同步  │
#       ↓               ↓
#  ┌──────────────────────────┐
#  │    JournalNode集群       │
#  │  JN-1   JN-2   JN-3    │
#  └──────────────────────────┘
#
#  ┌──────────────────────────┐
#  │    ZooKeeper集群         │  ← 负责选举Active/Standby
#  │  ZK-1   ZK-2   ZK-3    │  ← ZKFC(ZK Failover Controller)
#  └──────────────────────────┘
#
# Active NN把EditLog写入JournalNode集群
# Standby NN从JournalNode读取EditLog并回放
# 保证Standby的元数据和Active完全一致
# Active挂了,ZK通知Standby切换为Active
组件数量职责
Active NameNode1个处理所有客户端读写请求
Standby NameNode1个实时同步元数据,随时接管
JournalNode3个(奇数)存储EditLog,Active和Standby之间的桥梁
ZooKeeper3个(奇数)监控NN健康状态,触发故障切换
ZKFC每个NN一个向ZK注册,检测本机NN健康状况

Checkpoint机制——防止EditLog无限增长

如果EditLog一直增长不合并,NameNode重启时回放EditLog就会花很长时间。Checkpoint机制定期把EditLog合并到FsImage中:

# Checkpoint流程(由Standby NameNode执行)
#
# 1. Standby NN定期检查(默认1小时或EditLog达到100万条)
# 2. 把当前内存中的FsImage写出一个新的FsImage文件
# 3. 把新FsImage传给Active NN
# 4. Active NN用新FsImage替换旧的
# 5. 清空已合并的EditLog
#
# 好处:
# ① EditLog不会无限增长
# ② NameNode重启时只需加载最新FsImage + 少量EditLog
# ③ 重启时间从可能的几十分钟降到几分钟
#
# 相关配置:
# dfs.namenode.checkpoint.period = 3600  (每小时)
# dfs.namenode.checkpoint.txns = 1000000 (每100万条操作)

故障切换流程——Active挂了怎么办?

自动故障切换(Automatic Failover)的流程:

① 检测:ZKFC持续监控本机NameNode的健康状态。如果Active NN无响应(心跳超时),ZKFC在ZooKeeper上释放锁。

② 选举:Standby NN的ZKFC检测到Active的锁释放了,抢注ZK的锁,获得Active身份。

③ 隔离(Fencing):新Active NN先确保旧Active NN真的停了(通过SSH kill或特殊隔离机制),防止'脑裂'——两个NN同时认为自己是Active。

④ 切换:新Active NN开始处理客户端请求。客户端通过配置的逻辑名称(nameservice)自动连接到新Active NN。

整个过程通常在10-30秒内完成。

实战踩坑:NameNode Full GC导致的集群抖动

在某知名出海硬件品牌用EMR时,HDFS上存了约5亿个文件(含大量小文件),NameNode需要约60GB内存来存储元数据。有一次Java GC触发了Full GC(Stop-The-World),整个NameNode暂停了30秒。

虽然30秒后GC完成NN恢复了(没有触发HA切换),但这30秒内所有HDFS操作都超时了。正在运行的几十个Spark作业因为读不到HDFS数据纷纷报错,大部分需要重跑。

解决措施:① NameNode的JVM从默认的G1 GC调优——增大新生代、降低GC暂停阈值;② 清理历史小文件,把文件数从5亿降到2亿,NN内存需求从60GB降到25GB;③ 最终决定迁移到Databricks+S3——S3没有NameNode的单点瓶颈,元数据由AWS内部管理,彻底解决了这个问题。

面试高频追问

追问一:脑裂(Split Brain)是什么?怎么防止?

脑裂是指两个NameNode都认为自己是Active,同时接受写请求,导致元数据不一致。HDFS通过Fencing机制防止——新Active在切换前先确保旧Active已经停止(SSH kill或断开JournalNode连接)。JournalNode也有保护:同一时间只允许一个NN写入EditLog。

追问二:NameNode的内存为什么是瓶颈?

NameNode把整个文件系统的元数据都存在内存里。每个文件/目录约占150字节,每个Block约占150字节。1亿个文件+3亿个Block就需要约60GB内存。文件越多内存越大,而单机内存有上限。这就是HDFS不适合存大量小文件的根本原因——不是存储空间不够,而是NameNode的内存撑不住。

追问三:HDFS Federation是什么?

Federation让多个NameNode各管一部分命名空间(namespace),类似数据库的水平分片。比如NN-1管/user目录,NN-2管/warehouse目录。这样元数据分散在多个NN上,突破单个NN的内存瓶颈。但Federation的运维复杂度很高,大部分公司选择迁移到S3而不是搞Federation。

总结

NameNode高可用面试讲清楚三个层面:① NameNode存了什么(FsImage+EditLog,全部在内存里);② HA怎么实现(Active/Standby双节点+JournalNode同步EditLog+ZooKeeper选举);③ 故障切换流程(检测→选举→Fencing隔离→切换,10-30秒完成)。NameNode的内存瓶颈是HDFS最大的架构局限——也是很多公司迁移到S3的核心原因。能讲出Full GC导致集群抖动的实际经历和最终迁移S3的决策过程,面试官会很满意。

下一篇聊一个经典的HDFS问题:上传了10万个小文件,集群直接卡死了——小文件问题怎么解决?

你们的HDFS NameNode配了多大内存?有没有遇到过NN相关的问题?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器