HDFS 概述
定义: HDFS 是一个分布式文件管理系统,用来存储文件,通过目录树来定位文件;由多个服务器联合起来实现其功能,集群中的服务器由各自的角色。
应用场景: 适合一次写入多次读写的场景,支持追加、不支持修改。适合用来做数据分析,不适合做网盘使用
HDFS 优缺点
优点
- 高容错性: 通过增加副本的形式提高容错性,数据自动保存多个副本;某个副本丢失后,可自动恢复。
- 适合处理大数据: 数据规模(TB、PB级别以上);文件规模(百万规模以上文件数量)
- 可构建在廉价机器上,通过多副本机制,提高可靠性
缺点
- 不适合低延迟数据访问
- 无法高效的对大量的小文件进行存储
- 不支持并发写入、随即修改
HDFS 设计思想
- 大文件拆成块,分布在多态机器上:解决处理数据时的 IO 瓶颈
- 块均匀分布:解决负载均衡问题
HDFS 组成架构
- NameNode:
(1)处理 client 读写请求
(2)管理 HDFS 命名空间
(3)配置副本策略
(4)管理 block 映射信息
- DataNode:
(1)存储实际的数据块
(2)执行数据块的读/写操作
- Client:
(1)文件切分,Client 将文件切分成一个一个 block再上传
(2)与 NameNode 交互,获取文件位置信息
(3)与 DataNode 交互,读取或写入数据
(4)通过命令管理和访问 HDFS
- Secondary NameNode: 不是 NameNode 的热备,当 NameNode 过掉时,它并不能马上替换 NameNode 并提供服务
(1)辅助 NameNode ,分担工作量
(2)若NameNode出意外,可以用来恢复 NameNode
(3)定期合并 fsimage和fsedits,并推送给NameNode。
HDFS 文件块大小
HDFS 中文件再物理上分块存储,默认大小为 128M(2.x 版本),可以通过 blocksize 来规定。
假设寻址时间约为 10 ms,即查找到目标 block 的时间
寻址时间为传输时间的 1% 为最佳,所以传输时间 = 1s
磁盘的传输速率普遍为 100 M/s
最后可知,block 大小为 100 M
为什么块大小不能太小,也不能过大?
- blocksize 设置太小,数量增多,会增加寻址时间,程序一直再找块的开始位置
- blocksize 设置过大,则从磁盘传输数据的时间会明显大于定位这个块开始位置所需时间。导致程序再处理这块数据时,会非常慢。
因此,HDFS块的大小设置取决于磁盘传输速率
HDFS 数据流
HDFS 写数据流程

- 客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件,NameNode 检查目标文件是否存在,父目录是否存在以及是否有权限等。
- 如果NameNode 返回可以上传,客户端请求第一个 block 上传到哪几个 DataNode 服务器上;否则报 IO 异常。
- DataNode 返回 3 个节点(默认)
- Client 通过FSDataOutputStream 模块请求 DataNode 1上传数据, DataNode 1 收到请求会继续调用 DataNode 2,依次请求和调用,完成通信管道的建立。然后三个 DataNode 逐级应答客户端
- 客户端开始往 DataNode 1 上传 第一个 block,以 packet 为单位,DataNode 1 收到一个 packet 就会往后传;DataNode 1 每传一个 packet 会放入一个应答队列等待应答。
- 重复3 ~ 5 步骤,每上传一个 block ,都会向 NameNode 询问 block 存储的位置。
DataNode 写入故障解决
- 首先关闭管道,确认把队列中的所有数据包都添加回数据队列的最前端,以确保故障节点下游 的datanode不会漏掉任何一个数据包
- 为存储在另一正常datanode的当前数据块制定一个新标识,并将该标识传送给namenode, 以便故障datanode在恢复后可以删除存储的部分数据块
- 从管道中删除故障datanode,基于两个正常datanode构建一条新管道,余下数据块写入管道 中正常的datanode
- namenode注意到块复本不足时,会在另一个节点上创建一个新的复本 在一个块被写入期间可能会有多个datanode同时发生故障,但概率非常低。只要写入了 dfs.namenode.replication.min的复本数(默认1),写操作就会成功,并且这个块可以在集群中异步 复制,直到达到其目标复本数dfs.replication的数量(默认3)
机架感知(副本放置)
- 第一个副本在 Client 所处的节点上(就近原则);如果 Client 在集群外,随机选一个
- 第二个副本和第一个副本位于相同机架,随机节点
- 第三副本位于不同机架,随机节点
- 如果还有其它副本,任意
HDFS 读数据流程

- 通过 Distributed FileSystem 向 NameNode 请求下载文件,NameNode 通过查询元数据,找到文件块所在的 DataNode 地址;若找不到,报 IO 异常
- 就近原则,挑选最近一台 DataNode 服务器,请求读取数据。
- DataNode 开始传输数据给客户端(从磁盘读取数据流,以 packet 为单位来做校验)
- Client 以 packet 为接收单位,先本地缓存,再写入没目标文件
NameNode 和 SecondaryNameNode
NameNode 和 SecondaryNameNode 工作机制

