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 = newRawLocalFileSystem(); fs.initialize(null, conf);
或者直接设置fs.file.impl属性为 org.apache.hadoop.fs.RawLocalFileSystem 这样会全局禁用checksum
LocalFileSystem 内部使用了ChecksumFileSystem完成checksum工作。通过 ChecksumFileSystem 可以添加校验和功能。
FileSystem rawFs = ... FileSystem checksummedFs = newChecksumFileSystem(rawFs);