0%

安全模式

HDFS 安全模式:NameNode 启动时为什么要”关门”一会儿?

NameNode 重启的时候,你会发现 HDFS 有一段时间只能读不能写——创建不了文件、删除不了目录、上传数据报错。

这不是故障,是 安全模式(Safe Mode) 在起作用。

安全模式是 NameNode 启动时的”保护期”——在元数据恢复完成、数据块状态确认清楚之前,先关门谢客,不让写操作进来捣乱。

NameNode 启动时,为什么不能立刻对外服务?

NameNode 重启后要做两件事,这两件事做完之前,文件系统的状态是不完整的:

1. 恢复元数据

NameNode 的元数据存在磁盘上,分两部分:

  • fsimage:某个时刻的元数据快照
  • edits:快照之后的每次操作记录

启动时,先把 fsimage 读到内存,再把 edits 里的操作重放一遍,才能恢复到最新的元数据状态。

这个过程需要时间。如果恢复没完成就让客户端写数据,元数据会乱。

2. 确认数据块状态

DataNode 启动后会向 NameNode 汇报自己有哪些块。NameNode 需要等 DataNode 都报上来,才知道每个块有几个副本、副本都在哪。

如果不等 DataNode 汇报完就开始读写,NameNode 可能告诉客户端”块在 A 节点”,但 A 节点其实还没上线——数据读不到。

所以 NameNode 启动后先进入安全模式:元数据恢复完、块状态确认完之前,只读不写。

安全模式下能做什么、不能做什么

操作类型 安全模式下
读文件(hdfs dfs -cat / -get) 可以
查目录(hdfs dfs -ls) 可以
创建目录(hdfs dfs -mkdir) 不行
上传文件(hdfs dfs -put) 不行
删除文件(hdfs dfs -rm) 不行
修改权限(hdfs dfs -chmod) 不行

只读不写——这是安全模式的核心规则。

安全模式的完整工作流程

  1. 元数据加载阶段**:
    • NameNode 启动后,首先将磁盘上的fsimage文件(文件系统元数据的快照)载入内存。
    • 接着 replay edits文件(记录自上次 fsimage 生成后的元数据变更操作),将这些操作应用到内存中的元数据,以恢复到最新状态。
    • 完成后,NameNode 会创建一个新的fsimage文件(替代旧的快照),并生成一个空的edits文件(用于记录后续的元数据变更),此时元数据在内存中初始化完成。
  2. 数据块状态收集阶段
    • 进入安全模式后,NameNode 开始接收 DataNode 的心跳和块报告。每个 DataNode 会上报其存储的所有数据块信息(块 ID、副本数、存储位置等)。
    • NameNode 根据 DataNode 的报告,统计每个数据块的副本数量,并判断是否满足最小副本数(由dfs.replication.min配置,默认值为 1)。
  3. 安全模式退出判断
    • 当满足以下条件时,安全模式自动退出:
      • 达到最小副本数的数据块比例超过阈值(由dfs.safemode.threshold.pct配置,默认值为 0.999f)。
      • 数据块状态稳定一段时间(由dfs.safemode.extension配置,默认值为 30 秒),确保数据块信息收集完整且无频繁变化。
    • 退出安全模式后,HDFS 恢复正常读写功能,NameNode 开始处理客户端的创建、删除、修改等操作,并根据数据块副本状态进行副本均衡(如对副本不足的数据块进行复制)。

两个关键数字:

参数 默认值 含义
dfs.safemode.threshold.pct 0.999(99.9%) 副本数达标的块比例超过这个值,才允许退出
dfs.safemode.extension 30000ms(30 秒) 达标后还要稳 30 秒,才真正退出

为什么达标了还要等 30 秒? 防止 DataNode 上报信息有波动——刚达标时可能还有 DataNode 没报完,稳 30 秒确认状态稳定。

DataNode 数量不够,安全模式一直退不出来

如果集群里 DataNode 没启动完整,某些块只有 1 个副本(甚至 0 个),副本数达标的块比例达不到 99.9%,安全模式就卡住了。

看这个报错就能确认:

1
Safe mode is ON. The reported blocks 0 needs additional 1 blocks to reach the threshold 0.9990.

怎么解决?

  1. 确认所有 DataNode 都启动了(jps 看进程)
  2. 如果 DataNode 都起来了但还是卡住,可能是某个块副本数永久不足(比如某个 DataNode 磁盘坏了)
1
2
# 手动退出安全模式
hdfs dfsadmin -safemode leave

注意:手动退出安全模式时,先确认集群状态正常、大部分 DataNode 在线。 如果真有块副本数不足,强制退出后这些块就是”危险块”,NameNode 会在后台启动副本复制补足。

手动操作命令

1
2
3
4
5
6
7
8
9
10
11
# 查看安全模式状态
hdfs dfsadmin -safemode get

# 进入安全模式
hdfs dfsadmin -safemode enter

# 退出安全模式
hdfs dfsadmin -safemode leave

# 等待安全模式自动退出(脚本里用,阻塞直到退出)
hdfs dfsadmin -safemode wait

什么时候需要手动进入安全模式? 集群维护、数据迁移、HDFS 升级等需要停写的场景。进安全模式后,所有写操作被拒绝,可以安全地做维护操作。

几个常见场景

场景1:集群刚启动,安全模式一直不退

DataNode 还没全部启动,块汇报不完整。

→ 等所有 DataNode 启动完成。如果 DataNode 启动失败,先排查 DataNode 的问题。

场景2:手动退出安全模式后,部分数据块副本不足

NameNode 后台会自动调度副本复制补足,观察一段时间即可。

1
2
# 查看副本不足的块
hdfs fsck / -list-corruptfileblocks

场景3:误操作进入安全模式,需要立刻退出

1
hdfs dfsadmin -safemode leave

欢迎关注我的其它发布渠道