在读写过程中,由校验和检测数据的完整性
客户端写入datanode的时候,HDFS会对写入的数据计算校验和,默认每512个字节校验一次校验和,由dfs.bytes-per-checksum配置,在 hdfs-default.xml中配置
<property>
<name>dfs.stream-buffer-size</name>
<value>4096</value>
<description>The size of buffer to stream files.
The size of this buffer should probably be a multiple of hardware
page size (4096 on Intel x86), and it determines how much data is
buffered during read and write operations.</description>
</property>
<property>
<name>dfs.bytes-per-checksum</name>
<value>512</value>
<description>The number of bytes per checksum. Must not be larger than
dfs.stream-buffer-size</description>
</property>
HDFS数据的完整性主要体现在HDFS读取数据完整性、写数据完整性、还有磁盘完整性
客户端写数据的时候,将数据和校验和发送到一系列由datanode组成的管线,管线中的最后一个datanode负责校验校验和,如果发现数据校验和对不上,则抛出异常,hdfs会以特定方式处理,例如重试这个操作。
读数据时也会验证校验和,把读出来的数据和读出来的校验和校验,确保读出的数据是正确的,每个datanode都保持着一个用于验证的校验和日志,日志中保存着每个数据块的验证时间,客户端每验证完一个数据块,就会更新日志。
如果在读取数据的过程中,如果检测到数据校验错误,首先会通知namenode这个已损坏数据块以及正在读取的datanode,再抛出ChecksumException异常。namenode将这个数据块副本标记为已损坏,不再将客户端请求发送到这datanode上,并且会把这个数据块的一个副本复制到另一个datanode上,这样数据块的副本因子又可以变成期望水平,默认为3,最后已损坏的数据块会被删除
此外datanode也会在后台线程中运行一个线程定期检查datanode上的所有数据块,避免磁盘损坏。