《Hadoop权威指南》ch5 Data Integrity

Data Integrity(数据完整性)

尽管磁盘和网络的每个I/O操作,对数据造成损坏的可能性都很低,但是如果系统中需要处理的数据量大到Hadoop的处理极限时,数据被损坏的概率还是很高的。

Checksum (校验和)

在数据第一次引入的时候计算checksum,当数据在进行传输后再计算一次checksum,若不同则代表数据已损坏。其中,校验和作为数据也是有可能损坏的,但是相比于普通数据要小的多,所以损坏的可能性也非常小。

常用的错误检测码为CRC-32(32-bit cyclic redundancy check 32位循环冗余校验),任何大小的数据输入均计算得出一个32位的整数校验和。

Data Integrity in HDFS

  • dfs.bytes-per-checksum指定计算校验和字节的长度,默认为512个字节,CRC-32校验和是4个字节,因此存储数据的额外开销低于1%。

  • datanode从客户端或者其它datanode收到数据后对数据进行验证。

  • 每个datanode会保存检验和日志(persistent log of checksum verification),用来保存每次验证的验证时间。

  • 每个datanode也会在后台线程运行DataBlockScanner,定期验证该datanode上的数据块,该措施可用来解决数据的物理损坏。

  • 每个HDFS存储着每个数据块的复本(replica),因此可以通过数据复本修复损坏的数据块。

  • open()方法读取文件之前,可以将FileSystem实例的setVerifyChecksum(false)禁用校验和验证。该方法可以用来处理一些已损坏的数据,比如尝试是否能恢复部分数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Tests read/seek/getPos/skipped opeation for input stream.
*/
private void testChecker(FileSystem fileSys, boolean readCS)
throws Exception {
Path file = new Path("try.dat");
writeFile(fileSys, file);

try {
if (!readCS) {
fileSys.setVerifyChecksum(false);
}

stm = fileSys.open(file);
checkReadAndGetPos();
checkSeek();
checkSkip();
//checkMark
assertFalse(stm.markSupported());
stm.close();
} finally {
if (!readCS) {
fileSys.setVerifyChecksum(true);
}
cleanupFile(fileSys, file);
}
}
Have a nice day!