分布式文件系统HDFS

1,311 阅读11分钟

1. HDFS简介

1. 概念

  • Hadoop分布式文件系统(Hadoop Distributed File System)
  • 2003年10月Google发表了GFS(Google File System)论文
  • HDFS是GFS的开源实现
  • HDFS是Apache Hadoop的核心子项目
  • 在开源大数据技术体系中,地位无可替代

2. 设计目标

  • 运行在大量廉价商用机器上:硬件错误是常态,提供容错机制
  • 简单一致性模型:一次写入多次读取,支持追加,不允许修改,保证数据一致性
  • 流式数据访问:批量读而非随机读,关注吞吐量而非时间
  • 存储大规模数据集:典型文件大小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原理

HDFS架构-1

HDFS架构-2

1. 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镜像检查点文件

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 被设计运行在廉价的机器上,这意味着硬件是不可靠的,为了保证容错性,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 的同步更新。

支持快照

快照支持在特定时刻存储数据副本,在数据意外损坏时,可以通过回滚操作恢复到健康的数据状态。

7. HDFS特点

  1. 高容错:由于 HDFS 采用数据的多副本方案,所以部分硬件的损坏不会导致全部数据的丢失。
  2. 高吞吐量:HDFS 设计的重点是支持高吞吐量的数据访问,而不是低延迟的数据访问。
  3. 大文件支持:HDFS 适合于大文件的存储,文档的大小应该是是 GB 到 TB 级别的。
  4. 简单一致性模型:HDFS 更适合于一次写入多次读取 (write-once-read-many) 的访问模型。支持将内容追加到文件末尾,但不支持数据的随机访问,不能从文件任意位置新增数据。
  5. 跨平台移植性:HDFS 具有良好的跨平台移植性,这使得其他大数据计算框架都将其作为数据持久化存储的首选方案。

3. HDFS存储原理

1. HDFS写数据原理

HDFS写数据原理

HDFS漫画-1

HDFS漫画-2

HDFS漫画-3

2. HDFS读数据原理

HDFS读数据原理

HDFS漫画-4

3. HDFS故障类型和其检测方法

HDFS漫画-5

数据损坏,校验和

HDFS漫画-6

第二部分:读写故障的处理

HDFS漫画-7

第三部分:DataNode 故障处理

HDFS漫画-8

什么是安全模式

  • 安全模式是HDFS的一种特殊状态,在这种状态下,HDFS只接收读数据请求,而不接收写入、删除、修改等变更请求
  • 安全模式是HDFS确保Block数据安全的一种保护机制
  • Active NameNode启动时,HDFS会进入安全模式,DataNode主动向NameNode汇报可用Block列表等信息,在系统达到安全标准前,HDFS一直处于“只读”状态

何时正常离开安全模式

  • Block上报率:DataNode上报的可用Block个数 / NameNode元数据记录的Block个数
  • 当Block上报率 >= 阈值时,HDFS才能离开安全模式,默认阈值为0.999
  • 不建议手动强制退出安全模式

触发安全模式的原因

  • NameNode重启
  • NameNode磁盘空间不足
  • Block上报率低于阈值
  • DataNode无法正常启动
  • 日志中出现严重异常
  • 用户操作不当,如:强制关机(特别注意!)

故障排查

  • 找到DataNode不能正常启动的原因,重启DataNode
  • 清理NameNode磁盘

Active NN与Standby NN的主备切换

利用QJM实现元数据高可用

  • QJM机制(Quorum Journal Manager)
    • 只要保证Quorum(法定人数)数量的操作成功,就认为这是一次最终成功的操作
  • QJM共享存储系统
    • 部署奇数(2N+1)个JournalNode
    • JournalNode负责存储edits编辑日志
    • 写edits的时候,只要超过半数(N+1)的JournalNode返回成功,就代表本次写入成功
    • 最多可容忍N个JournalNode宕机
    • 基于Paxos算法实现

利用ZooKeeper实现Active节点选举

利用ZooKeeper实现Active节点选举

最后

大家可以关注我的微信公众号一起学习进步。