HDFS(Hadoop 分布式文件系统)知识点梳理
一、HDFS 基础认知
1. 定义与起源
- 起源:源自 Google 2003 年发表的 GFS(Google File System)论文,是 GFS 的开源克隆版。
- 定位:运行在普通低成本机器上的分布式文件系统,自带容错机制,提供高性能存储服务。
2. 核心优缺点
| 类别 | 具体特性 |
| 优点 | 1. 高容错:数据自动多副本存储,副本丢失可自动恢复<br>2. 适配批量处理:移动计算而非数据,暴露数据位置给计算框架<br>3. 支持大数据:兼容 TB/PB 级数据、百万级文件、10K+ 节点<br>4. 流式访问:一次写入、多次读取,保证数据一致性<br>5. 低成本:基于廉价机器构建,多副本保障可靠性 |
| 缺点 | 1. 低延迟差:无法满足毫秒级响应(需权衡高吞吐)<br>2. 小文件处理弱:大量小文件占用 NameNode 内存,寻道时间超读取时间<br>3. 写入不灵活:不支持并发写入,仅允许单个 Writer,仅支持追加写入 |
二、HDFS 核心设计
1. 数据块(Block)设计
- 默认大小:64MB(可配置),文件不足 64MB 时单独占一个块。
- 划分原则:平衡数据传输时间与磁盘寻道时间。
- 存储方式:文件被切分为多个块,默认每个块存 3 个副本,分散在不同节点。
2. 核心设计思想
- 分而治之:海量数据拆分到多节点存储,通过分布式架构提升容量、增加吞吐。
- 取舍逻辑:牺牲低延迟、随机修改等灵活性,优先保障高吞吐、高可靠、高扩展。
三、HDFS 架构组成(主从架构)
| 组件 | 角色 | 核心功能 |
| Active NameNode | 主节点(唯一) | 1. 管理文件系统命名空间<br>2. 维护数据块与节点的映射关系<br>3. 配置副本策略<br>4. 处理客户端读写请求 |
| Standby NameNode | 主节点热备 | 1. 定期合并 fsimage(文件系统镜像)和 editslog(操作日志)<br>2. 推送合并结果给 Active NameNode<br>3. Active 故障时快速切换为主节点 |
| DataNode | 从节点(多个) | 1. 存储实际数据块<br>2. 执行数据块的读写操作<br>3. 定期向 NameNode 发送心跳报告状态 |
| Client | 客户端 | 1. 写入时切分文件<br>2. 与 NameNode 交互获取文件位置<br>3. 与 DataNode 直接读写数据 |
四、HDFS 核心流程
1. 写流程(客户端写入文件)
1. Client 向 NameNode 发送“创建文件”请求,NameNode 校验后返回可用 DataNode 列表。
2. Client 将文件切分为数据块,按顺序向第一个 DataNode 写入数据。
3. 数据通过“DataNode 管道”自动复制到其他副本节点(默认 3 个)。
4. 每个 DataNode 写入完成后向 Client 返回确认(Ack)。
5. 所有数据块写入完成,Client 向 NameNode 发送“完成”请求,更新元数据。
2. 读流程(客户端读取文件)
1. Client 向 NameNode 发送“打开文件”请求,NameNode 返回数据块及存储节点信息。
2. Client 根据节点信息,向距离最近的 DataNode 读取数据块。
3. 所有数据块读取完成后,Client 在本地拼接成完整文件,关闭输入流。
五、HDFS 关键策略
1. 副本放置策略
- 副本 1:存储在与 Client 相同节点(若 Client 不在集群内,则随机选一个节点)。
- 副本 2:存储在与副本 1 不同机架的节点(提升跨机架容错性)。
- 副本 3:存储在与副本 2 相同机架的其他节点(平衡性能与容错)。
- 更多副本:随机分配到集群节点。
2. 可靠性保障策略
| 故障场景 | 应对措施 |
| 文件损坏 | 通过 CRC32 校验检测损坏数据,自动用其他副本替换受损块。|
| DataNode 失效 | DataNode 定期向 NameNode 发送心跳,超时未响应则标记为失效,触发副本补全。|
| NameNode 失效 | 依赖 FSImage 和 EditsLog 实现元数据恢复;通过 Standby NameNode 实现主备实时切换。 |
3. 小文件处理问题
- 核心痛点:每个小文件的元数据(约 150Byte)占用 NameNode 内存,大量小文件会耗尽内存;且寻道时间长,访问效率低。
- 示例:1 亿个 10K 小文件仅占 1TB 存储,却需消耗 20GB NameNode 内存。
六、HDFS 访问与管理
1. 常用 Shell 命令
| 功能 | 命令示例 |
| 本地文件上传到 HDFS | `hadoop fs -copyFromLocal /local/data /hdfs/data` |
| HDFS 文件下载到本地 | `hadoop fs -copyToLocal /hdfs/data /local/data` |
| 创建 HDFS 目录 | `hadoop fs -mkdir /hdfs/data` |
| 删除 HDFS 文件/目录 | `hadoop fs -rmr /hdfs/data` |
| 查看 HDFS 目录内容 | `hadoop fs -ls /hdfs/data` |
2. 集群管理脚本(`sbin` 目录下)
- 启动全集群:`start-all.sh`
- 停止全集群:`stop-all.sh`
- 启动 HDFS:`start-dfs.sh`
- 单独启动 NameNode:`hadoop-deamon.sh start namenode`
- 单独启动 DataNode:`hadoop-deamons.sh start datanode`
3. 节点增删操作
- 添加 DataNode:
1. 复制现有 DataNode 的安装包及配置文件到新节点。
2. 执行 `sbin/hadoop-deamon.sh start datanode` 启动新节点。
- 删除失效 DataNode:
1. 在 NameNode 配置文件 `dfs.hosts.exclude` 中添加待删除节点的 IP/主机名。
2. 执行 `bin/hadoop dfsadmin -refreshNodes` 使配置生效。
4. Java API 核心用法
核心类(均来自 `org.apache.hadoop.fs` 包):
- `Configuration`:封装 HDFS 配置信息。
- `FileSystem`:文件系统操作核心类,通过 `FileSystem.get(config)` 获取实例。
- `FSDataInputStream`/`FSDataOutputStream`:HDFS 文件输入/输出流,分别通过 `open()` 和 `create()` 方法获取。
七、HDFS 拓扑结构
- 集群节点按 机架(Rack)划分,每个机架通常包含 16 - 64 个节点。
- NameNode、Secondary NameNode、Client 等部署在独立节点,DataNode 分布式部署在各机架节点,通过交换机连接,形成层级网络结构,兼顾性能与容错。