HDFS保证数据一致性

Hadoop

  HDFS作为分布式文件系统在分布式环境下如何保证数据一致性。HDFS中,存储的文件将会被分成若干的大小一致的block分布式地存储在不同的机器上,需要NameNode节点来对这些数据进行管理,存储这些block的结点称为DataNode,NameNode是用来管理这些元数据的。

NameNode保证元数据的一致性

  客户端上传文件时,NameNode首先往edits log文件中记录元数据的操作日志。与此同时,NameNode将会在磁盘做一份持久化处理(fsimage文件):它跟内存中的数据是对应的,如何保证和内存中的数据的一致性?在edits logs满之前对内存和fsimage的数据做同步,合并edits logs和fsimage上的数据,然后edits logs上的数据即可清除。而当edits logs满之后,文件的上传不能中断,所以将会往一个新的文件edits.new上写数据,而老的edits logs的合并操作将由secondNameNode来完成,即所谓的checkpoint操作。
  checkpoint的触发一般由两种限制,一个是edits logs的大小限制,即fs.checkpoint.size配置;一个是指定时间,即fs.checkpoint.period配置。根据规定,大小的限制是优先的,规定edits文件一旦超过阈值,则不管是否达到最大时间间隔,都会强制checkpoint。

  SecondaytNameNode 是 HA(High Available 高可用性)的一个解决方案,但不支持热备,配置即可。SecondaryNameNode执行过程:从NameNode上下载元数据信息(fsimage、edits),然后把二者合并,生成新的fsimage,在本地保存,并将其推送到NameNode,替换旧的fsimage。(注:SecondaryNameNode 只存在于Hadoop1.0中,Hadoop2.0以上版本中没有,但在伪分布模式中是有SecondaryNameNode的,在集群模式中是没有SecondaryNameNode的)

SecondaryNameNode 工作流程步骤:

  1. SecondaryNameNode 通知NameNode切换edits文件

  2. SecondaryNameNode 从NameNode获得fsimage和edits(通过http)

  3. SecondaryNameNode 将fsimage载入内存,然后开始合并edits
    (同样合并edits操作是需要满足一定条件才进行的,有两个条件:
    1)fs.checkpoint.period指定两次checkpoint的最大时间间隔,默认3600秒
    2)fs.checkpoint.size规定edits文件的最大值,一旦超过这个值(默认大小是64M)则强制checkpoint,不管是否到达最大时间间隔。)

  4. SecondaryNameNode 将新的fsimage发回给NameNode

  5. NameNode用新的fsimage替换旧的fsimage

校验和

  HDFS 会对写入的所有数据计算校验和(checksum),并在读取数据时验证校验和。针对指定字节的数目计算校验和。字节数默认是512 字节,可以通过io.bytes.per.checksum属性设置。通过CRC-32编码后为4字节。
  DataNode 在保存数据前负责验证checksum。client 会把数据和校验和一起发送到一个由多个DataNode 组成的队列中,最后一个DataNode 负责验证checksum。如果验证失败,会抛出一个ChecksumException。客户端需要处理这种异常。客户端从DataNode 读取数据时,也会验证checksum。每个DataNode 都保存了一个验证checksum的日志。每次客户端成功验证一个数据块后,都会告知DataNode ,DataNode 会更新日志。
  每个DataNode 也会在一个后台线程中运行一个DataBlockScanner,定期验证这个 DataNode 上的所有数据块。在用 hadoop fs get 命令读取文件时,可以用 -ignoreCrc 忽略验证。如果是通过FileSystem API 读取时,可以通过setVerifyChecksum(false),忽略验证。Hadoop中的LocalFileSystem会进行客户端的检验和,写文件时,会在目录下创建一个名为.filename.crc的隐藏文件,如果想禁止校验和功能,可以用RawLocalFileSystem代替LocalFileSystem 。

Configuration conf = ...
FileSystem fs = new RawLocalFileSystem();
fs.initialize(null, conf);

或者直接设置fs.file.impl属性为org.apache.hadoop.fs.RawLocalFileSystem,这样会全局禁用checksum。
  LocalFileSystem内部使用了ChecksumFileSystem完成checksum工作。通过ChecksumFileSystem可以添加校验和功能。

FileSystem rawFs = ...
FileSystem checksummedFs = new ChecksumFileSystem(rawFs);

HA高可用

冗余副本

  • HDFS处理节点失效的一个方法就是数据冗余,即对数据做多个备份,在HDFS中可以通过配置文件设置备份的数量,如果不进行设置,这个数量默认为3。注意参数dfs.replication.min和dfs.replication的区别:在一个块被写入期间,只要至少写入了dfs.replication.min个副本数(默认是1),写操作就会成功,直到达到其目标副本数dfs.replication(默认是3)

