HDFS数据完整性之校验和checksum

转载请注明出处:hadoop深入研究:(六)——HDFS数据完整性

数据完整性

IO操作过程中难免会出现数据丢失或脏数据,数据传输得量越大出错得几率越高。校验错误最常用得办法就是传输前计算一个校验和,传输后计算一个校验和,两个校验和如果不相同就说明数据存在错误,比较常用得错误校验码是CRC32.

hdfs数据完整性

hdfs写入的时候计算出校验和,然后每次读的时候再计算校验和。要注意的一点是,hdfs每固定长度就会计算一次校验和,这个值由io.bytes.per.checksum指定,默认是512字节。因为CRC32是32位即4个字节,这样校验和占用的空间就会少于原数据的1%。1%这个数字在hadoop中会经常看到。以后有时间会整理一份hadoop和1%不得不说的故事。
datanode在存储收到的数据前会校验数据的校验和,比如收到客户端的数据或者其他副本传过来的数据。想一下前面的文章hadoop深入研究:(三)——hdfs数据流中客户端写入数据到hdfs时的数据流,在管道的最后一个datanode会去检查这个校验和,如果发现错误,就会抛出ChecksumException到客户端。
客户端从datanode读数据的时候一样要检查校验和,而且每个datanode还保存了检查校验和的日志,客户端的每一次校验都会记录到日志中。
除了读写操作会检查校验和以外,datanode还跑着一个后台进程(DataBlockScanner)来定期校验存在在它上面的block,因为除了读写过程中会产生数据错误以外,硬件本身也会产生数据错误,比如说位衰减(bit rot)。
如果客户端发现有block坏掉呢,会怎么恢复这个坏的块,主要分几步:
1.客户端在抛出ChecksumException之前会把坏的block和block所在的datanode报告给namenode
2.namenode把这个block标记为已损坏,这样namenode就不会把客户端指向这个block,也不会复制这个block到其他的datanode。
3.namenode会把一个好的block复制到另外一个datanode
4.namenode把坏的block删除掉
如果出于一些原因在操作的时候不想让hdfs检查校验码,在调用FileSystem的open方法前调用setVerityCheckSum方法,并设为为false即可,命令行下可以使用-ignoreCrc参数。

实现

LocalFileSystem继承自ChecksumFileSystem,已经实现了checksum功能,checksum的信息存储在与文件名同名的crc文件中,发现错误的文件放在bad_files文件夹中。如果你确认顶层系统已经实现了checksum功能,那么你就没必要使用LocalFileSystem,改为用RowLocalFileSystem。可以通过更改fs.file.impl=org.apache.hadoop.fs.RawLoacalFileSystem全局指定,也可以通过代码直接实例化。
[java] view plain copy
  1. Configuration conf=...  
  2.        FileSystem fs=new RawLocalFileSystem();  
  3.        fs.initialize(null, conf);  
如果其他的FileSystem想拥有checksum功能的话,只需要用ChecksumFileSystem包装一层即可:
[java] view plain copy
  1. FileSystem rawFs=...  
  2.         FileSystem checksummedFs=new ChecksumFileSystem(fs){} ; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值