Fsimage:NameNode 内存中元数据序列化后形成的文件
Edits:存放 HDFS文件系统的所有更新操作的路径,记录客户端更新元数据信息的每一步操作
第一阶段: NameNode 启动
- 首次启动 NameNode 格式化后,创建 FsImage 和 Edits 文件。如果不是第一次启动,先滚动 Edits 并生成一个空的 edits.inprogress,再加载编辑日志和镜像文件到内存。
- Client 对元数据进行增删改的请求。
- NameNode 记录操作日志,更新滚动日志。
- NameNode 再内存中对数据进行增删改。
第二阶段 Secondary NameNode 工作
- Secondary NameNode 询问 NameNode 是否需要 CheckPoint。直接带回 NameNode 是都检查结果
- Secondary NameNode 请求执行 CheckPoint
- NameNode 滚动正在写的 Edits 日志
- 将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode
- Secondary NameNode 加载编辑日志和镜像文件到内存,并合并
- 生成新的镜像文件 fsimage.checkpoint
- 拷贝 fsimage.checkpoint 到 NameNode
- NameNode 将 fsimage.checkpoint 重新命名成 fsimage
触发 checkpoint 条件: 默认1小时 或 操作次数一百万次
安全模式
一种工作状态,只向client提供文件的读操作,不接受命名空间的修改,同时namenode节点也不会进行块的复制或删除
进入安全模式
- HDFS文件系统刚启动会默认的安全模式倒计时,默认30s
- 报告的块数低于总应存储的块的数量(不包含副本)
- datanode的数量低于设定值
离开安全模式
- 修复丢失的数据
- 调低阈值或datanode数量
- 通过命令离开安全模式 hdfs dfsadmin -safemode enter/leave
- 重新格式化集群
DataNode
DataName工作机制

- block 再DataNode 上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据(包括block 的长度、校验和、时间戳)
- DataNode 启动后向 NammeNode 注册,周期性向 NameNode 上报所有的块信息
- 心跳机制:每秒一次,心跳返回结果带有 NameNode 给该 DataNode 的命令,如果超过 10 分钟没有收到某个 DataNode 的心跳,则认为该节点不可用。
- 集群中可以安全加入和退出一些机器
数据完整性(校验和)
- 当 DataNode 读取 block 时,它会计算 CheckSum
- 如果计算后的 CheckSum 与block 创建时的值不一样,说明 block 损坏
- Client 读取其他 DataNode 上的 block
- DataNode 在文件创建后周期验证 CheckSum
DataNode 掉线时限参数设置
当 DataNode 进程死亡或者网络故障造成 DataNode 无法与NameNode 通信,NameNode 不会立刻把该节点判定为死亡,要经过一段时间,这段时间暂称做超长时长,默认为 10分钟 30 秒。
超时时长 = 2 * dfs.namenode.heartbeat.recheck-interval(默认 5 分钟) + dfs.heartbeat.interval (默认 30s)
dfs.namenode.heartbeat.recheck-interval
300000
dfs.heartbeat.interval
3
HDFS 2.X 新特性
小文件存档
弊端: 每个文件按块存储你,每个块的元数据存储在 NameNode 的内存中,因此 HDFS 存储小文件会非常低效。因为大量的小文件会耗尽 NameNode 中的大部分内存。(存储小文件所需的磁盘容量与数据块大小无关)
解决方案: HDFS 存档文件或HAR文件,是一个更高效的文件存档工具,它将文件存入 HDFS 块,在减少 NameNode 内存使用的同时,允许对文件进行透明的访问。具体来说,HDFS存档文件对内还是一个一个独立文件,对 NameNode 来说是一个整体,减少了 NameNode 内存。
-
需要启动 YARN 进程 start-yarn
-
归档文件
例如:把 /user/data/input 目录里面的所有文件归档成一个叫 input.har 的归档文件,并把归档后的文件存储到 /user/data/output 路径下
bin/hadoop archive -archiveName input.har –p /user/username/input /user/username/output
-
查看归档
hadoop fs -lsr/user/username/output/input.har
-
解归档文件
hadoop fs -cp har:///user/username/output/input.har/* /user/data
回收站
开启回收站功能,可以将删除的文件在不超时的情况下,恢复数据,起到防止误删、备份等作用。
相关参数:
- 默认值 fs.trash.interval=0 ,0 表示禁用回收站;其他值表示设置文件的存活时间
- 默认值 fs.trash.checkpoint.interval=0 ,检查回收站的时间间隔。如果该值为0,则该值设置和fs.trash.interval的参数值相等。
- 要求fs.trash.checkpoint.interval<=fs.trash.interval。
回收站工作机制:

