数据的冗余存储
作为分布式文件系统的基石,HDFS 的核心设计目标就是容错与高可用。为了保证这一点,它采用了多副本机制对数据进行冗余存储。通常一个数据块的多个副本会被分布到不同的数据节点上,如图 1 所示。
图 1 HDFS 数据块多副本存储
这种多副本方式主要有三个好处:
首先,能显著提升传输效率。当多个客户端需要同时访问同一个文件时,可以让它们分别从不同的数据块副本中读取数据,避免单点瓶颈。 其次,便于检查数据错误。HDFS 的数据节点之间通过网络传输数据,采用多个副本可以很容易判断数据传输是否出错。 最后,保证数据的可靠性。即使某个数据节点出现故障失效,也不会造成数据丢失。
数据存取策略
数据存取策略包括存放、读取和复制等方面,它在很大程度上会影响到整个分布式文件系统的读写性能,是核心内容之一。
数据存放
为了提高数据的可靠性与系统的可用性,以及充分利用网络带宽,HDFS 采用了以机架(Rack)为基础的数据存放策略。一个 HDFS 集群通常包含多个机架,不同机架之间的数据通信需要经过交换机或者路由器,而同一机架内机器之间的通信则不需要经过这些设备,这意味着同一机架内的通信带宽更大。
虽然默认策略下每个数据节点都在不同的机架上,但这并不意味着写入时不能利用机架内部带宽。相反,HDFS 的副本放置策略非常讲究:默认冗余复制因子是 3,每一个文件块会被同时保存到 3 个地方。其中,有两个副本放在同一个机架的不同机器上面,第 3 个副本放在不同机架的机器上面。这样既可以保证机架发生异常时的数据恢复,也可以提高数据读写性能。一般而言,HDFS 副本的放置策略如图 2。
图 2 HDFS 副本的放置策略
具体规则如下:
- 如果是在集群内发起写操作请求,则把第 1 个副本放置在发起写操作请求的数据节点上,实现就近写入数据。如果是在集群外发起写操作请求,则从集群内部挑选一台磁盘空间较为充足、CPU 不太忙的数据节点,作为第 1 个副本的存放地。
- 第 2 个副本会被放置在与第 1 个副本不同的机架的数据节点上。
- 第 3 个副本会被放置在与第 1 个副本相同的机架的其他节点上。
- 如果还有更多的副本,则继续从集群中随机选择数据节点进行存放。
数据读取
HDFS 提供了一个 API 可以确定一个数据节点所属的机架 ID,客户端也可以调用 API 获取自己所属的机架 ID。当客户端读取数据时,从名称节点获得数据块不同副本的存放位置列表,列表中包含了副本所在的数据节点,可以调用 API 来确定客户端和这些数据节点所属的机架 ID。当发现某个数据块副本对应的机架 ID 和客户端对应的机架 ID 相同时,就优先选择该副本读取数据;如果没有发现,就随机选择一个副本读取数据。
数据复制
HDFS 的数据复制采用了流水线复制的策略,大大提高了数据复制过程的效率。当客户端要往 HDFS 中写入一个文件时,这个文件会首先被写入本地,并被切分成若干个块,每个块的大小是由 HDFS 的设定值来决定的。每个块都向 HDFS 集群中的名称节点发起写请求,名称节点会根据系统中各个数据节点的使用情况,选择一个数据节点列表返回给客户端。
然后客户端就把数据首先写入列表中的第 1 个数据节点,同时把列表传给第 1 个数据节点。当第 1 个数据节点接收到 4 KB 数据的时候,写入本地,并且向列表中的第 2 个数据节点发起连接请求,把自己已经接收到的 4 KB 数据和列表传给第 2 个数据节点。当第 2 个数据节点接收到 4 KB 数据的时候,写入本地,并且向列表中的第 3 个数据节点发起连接请求,依此类推,列表中的多个数据节点形成一条数据复制的流水线。最后,当文件写完的时候,数据复制也同时完成。
数据错误与恢复
HDFS 具有较高的容错性,可以兼容廉价的硬件设备,它把硬件出错看成一种常态,而不是异常,并设计了相应的机制检测数据错误和进行自动恢复,主要包括以下 3 种情形。


