运行在大量廉价商用机器上:硬件错误是常态,提供容错机制简单一致性模型:一次写入多次读取,支持追加,不允许修改,保证数据一致性流式数据访问:批量读而非随机读,关注吞吐量而非时间存储大规模数据集:典型文件大小GB~TB,关注横向线性扩展
HDFS (Hadoop Distributed File System)是 Hadoop 下的分布式文件系统,具有高容错、高吞吐量等特性,可以部署在低成本的硬件上。
3. 优点
- 高容错、高可用、高扩展数据冗余,多Block多副本,副本丢失后自动恢复NameNode HA、安全模式10K节点规模
- 海量数据存储典型文件大小GB~TB,百万以上文件数量, PB以上数据规模
- 构建成本低、安全可靠构建在廉价的商用服务器上提供了容错和恢复机制
- 适合大规模离线批处理流式数据访问数据位置暴露给计算框架
4. 缺点
- 不适合低延迟数据访问
- 不适合大量小文件存储元数据占用NameNode大量内存空间每个文件、目录和Block的元数据都要占用150Byte存储1亿个元素,大约需要20GB内存如果一个文件为10KB,1一个文件大小仅有1TB,却要消耗掉20GB内存磁盘寻道时间超过读取时间
- 不支持并发写入一个文件同时只能有一个写入者
- 不支持文件随机修改仅支持追加写入
2. HDFS原理
1. HDFS 架构
hdfs创建目录、HDFS 遵循主/从架构,由单个 NameNode(NN) 和多个 DataNode(DN) 组成:
- NameNode : 负责执行有关文件系统命名空间的操作,例如打开,关闭、重命名文件和目录等。它同时还负责集群元数据的存储,记录着文件中各个数据块的位置信息。
- DataNode:负责提供来自文件系统客户端的读写请求,执行块的创建,删除等操作。
Active NameNode(AN)
- 活动Master管理节点(集群中唯一)
- 管理命名空间
- 管理元数据:文件的位置、所有者、权限、数据块等
- 管理Block副本策略:默认3个副本
- 处理客户端读写请求,为DataNode分配任务
Standby NameNode(SN)
- 热备Master管理节点(Active NameNode的热备节点)Hadoop 3.0允许配置多个Standby NameNode
- Active NameNode宕机后,快速升级为新的Active
- 同步元数据,即周期性下载edits编辑日志,生成fsimage镜像检查点文件
NameNode元数据文件
- edits(编辑日志文件):保存了自最新检查点(Checkpoint)之后的所有文件更新操作
- fsimage(元数据检查点镜像文件):保存了文件系统中所有的目录和文件信息,如:某个目录下有哪些子目录和文件,以及文件名、文件副本数、文件由哪些Block组成等
- Active NameNode内存中有一份最新的元数据(= fsimage + edits)
- Standby NameNode在检查点定期将内存中的元数据保存到fsimage文件中
DataNode
- Slave工作节点(可大规模扩展)
- 存储Block和数据校验和
- 执行客户端发送的读写操作
- 通过心跳机制定期(默认3秒)向NameNode汇报运行状态和Block列表信息
- 集群启动时,DataNode向NameNode提供Block列表信息
Block数据块
- HDFS最小存储单元
- 文件写入HDFS会被切分成若干个Block
- Block大小固定,默认为128MB,可自定义
- 若一个Block的大小小于设定值,不会占用整个块空间
- 默认情况下每个Block有3个副本
Client
- 将文件切分为Block
- 与NameNode交互,获取文件访问计划和相关元数据
- 与DataNode交互,读取或写入数据
- 管理HDFS
2. 文件系统命名空间
HDFS 的文件系统命名空间的层次结构与大多数文件系统类似 (如 Linux), 支持目录和文件的创建、移动、删除和重命名等操作,支持配置用户和访问权限,但不支持硬链接和软连接。NameNode 负责维护文件系统名称空间,记录对名称空间或其属性的任何更改。
3. 数据复制
启动hadoop。由于 Hadoop 被设计运行在廉价的机器上,这意味着硬件是不可靠的,为了保证容错性,HDFS 提供了数据复制机制。HDFS 将每一个文件存储为一系列块,每个块由多个副本来保证容错,块的大小和复制因子可以自行配置(默认情况下,块大小是 128M,默认复制因子是 3)。
4. 数据复制的实现原理
Block存储
- Block是HDFS的最小存储单元
- 如何设置Block大小目标:最小化寻址开销,降到1%以下默认大小:128M块太小:寻址时间占比过高块太大:Map任务数太少,作业执行速度变慢
- Block和元数据分开存储:Block存储于DataNode,元数据存储于NameNode
- Block多副本以DataNode节点为备份对象机架感知:将副本存储到不同的机架上,实现数据的高容错副本均匀分布:提高访问带宽和读取性能,实现负载均衡
Block副本放置策略
- 副本1:放在Client所在节点 -对于远程Client,系统会随机选择节点
- 副本2:放在不同的机架节点上
- 副本3:放在与第二个副本同一机架的不同节点上
- 副本N:随机选择
- 节点选择:同等条件下优先选择空闲节点
大型的 HDFS 实例在通常分布在多个机架的多台服务器上,不同机架上的两台服务器之间通过交换机进行通讯。在大多数情况下,同一机架中的服务器间的网络带宽大于不同机架中的服务器之间的带宽。因此 HDFS 采用机架感知副本放置策略,对于常见情况,当复制因子为 3 时,HDFS 的放置策略是:
在写入程序位于 datanode 上时,就优先将写入文件的一个副本放置在该 datanode 上,否则放在随机 datanode 上。之后在另一个远程机架上的任意一个节点上放置另一个副本,并在该机架上的另一个节点上放置最后一个副本。此策略可以减少机架间的写入流量,从而提高写入性能。
如果复制因子大于 3,则随机确定第 4 个和之后副本的放置位置,同时保持每个机架的副本数量低于上限,上限值通常为 (复制系数 - 1)/机架数量 + 2,需要注意的是不允许同一个 dataNode 上具有同一个块的多个副本。
Block文件
- Block文件是DataNode本地磁盘中名为“blk_blockId”的Linux文件DataNode在启动时自动创建存储目录,无需格式化DataNode的current目录下的文件名都以“blk_”为前缀Block元数据文件(*.meta)由一个包含版本、类型信息的头文件和一系列校验值组成
5. 副本的选择
为了最大限度地减少带宽消耗和读取延迟,HDFS 在执行读取请求时,优先读取距离读取器最近的副本。如果在与读取器节点相同的机架上存在副本,则优先选择该副本。如果 HDFS 群集跨越多个数据中心,则优先选择本地数据中心上的副本。
6. 架构的稳定性
心跳机制和重新复制
每个 DataNode 定期向 NameNode 发送心跳消息,如果超过指定时间没有收到心跳消息,则将 DataNode 标记为死亡。NameNode 不会将任何新的 IO 请求转发给标记为死亡的 DataNode,也不会再使用这些 DataNode 上的数据。 由于数据不再可用,可能会导致某些块的复制因子小于其指定值,NameNode 会跟踪这些块,并在必要的时候进行重新复制。
数据的完整性
由于存储设备故障等原因,存储在 DataNode 上的数据块也会发生损坏。为了避免读取到已经损坏的数据而导致错误,HDFS 提供了数据完整性校验机制来保证数据的完整性,具体操作如下:
当客户端创建 HDFS 文件时,它会计算文件的每个块的校验和,并将校验和存储在同一HDFS 命名空间下的单独的隐藏文件中。当客户端检索文件内容时,它会验证从每个 DataNode 接收的数据是否与存储在关联校验和文件中的校验和匹配。如果匹配失败,则证明数据已经损坏,此时客户端会选择从其他 DataNode 获取该块的其他可用副本。
元数据的磁盘故障
元数据的两种存储形式
- 内存元数据(NameNode)
- 文件元数据(edits + fsimage)
edits(编辑日志文件)
- Client请求变更操作时,操作首先被写入edits,再写入内存
- edits文件名通过前/后缀记录当前操作的Transaction Id
fsimage(元数据镜像检查点文件)
- 不会为文件系统的每个更新操作进行持久化,因为写fsimage的速度非常慢
- fsimage文件名会标记对应的Transaction Id
FsImage 和 EditLog 是 HDFS 的核心数据,这些数据的意外丢失可能会导致整个 HDFS 服务不可用。为了避免这个问题,可以配置 NameNode 使其支持 FsImage 和 EditLog 多副本同步,这样 FsImage 或 EditLog 的任何改变都会引起每个副本 FsImage 和 EditLog 的同步更新。
支持快照
快照支持在特定时刻存储数据副本,在数据意外损坏时,可以通过回滚操作恢复到健康的数据状态。