启用回收站: 修改 core-site.xml,配置垃圾回收时间为 1 分钟。
fs.trash.interval
1
查看回收站: 回收站在集群中的路径
修改访问垃圾回收站用户名称: 修改 core-site.xml,进入垃圾回收站用户名称,默认是 dr.who,修改为 username
hadoop.http.staticuser.user
username
通过程序删除的文件不会经过回收站,需要调用 moveToTrash()才进入回收站
Trash trash = New Trash(conf);
trash.moveToTrash(path);
恢复回收站数据:
hadoop fs -mv /user/username/.Trash/Current/user/username/input /user/username/input
清空回收站:
hadoop fs -expunge
快照管理
快照: 相当于对目录做一个备份。并不会立刻复制所有文件,二是记录文件变化。
1. hdfs dfsadmin -allowSnapshot path 开启指定目录的快照功能
2. hdfs dfsadmin -disallowSnapshot path 禁用指定目录的快照功能(默认)
3. hdfs dfs -createSnapshot path 对目录创建快照
4. hdfs dfs -createSnapshot path name 对指定名称创建快照
5. hdfs dfs -renameSnapshot path oldname newname 重命名快照
6. hdfs lsSnapshottableDir 列出当前用户所有可快照目录
7. hdfs snapshotDiff path1 path2 比较两个快照目录的不同之处
8. hdfs dfs -deleteSnapshot 删除快照
HDFS HA高可用
HA 概述
-
HA 高可用,即7*24 小时不中断服务
-
NameNode 主要在以下两个方面影响 HDFS 集群:
NameNode 机器发生意外,如宕机,集群将无法使用,直到管理员重启
NameNode 机器需要升级,包括软件、硬件升级,此时集群也将无法使用
-
HDFS HA 功能通过配置 Active/Standby 两个 NameNodes 实现在集群中对 NameNode 的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将 NameNode 很快的切换到另外一台机器。
-
实现高可用最关键的策略是消除单点故障
工作机制
通过双 NameNode 消除单点故障
HDFS - HA 工作要点
- 元数据管理方式需要改变
(1)内存中各自保存一份元数据;
(2)Edits 日志只有 ative 状态的 NameNode 节点可以做写操作
(3)两个 NameNode 都可以读取 Edits
(4)共享的 Edits 放在一个共享存储中管理(qjournal和NFS实现)
- 状态管理
实现了一个 zkfailover ,常驻在每一个 namenode 所在的节点,每个 zkfailover 负责监控自己所在 NameNode 节点,利用 zk 进行状态标识,当需要进行状态切换时,由 zkfailover 来负责切换,切换时需要防止 brain split 现象发生
- 隔离,统一时刻仅仅有一个 NameNode 对外服务
- 必须保证两个 NameNode 之间能够 ssh 无密码登录
NamaNode 故障手动处理
将 active 节点中的数据拷贝到NameNode 存储数据的目录
- 首先进入安全模式:
hdfs dfsadmin -safemode enter
- 然后刷一下 active 节点的log到image
hdfs dfsadmin -saveNamespace
- 然后将 active 节点的image文件全部拷贝到故障节点的相应目录下
然后重启故障namenode
- 最后hdfs namenode -bootstrapStandby
HDFS - HA 自动给故障转移工作机制
自动故障转移为 HDFS 部署两个新组件,即 Zookeeper 和 ZKFailoverController(以下简称 ZKFC) 进程。
Zookeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。HA 的故障转移依赖于 Zookeeper 的以下功能:
- 故障检测: 集群中的每一个 NameNode 在 Zookeeper 中维护了一个持久会话,如果机器崩溃,Zookeeper 中的会话将终止,Zookeeper 通知另一个 NameNode 需要触发故障转移。
- 现役 NameNode 选择: Zookeeper 提供了一个简单的机制用于唯一的选择一个节点为 active 状态。如果目前现役 NameNode 崩溃,另一个可能从 Zookeeper 获得特殊的排外锁以表明它应该成为现役 NameNode。
ZKFC 是 Zookeeper 的客户端,也监视和管理 NameNode 的状态。每个运行 NameNode 的主机也运行了一个 ZKFC 进程,ZKFC负责:
(1)健康检测: ZKFC 使用一个健康检查命令定期地 ping 与之在相同主机的 NameNode,只要该 NameNode 及时地回复到健康状态,ZKFC 认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测标识该节点为健康的。
(2)Zookeeper 会话管理: 当本地 NameNode 是健康的,ZKFC 保持一个在 Zookeeper 中打开的会话。如果本地 NameNode 处于 active 状态,ZKFC 也保持一个特殊的 znode 锁,该锁使用了 Zookeeper 对短暂节点的支持,如果会话终止,锁节点将自动删除。
(3)基于 Zookeeper 的选择: 如果本地 NameNode 是健康的,且 ZKFC 发现没有其他的节点当前持有 znode 锁 ,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地 NameNode 为 Active 。
HDFS 可靠性策略
- 保证文件完整性
- 网络或机器失效
(1)副本冗余
(2)机架感知策略
(3)心跳机制
- NameNode 宕机:准备切换(HA);fsimage和edits存磁盘、可多份,多磁盘存储
- 其他:快照;垃圾回收机制;安全模式