Hadoop数据完整性与CheckSum校验原理

一、HDFS数据完整性

用户肯定都希望系统在存储和处理数据时,数据不会有任何丢失或损坏。但是,受网络不稳定、硬件损坏等因素,IO操作过程中难免会出现数据丢失或脏数据,难免会出现数据丢失或脏数据,数据传输的量越大,出现错误的概率就越高。

检测数据是否损坏的常见措施是,在数据第一次引入系统时计算校验和(checksum)并存储,在数据进行传输后再次计算校验和进行对比,如果计算所得的新校验和和原来的校验和不匹配,就认为数据已损坏。但该技术并不能修复数据——它只能检测出数据错误。(这正是不使用低端硬件的原因。具体说来,一定要使用ECC内存。)注意,校验和也是可能损坏的,不只是数据,但由于校验和比数据小得多,所以损坏的可能性非常小。

(1)对本地文件I/O的检查
在Hadoop中,本地文件系统的数据完整性由客户端负责。重点在于存车读取文件时进行校验和的处理。
具体做法是:每当hadoop创建文件a时,hadoop就会同时在同一个文件夹下创建隐藏文件.a.crc,这个文件记录了 文件a的校验和。针对数据文件的大小,每512个字节会生成一个32位的校验和(4字节),可以在src/core/core-default.xml中通过修改io.bytes.per.checksum的大小来修改每个校验和所针对的文件的大小。

在hadoop中,校验和系统单独为一类,org.apache.hadoop.fs.ChecksumFileSystem,当需要校验和机制时,可以很方便的调用它来服务。

(2)对HDFS的I/O数据进行检查

一般来说,HDFS会在三种情况下检验校验和:

  1. DataNode接收数据后存储数据前
    DataNode接收数据一般有两种情况:1.从客户端上传数据 2.DataNode从其他DataNode上接收数据。
    当客户端上传数据时,正在写数据的客户端将数据及其校验和发送到由一系列datanode组成的Pipeline管线。Pipeline管线中最后一个datanode负责验证校验和。

    DataNode数据存储步骤:(包括从DataNode和客户端两种传输方式)
    1.在传输数据的最开始阶段,Hadoop会简单地检查数据块的完整性信息;
    2.依次向各个DataNode传输数据,包括数据头信息、块信息、备份个数、校验和等;
    3.Hadoop不会在数据每流动到一个DataNode都检查校验和,只会在数据流达到最后一个节点时才检查校验和
    如果在验证过程中发现有不一致的块,就会抛出CheckSumException异常信息

  2. 客户端读取DataNode上的数据时
    Hadoop会在客户端读取DataNode上的数据时,使用DFSClient中的read函数先将数据读入到用户的数据缓冲区,然后再检查校验和。将他们与datanode中存储的校验和进行比较
    每个datanode均持久保存有一个用于验证的校验和日志,所以它知道每个数据块的最后一次验证时间
    客户端成功验证一个数据块后,会告诉这个datanode,datanode由此更新日志

  3. DataNode后台守护进程的定期检查
    DataNode会在后台运行DataBlockScanner,这个程序定期验证存储在这个datanode上的所有数据块(3周)
    该项措施是解决物理存储媒体上位衰减,位损坏的有力措施。

Hadoop处理损坏数据的机制:

  1. DataNode在读取block块的时候会先进行checksum(数据块校验和)
    如果client发现本次计算的校验和跟创建时的校验和不一致,则认为该block块已损坏
  2. 客户端在抛出ChecksumException之前上报该block信息给namenode进行标记(“已损坏”)
    这样namenode就不会把客户端指向这个block,也不会复制这个block到其他的datanode。
  3. client重新读取另外的datanode上的block
  4. 在心跳返回时NameNode将块的复制任务交给DataNode,从完好的block副本进行复制以达到默认的备份数3
  5. NameNode删除掉坏的block。
  6. DataNode在一个block块被创建之日起三周后开始进行校验

如果出于一些原因在操作的时候不想让hdfs检查校验码

在FileSystem的open()之前通过设置FileSystem的setVerifyCheckSum(false)方法禁用校验和
或者命令行使用get时候添加选项-ignoreCrc或者直接使用-copyToLocal
    fs.setVerifyChecksum(false)   fs.open(new Path(“”)) // 就不进行校验检查了
    Hadoop fs –get –ignoreCrc hdfs://master:9000/a.txt
    Hadoop fs –copyToLocal hdfs://master:9000/a.txt

二、CheckSum校验原理

Hadoop数据的完整性检测,都是通过校验和的比较来完成,在创建新文件时(也就是在上传数据到hdfs上时)将校验和的值和数据一起保存起来。NameNode会收到来自client、DataNode的检验和信息,根据这两个信息来维护文件的块存储及向客户端提供块读取服务。

HDFS会对写入的所有数据计算校验和,并在读取数据时验证校验和。
常用的错误检测码是CRC-32(循环冗余校验),任何大小的数据输入均计算得到一个32位的整数校验和。
在写入文件时,hdfs为每个数据块都生成一个crc文件。客户端读取数据时生成一个crc与数据节点存储的crc做比对,如果不匹配则说明数据已经损坏了。数据节点在后台运行一个程序定期(默认为21天)检测数据,防止物理存储介质中位衰减而造成的数据损坏。

  1. DataNode在写入时计算出校验和,然后每次读的时候再计算校验和进行检验
    hdfs会为每一个固定长度的数据(一个个数据包)执行一次校验和
    这个值由io.bytes.per.checksum指定,默认是512字节。
    因为CRC32是32位即4个字节,这样校验和占用的空间就会少于原数据的1%。

  2. datanode在存储收到的数据前会校验数据的校验和,比如收到客户端的数据或者其他副本传过来的数据。
    如hdfs数据流中客户端写入数据到hdfs时的数据流,在管道的最后一个datanode会去检查这个校验和
    如果发现错误,就会抛出ChecksumException到客户端

    从datanode读数据的时候一样要检查校验和,而且每个datanode还保存了检查校验和的日志,每次校验都会记录到日志中

  3. 除了读写操作会检查校验和以外,datanode还跑着一个后台进程(DataBlockScanner)
    定期校验存在在它上面的block,因为除了读写过程中会产生数据错误以外,硬件本身也会产生数据错误,比如位衰减(bit rot)

你可能感兴趣的:(hadoop,hadoop,数据完整性,CheckSum)