Apache Hadoop — 在一个 Pod 里搭起并运维 HDFS 与 YARN
打开 fsimage 和 edits,读出命名空间
目标
亲手打开看看 NameNode 是如何把命名空间保存到磁盘上的——某个时间点的快照 fsimage,以及此后的变更记录 edits。观察安全模式下写入被拒绝,用 saveNamespace 生成新的 fsimage,并用离线镜像查看器(oiv)和离线编辑日志查看器(oev)读取其内容。
为什么重要
NameNode 把整个文件树放在内存中工作。内存一断电就会消失,所以要把两样东西留在磁盘上。fsimage 是截止到某个事务编号(txid)为止的完整命名空间,edits 则是此后发生的变更(创建目录、关闭文件、重命名等等)逐行记录的日志。NameNode 重新启动时,会读取 fsimage,再重新应用其后的 edits。
edits 变长会使启动变慢,所以需要定期合并进 fsimage(检查点)。在生产环境中,由 Secondary NameNode 或 Standby NameNode 来做;在本实验中,则用管理员命令 saveNamespace 亲自去做。这条命令要求处于安全模式,是因为保存期间命名空间不能发生变化。
安全模式是 NameNode 只接受读取的状态。刚启动时,在收集到足够多的 DataNode 块报告之前会自动进入,管理员为了做某些操作,也会手动把它切入这种状态。“所有写入都失败”这类故障,它是常见的原因。
如果会离线读取 fsimage,就能在不给运行中的 NameNode 增加负担的情况下,分析全部的文件列表、大小和所有者。找出小文件集中在哪里,通常就是从这里开始的。
步骤
- 把
hdfs dfsadmin -safemode get的输出保存到 /root/hdp/meta/safemode.txt。 - 把
/data/finance/q1.csv上传为 /user/root/meta/q1.csv 之后,进入安全模式(-safemode enter),尝试创建 /user/root/meta/in-safemode 目录,并把错误输出保存到 /root/hdp/meta/deny.txt。 - 保持安全模式,执行
hdfs dfsadmin -saveNamespace,把新生成的 fsimage 的 txid(文件名中的数字)以整数写入 /root/hdp/meta/fsimage_txid.txt。 - 退出安全模式(
-safemode leave),创建 /user/root/meta/after-save 目录。 - 用
hdfs oiv -p XML把第 3 步的 fsimage 解析并写入 /root/hdp/meta/fsimage.xml。 - 用
hdfs oiv -p Delimited把同一个 fsimage 解析并写入 /root/hdp/meta/fsimage.tsv。 - 用
hdfs dfsadmin -rollEdits关闭当前正在写入的 edits 分段,再用hdfs oev把包含第 4 步所创建目录的已关闭分段(edits_<시작>-<끝>,占位符依次为起始与结束事务编号)解析并写入 /root/hdp/meta/edits.xml,然后把该分段的名称和 OP_MKDIR 的个数,按{"segment": "edits_…-…", "OP_MKDIR": 정수}的格式写入 /root/hdp/meta/ops.json(占位符为整数)。 - 在 /root/hdp/meta/report.md 中写出
## 안전 모드、## fsimage、## edits三个小节。第二节写入第 3 步的 txid,第三节写入第 7 步的 OP_MKDIR 个数。
参考
- NameNode 的元数据目录:
/var/lib/hadoop/name/current——fsimage_<txid>(及.md5)、edits_<시작>-<끝>(已关闭的分段)、edits_inprogress_<시작>(正在写入)、seen_txid(占位符依次为起始与结束事务编号)。 - fsimage 只保留最近的两个(
dfs.namenode.num.checkpoints.retained)。如果执行过多次 saveNamespace,请写最后一个的 txid。 hdfs oiv -p XML -i <fsimage> -o <출력>、hdfs oiv -p Delimited -i <fsimage> -o <출력>、hdfs oev -i <edits 파일> -o <출력>(默认输出格式是 XML;其中的占位符表示输入文件和输出文件)。- 常见错误:没有退出安全模式就进入下一步(所有写入都会失败),以及想用 oev 打开
edits_inprogress_(请打开已关闭的分段)。 - 官方文档:HDFS Architecture — The Persistence of File System Metadata · Offline Image Viewer · Offline Edits Viewer · HDFS Commands — dfsadmin
是否处于安全模式
把 hdfs dfsadmin -safemode get 的输出保存到 /root/hdp/meta/safemode.txt。
刚启动时会处于安全模式,直到块报告收集齐全才会自行退出。现在它应当是关闭的。如果是开启的,说明 NameNode 还在启动中,或者磁盘空间不足。
安全模式下写入会被拒绝
把 /data/finance/q1.csv 上传为 HDFS 的 /user/root/meta/q1.csv,然后用 hdfs dfsadmin -safemode enter 进入安全模式,并把 hdfs dfs -mkdir /user/root/meta/in-safemode 的错误输出保存到 /root/hdp/meta/deny.txt。
安全模式是把命名空间冻结起来的状态。读取(ls、cat)可以,但凡是修改名字的操作都会被拒绝。下一步的 saveNamespace 要求的正是这种状态——因为保存期间目录树不能发生变化。
saveNamespace——手动触发检查点
保持安全模式,执行 hdfs dfsadmin -saveNamespace,把 /var/lib/hadoop/name/current 中新生成的 fsimage_<txid> 的 txid,以整数写入 /root/hdp/meta/fsimage_txid.txt。
saveNamespace 会把内存中的命名空间写成新的 fsimage,并把 edits 切换到新的分段。文件名中的数字是“这个镜像反映到的最后一个事务编号”。请去掉前面的 0,以整数写入。
退出安全模式后再次写入
用 hdfs dfsadmin -safemode leave 退出安全模式,并创建 /user/root/meta/after-save 目录。
这个目录不在第 3 步的 fsimage 中,只记录在 edits 里。在第 5–7 步中,你会亲眼确认这个差异。
把 fsimage 解析成 XML
把第 3 步的 fsimage 文件(fsimage_<txid>)用 hdfs oiv -p XML -i <파일> -o /root/hdp/meta/fsimage.xml 解析并写出(占位符为 fsimage 文件)。
XML 的 NameSection 中有这个镜像的 txid,INodeSection 中则有每个 inode(文件、目录)的名称、权限和块。请找到 q1.csv 的块大小,并确认没有 after-save。评分器也会检查这两项。
解析成表格——分析用这种更方便
用 hdfs oiv -p Delimited -i <파일> -o /root/hdp/meta/fsimage.tsv 解析并写出同一个 fsimage(占位符为 fsimage 文件)。
Delimited 每个 inode 占一行,各列依次是路径、副本系数、修改时间、块大小、块数、文件大小、配额、权限、所有者、组。在有数百万个文件的集群中,想找出“哪个目录里小文件扎堆”时,就是把这张表读入电子表格或 Spark。
打开 edits 读取变更记录
用 hdfs dfsadmin -rollEdits 关闭当前正在写入的分段,再用 hdfs oev -i <파일> -o /root/hdp/meta/edits.xml 解析包含第 4 步所创建目录的已关闭分段 edits_<시작>-<끝>(占位符依次为 edits 文件与起始、结束事务编号)。把该分段的名称和其中 OP_MKDIR 的个数,按 {"segment": "edits_…-…", "OP_MKDIR": 정수} 的格式写入 /root/hdp/meta/ops.json(占位符为整数)。
edits 是每个事务都带有 OPCODE 和 TXID 的记录。紧接在第 3 步 txid 之后开始的分段中,有 after-save 的 OP_MKDIR。不要打开尚未关闭的 edits_inprogress_。
元数据保存在哪里、如何保存
在 /root/hdp/meta/report.md 中写出 ## 안전 모드、## fsimage、## edits 三个小节。第二节写入第 3 步的 txid,第三节写入第 7 步的 OP_MKDIR 个数。
请写出:NameNode 重新启动时,按什么顺序使用 fsimage 和 edits;after-save 在哪里有、在哪里没有。