TT Lab
开始
学习 学习路径 课程

Apache Hadoop — 在一个 Pod 里搭起并运维 HDFS 与 YARN

打开 fsimage 和 edits,读出命名空间

在 TT Lab 中继续学习

目标

亲手打开看看 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 增加负担的情况下,分析全部的文件列表、大小和所有者。找出小文件集中在哪里,通常就是从这里开始的。

步骤

  1. 把 hdfs dfsadmin -safemode get 的输出保存到 /root/hdp/meta/safemode.txt。
  2. 把 /data/finance/q1.csv 上传为 /user/root/meta/q1.csv 之后,进入安全模式(-safemode enter),尝试创建 /user/root/meta/in-safemode 目录,并把错误输出保存到 /root/hdp/meta/deny.txt。
  3. 保持安全模式,执行 hdfs dfsadmin -saveNamespace,把新生成的 fsimage 的 txid(文件名中的数字)以整数写入 /root/hdp/meta/fsimage_txid.txt。
  4. 退出安全模式(-safemode leave),创建 /user/root/meta/after-save 目录。
  5. 用 hdfs oiv -p XML 把第 3 步的 fsimage 解析并写入 /root/hdp/meta/fsimage.xml。
  6. 用 hdfs oiv -p Delimited 把同一个 fsimage 解析并写入 /root/hdp/meta/fsimage.tsv。
  7. 用 hdfs dfsadmin -rollEdits 关闭当前正在写入的 edits 分段,再用 hdfs oev 把包含第 4 步所创建目录的已关闭分段(edits_<시작>-<끝>,占位符依次为起始与结束事务编号)解析并写入 /root/hdp/meta/edits.xml,然后把该分段的名称和 OP_MKDIR 的个数,按 {"segment": "edits_…-…", "OP_MKDIR": 정수} 的格式写入 /root/hdp/meta/ops.json(占位符为整数)。
  8. 在 /root/hdp/meta/report.md 中写出 ## 안전 모드、## fsimage、## edits 三个小节。第二节写入第 3 步的 txid,第三节写入第 7 步的 OP_MKDIR 个数。

参考

是否处于安全模式

把 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 在哪里有、在哪里没有。