一、数据块的冗余
为了保证系统的容错性和可用性,hdfs采用了多副本方式对数据块进行冗余存储,也就是一个数据块的多个副本会被分布到不同的Datanode上,存储在Datanode的本地文件系统中。
这种多副本的存储方式有以下优点:
1)加快数据传输速度。当多个客户端需要同时访问同一个文件时,这些客户端可以从不同的数据块副本中读取数据,大大提高了数据的传输速度。
2)容易检查数据错误。HDFS的Datanode之间通过网络传输数据,采用多副本可以很容易判断数据传输是否出错。
3)保证数据的可靠性。即使某个Datanode出现了故障,也不会造成数据丢失。
二、数据的存取策略
数据存取策略包括数据存放、数据读取和数据复制等方面,在很大程度上影响了整个HDFS的读写性能,是HDFS的核心内容。
1、数据存放
为了提高数据的可靠性和系统的可用性,和充分利用网络带宽,HDFS采用了以机架(Rack)为基础的存放策略
一个集群通常包含多个机架(Rack),不同的机架之间的数据通信需要经过交换机或者路由器,同一个机架中不同及其之间的通信则不需要经过交换机和路由器,这意味着同一个机架中不同机器之间的通信要比机架之间机器的通信带宽要大得多。
第一个副本的位置:客户端在集群之外的情况,就会随机选择一个机架和此机架上的随机一个节点进行存储。
第二个副本的位置:选择与第一个副本不同的机架,并随机选择一个节点进行存储。
第三个副本的位置:选择与第二个副本相同的机架的不同节点进行存储。
如果有其他副本,将被分散到其他机架。
这样的存储策略,可以获取很高的数据可靠性,即使一个机架发生故障,其他机架上的数据复本仍然可用;再一个,在读取数据的时候,可以在多个机架并行读取,大大提高了数据读取速度;还可以实现系统的负载均衡。
2、数据读取
HDFS提供了一个API可以确定一个数据节点所属的机架ID,客户端也可以调用API获取自己所属的机架ID。当客户端读取数据时,从Namenode的内存中获取数据块的不同副本的存放位置列表,列表中包含了副本所在的数据节点,然后调用API获取客户端和数据节点的机架ID,当发现某个数据块副本对应的机架ID和客户端的机架ID相同时,就优先选择该副本进行读取(就近选择读取);如果没有发现,就随机选择一个副本进行读取。
3、数据复制
hdfs的数据复制采取了流水线复制的策略,大大提高了数据复制过程的效率。当客户端要往HDFS中写入一个文件时,这个文件会先被写入本地缓存,当达到一个块大小时,客户端会向Namenode发送写请求,Namenode会根据各个Datanode的使用情况,选择副本数量的Datanode列表,返回给客户端。然后客户端就先把数据写入列表中的第一个Datanode上,同时把列表传给第一个Datanode,当Datanode接收到4KB数据的时候,就写入本地,并且向列表中的第二个Datanode发起连接请求,把自己已经接收到的4KB数据和列表传给第二个Datanode,当第二个Datanode接收到4KB数据时,再写入本地,并且向列表中的第三个Datanode发起连接请求,第三个数据节点接收到4KB数据后,再写入本地。以此类推,列表中的多个Datanode形成一条数据复制的流水线。当第一个块的所有副本都写完后,客户端再向 Namenode 请求下一个块的副本存储的Datanode列表,一个新的流水线被组织起来,直到文件的最后一个块。
三、数据错误和恢复
HDFS具有很高的容错性,它把硬件出错看成一种常态,而不是异常,并设计了相应的机制检测数据错误和进行自动恢复,主要包括以下几种情形:
1、Namenode出错
Namenode主要以fsimage和editlog两个文件保存了所有的元数据信息,如果这两个文件发生损坏,那么整个HDFS实例将失效。因此HDFS设置了备份机制,即把这两个核心文件同步复制到SecondaryNamenode上。SecondaryNamenode本身不会处理任何请求(除了创建检查点)。当Namenode出错时,就可以根据SecondaryNamenode上的fsimage和editlog进行数据恢复。
PS:创建检查点后,Namenode很可能已经发生了文件的创建,删除,重命名等操作,这个时候,如果Namenode出错,使用备份恢复后,最近新生成的部分元数据则永久失效。
2、Datanode出错
每个Datanode会定期向Namenode发送心跳(Heartbeat)信息,报告自己的状态信息。如果某个Datanode发生故障,或者网络发生断网时,Namenode就无法收到这个Datanode的心跳信息,这时,这个Datanode就会被标记为“宕机”,Namenode不会再给这样的Datanode发送任何I/O请求。这时,由于宕机状态的Datanode不可用,副本数量明显不够,Namenode就会启动数据冗余复制,为数据块生成新的副本。HDFS和其他分布式文件系统的最大区别就是可以调整冗余数据的位置。
3、数据出错
存储设备故障,网络故障等都可能造成数据块的损坏。数据块在被写入Datanode时,会采用算法计算数据块的校验和,然后存储在一个隐藏文件中。当客户端读取数据块的时候,也会重新计算数据块的校验和,然后与隐藏文件里的校验和进行对比,如果结果不一致,客户端就会请求到该块的另一个副本节点上进行读取,并且报告这个数据块有错误,Namenode会再次启动数据块的冗余复制。