《Hadoop权威指南:大数据的存储与分析》—5 Hadoop的I/O操作
第5章
Hadoop的I/O操作
Hadoop自带一套原子操作用于数据I/O操作。其中有一些技术比Hadoop本身更常用,如数据完整性保持和压缩,但在处理多达好几个TB的数据集时,特别值得关注。其他一些则是Hadoop工具或API,它们所形成的构建模块可用于开发分布式系统,比如序列化框架和在盘(on-disk)数据结构。
5.1 数据完整性
Hadoop用户肯定都希望系统在存储和处理数据时不会丢失或损坏任何数据。尽管磁盘或网络上的每个I/O操作不太可能将错误引入自己正在读/写的数据中,但是如果系统中需要处理的数据量大到Hadoop的处理极限时,数据被损坏的概率还是很高的。
检测数据是否损坏的常见措施是,在数据第一次引入系统时计算校验和(checksum)并在数据通过一个不可靠的通道进行传输时再次计算校验和,这样就能发现数据是否损坏。如果计算所得的新校验和与原来的校验和不匹配,我们就认为数据已损坏。但该技术并不能修复数据——它只能检测出数据错误。(这正是不使用低端硬件的原因。具体说来,一定要使用ECC内存。)注意,校验和也是可能损坏的,不只是数据,但由于校验和比数据小得多,所以损坏的可能性非常小。
常用的错误检测码是CRC-32(32位循环冗余校验),任何大小的数据输入均计算得到一个32位的整数校验和。Hadoop ChecksumFileSystem使用CRC-32计算校验和,HDFS用于校验和计算的则是一个更有效的变体CRC-32C。
5.1.1 HDFS的数据完整性
HDFS会对写入的所有数据计算校验和,并在读取数据时验证校验和。它针对每个由dfs.bytes-per-checksum指定字节的数据计算校验和。默认情况下为512个字节,由于CRC-32校验和是4个字节,所以存储校验和的额外开销低于1%。
datanode负责在收到数据后存储该数据及其校验和之前对数据进行验证。它在收到客户端的数据或复制其他datanode的数据时执行这个操作。正在写数据的客户端将数据及其校验和发送到由一系列datanode组成的管线(详见第3章),管线中最后一个datanode负责验证校验和。如果datanode检测到错误,客户端便会收到一个IOException异常的一个子类,对于该异常应以应用程序特定的方式来处理,比如重试这个操作。
客户端从datanode读取数据时,也会验证校验和,将它们与datanode中存储的校验和进行比较。每个datanode均持久保存有一个用于验证的校验和日志(persistent log of checksum verification),所以它知道每个数据块的最后一次验证时间。客户端成功验证一个数据块后,会告诉这个datanode,datanode由此更新日志。保存这些统计信息对于检测损坏的磁盘很有价值。
不只是客户端在读取数据块时会验证校验和,每个datanode也会在一个后台线程中运行一个DataBlockScanner,从而定期验证存储在这个datanode上的所有数据块。该项措施是解决物理存储媒体上位损坏的有力措施。11.1.4节将详细描述如何访问扫描报告。
由于HDFS存储着每个数据块的复本(replica),因此它可以通过数据复本来修复损坏的数据块,进而得到一个新的、完好无损的复本。基本思路是,客户端在读取数据块时,如果检测到错误,首先向namenode报告已损坏的数据块及其正在尝试读操作的这个datanode,再抛出ChecksumException异常。namenode将这个数据块复本标记为已损坏,这样它不再将客户端处理请求直接发送到这个节点,或尝试将这个复本复制到另一个datanode。之后,它安排这个数据块的一个复本复制到另一个datanode,如此一来,数据块的复本因子(replication factor)又回到期望水平。此后,已损坏的数据块复本便被删除。
在使用open()方法读取文件之前,将false值传递给FileSystem对象的setVerifyChecksum()方法,即可以禁用校验和验证。如果在命令解释器中使用带-get选项的-ignoreCrc命令或者使用等价的-copyToLocal命令,也可以达到相同的效果。如果有一个已损坏的文件需要检查并决定如何处理,这个特性是非常有用的。例如,也许你希望在删除该文件之前尝试看看是否能够恢复部分数据。
可以用hadoop 的命令fs –checksum来检查一个文件的校验和。这可用于在HDFS中检查两个文件是否具有相同内容,distcp命令也具有类似的功能。详情可以参见3.7节。
- 点赞
- 收藏
- 关注作者
评论(0)