内容提要
HDFS FsImage是NameNode的元数据快照,记录文件系统目录树和块映射。核心流程包括加载和保存,采用Protobuf格式,支持并行处理。加载时通过LoaderDelegator自动检测新旧格式,保存时按固定顺序写入各section。系统包含压缩管理、存储检查、HTTP传输和离线查看工具,配置参数可控制压缩和并行加载行为。
延伸解读
格式兼容与自动检测
FsImage 文件以固定魔数 'HDFSIMG1' 开头,LoaderDelegator 通过读取前 8 字节自动判断新旧格式,无需人工干预。新格式基于 Protobuf,支持并行加载和压缩,而旧格式仅用于向后兼容,主要服务于离线查看工具。这种设计使得升级和回滚过程更加平滑,但需注意新旧格式在序列化细节上的差异。
并行加载与保存的权衡
并行加载和保存通过将 INode 和目录 section 拆分为子 section 实现,由线程池处理,可显著加快大集群的元数据恢复速度。但并行加载默认关闭(dfs.image.parallel.load=false),需手动开启,且并行保存有阈值(默认100万 INode)和子 section 数量限制。启用时需关注线程数配置,避免资源竞争。
压缩与校验的可靠性
FsImage 支持压缩(默认关闭),压缩仅作用于各 section,魔数和 FileSummary 不压缩,确保文件头可读。每个镜像附带 .md5 校验文件,加载时异步计算 MD5 并与文件对比,确保数据完整性。保存时也会生成 MD5 文件,并在检测到损坏时触发进程退出,防止使用损坏的镜像。
存储检查与恢复机制
存储检查器(FSImageStorageInspector)负责扫描存储目录,识别镜像文件并记录事务 ID。当前格式基于事务 ID 命名,旧格式基于文件名。启动时若发现镜像损坏,会自动尝试其他副本,并在必要时重新保存。此外,NameNode 会定期 checkpoint,清理旧镜像,保持元数据最新。
Q&A
HDFS FsImage 文件的作用是什么?
FsImage 是 HDFS NameNode 的元数据快照文件,记录了整个文件系统的目录树和文件块映射关系,用于在 NameNode 重启时恢复元数据。
HDFS FsImage 文件的物理布局是怎样的?
FsImage 文件以 8 字节的 MAGIC 'HDFSIMG1' 开头,随后是多个 section,文件末尾是 FileSummary 和 4 字节的 FileSummaryLength。FileSummary 包含所有 section 的偏移量、长度、layoutVersion、ondiskVersion 和压缩编码。每个 section 可独立压缩,但 MAGIC 和 FileSummary 不压缩。
FsImage 加载时如何检测新旧格式?
加载时通过 LoaderDelegator 读取文件前 8 字节,如果等于 MAGIC 'HDFSIMG1' 则使用 Protobuf 格式的 Loader,否则使用旧版格式的 Loader。
FsImage 保存时各 section 的写入顺序是什么?
保存时按固定顺序写入:NS_INFO、ERASURE_CODING、INODE、SNAPSHOT、SNAPSHOT_DIFF、INODE_REFERENCE、SECRET_MANAGER、CACHE_MANAGER、STRING_TABLE。
如何启用 FsImage 的并行加载?
通过设置配置参数 dfs.image.parallel.load=true 启用并行加载,并行线程数由 dfs.image.parallel.threads 控制(默认 2)。并行加载主要针对 INODE 和 INODE_DIR 的子 section,每个子 section 由一个线程处理,使用 CountDownLatch 同步。
FsImage 文件如何校验完整性?
每个 FsImage 文件附带一个 .md5 校验文件。加载时启动 DigestThread 异步计算文件 MD5,并与 .md5 文件对比;保存时通过 MD5FileUtils.saveMD5File() 写入 MD5 文件。
FsImage 支持哪些压缩配置?
FsImage 压缩由 dfs.image.compress 控制(默认 false),压缩编码器由 dfs.image.compress.codec 指定(默认 DefaultCodec)。压缩时每个 section 独立压缩,但 MAGIC 和 FileSummary 不压缩。
OfflineImageViewer 如何离线查看 FsImage?
OfflineImageViewer 通过 FSImageLoader 独立于 NameNode 环境运行,解析 FsImage 的 Protobuf section,将 INode 按 id 排序存储在内存中,支持 getFileStatus() 和 listStatus() 返回 JSON 格式的文件状态和目录列表。