机架感知

  • 通常,大型Hadoop集群是以机架的形式来组织的,同一个机架上不同节点间的网络状况比不同机架之间的更为理想。Namenode设法将数据块副本保存在不同的机架上以提高容错性
  • HDFS如何得知哪个Datanode在哪个机架上?
    HDFS使用了一种称为“机架感知”的策略。HDFS不能够自动判断集群中各个Datanode的网络拓扑情况,必须通过配置dfs.network.script参数来确定节点所处的机架。文件提供了IP->rackid的翻译,NameNode通过这个得到集群中各个Datanode节点的rackid

心跳机制

  • 检测节点失效使用“心跳机制”。每个DataNode节点周期性地向NameNode发送心跳信号。网络分区可能导致一部分DataNode跟NameNode失去联系。NameNode通过心跳信号的缺失来检测这一情况,并将这些近期不再发送心跳信号DataNode标记为宕机,不会再将新的IO请求发给它们
  • 任何存储在宕机DataNode上的数据将不再有效。DataNode的宕机可能会引起一些数据块的副本系数低于指定值,NameNode不断地检测这些需要复制的数据块,一旦发现就启动复制操作

在下列情况下,可能需要重新复制:
a) 某个DataNode节点失效
b) 某个副本遭到损坏
c) DataNode上的硬盘错误
d) 文件的冗余因子增大

安全模式

  • NameNode启动后会进入一个称为安全模式的特殊状态。处于安全模式的NameNode对于客户端来说是只读的。NameNode从所有的DataNode接收心跳信号和块状态报告(blockreport)
  • 每个数据块都有一个指定的最小副本数(dfs.replication.min),当NameNode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全(safely replicated)的
  • 在一定百分比(这个参数配置于dfs.safemode.threshold.pct,默认值是99.9%)的数据块被NameNode检测确认是安全之后,再过若干时间后(这个参数配置于dfs.safemode.extension,默认值是30秒),NameNode将退出安全模式状态。接下来NameNode会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他DataNode上

校验和

  • HDFS会对写入的所有数据计算校验和(checksum),并在读取数据时验证。Datanode在收到客户端的数据或者复制其他Datanode的数据时,在验证数据后会存储校验和。正在写数据的客户端将数据及其校验和发送到由一系列Datanode组成的管线,管线中的最后一个Datanode负责验证校验和。如果Datanode检测到错误,客户端便会收到一个ChecksumException
  • 客户端从Datanode读取数据时,也会验证校验和,将它们与Datanode中存储的校验和进行比较。每个Datanode均持久保存一个用于验证的校验和日志,所以它知道每个数据块的最后一次验证时间。客户端成功验证一个数据块后,会通知这个Datanode更新次日志
  • 此外,每个Datanode也会在一个后台运行一个称为DataBlockScanner的进程定期验证存储在这个Datanode上的所有数据块。检测到错误后,Namenode将这个已损坏的数据块标记为已损坏,之后从其他Datanode复制此数据的副本,最后使得数据的副本达到指定数目

回收站

  • 当用户或应用程序删除某个文件时,这个文件并没有立刻从HDFS中删除。实际上,HDFS会将这个文件重命名转移到/trash目录。只要文件还在/trash目录中,该文件就可以被迅速地恢复
  • 文件在/trash中保存的时间是可配置的(配置参数fs.trash.interval),当超过这个时间时,Namenode就会将该文件从命名空间中删除。删除文件会使得该文件相关的数据块被释放。注意,从用户删除文件到HDFS空闲空间的增加之间会有一定时间的延迟

元数据保护

  FsImage和Editlog是HDFS的核心数据。如果这些文件损坏了,整个HDFS都将失效。因而,Namenode可以配置成支持维护多个FsImage和Editlog的副本。任何对FsImage或者Editlog的修改,都将同步到它们的副本上。这种多副本的同步操作可能会降低Namenode每秒处理的名字空间事务数量。然而这个代价是可以接受的,因为即使HDFS的应用是数据密集的,它们也非元数据密集的。当Namenode重启的时候,它会选取最近的完整的FsImage和Editlog来使用

快照机制

  快照支持某一特定时刻的数据的复制备份。利用快照,可以让HDFS在数据损坏时恢复到过去一个已知正确的时间点。HDFS目前还不支持快照功能,但计划会在将来的版本支持。

猜你喜欢

转载自blog.csdn.net/ThreeAspects/article/details/105983047