HDFS RAID

March 14, 2012 / ErasureCode, Hadoop, HDFS, RAID

背景

HDFS RAID的工作源自Facebook。首先,看看HDFS RAID的作者之一Dhruba Borthakur在2009年发表的博文的一部分。

HDFS的主要不足之一是每份数据要复制在三个地方,当今,磁盘存储越来越便宜,这是可以接受的,相对于小型或中型规模的机群,这并不是一个问题。使用15块磁盘和10块磁盘的价格差距并不大。假设每GB数据的成本为$1,那么15块1TB磁盘和10块1TB磁盘的价格差只是$5k。但如果机群的总数据量是10PB的话,那么将数据存储在两个地方而不是三个,节省的成本是$10,000,000!

上述是在2009年的数据,如今磁盘存储的成本已不到¥1/GB了。

HDFS使用3副本是因为它使用商用机器以及磁盘有不可忽略的出现故障的机率。据观测,在实践中使用3副本已经足以保证不丢失数据。现在的挑战是要保持真实的副本数接近2而有效副本数是3。Erasure Codes是最好的实现方案。

作者的想法参考自CMU的DiskReduce,这是一种在HDFS实现erasure codes的方法。HDFS的代码本身就比较复杂,为了不使其变得更加复杂,作者将HDFS Erasure Coding作为HDFS之上的一个软件层,而不是HDFS中的一部分。

概况

HDFS RAID模块提供一个使用Hadoop分布式系统(DFS)的分布式Raid文件系统(DRFS),在DRFS中存储的文件被分成多个由块组成的stripe。对于每个stripe,若干parity(校验)块存储在与源文件对应的parity文件中。这使得当源文件或parity文件中的块丢失或损坏进可以重新计算并恢复成为可能。

DRFS的主要好处是增加针对数据损坏的保护,有了这样的保护,可以采用更低的副本数来保持同样的可用性保障,将会节省很大的存储空间。

架构与实现

Raid是Hadoop mapreduce的一个contrib,Hadoop 0.21.0以上版本就有。

HDFS Raid包含几个软件模块:

DRFS client

DRFS client作为DFS client之上的一软件层,拦截所有进来的请求并传它们传递给下边的客户端。当下边的DFS抛出ChecksumException或BlockMissingException异常,DFS client捕获这些异常,定位当前source文件的parity文件,并在返回丢失的块给应用前将它们重新计算。

值得注意的是,DRFS client在读到损坏的文件重新计算丢失的块时,并不会将这些丢失的块存到文件系统中,它在完成应用的请求后将其忽略。BlockFixer和RaidShell能用来永远地修改损坏的块。

RaidNode

RaidNode定期扫描配置指定的所有路径,对于每个路径,递归地检查所有拥有超过2个块的文件并选择那些最近(默认是24小时内)没被修改过的文件。一旦选择了一个source文件,它会遍历该文件的所有stripe并为每个stripe创建合适数量的parity块,最后所有的parity块会被合并在一起并存储在与source文件相关的parity文件。RaidNode也会定期删除那些已经孤立或过时的parity文件。

当前RaidNode有两种实现:

BlockFixer

BlockFixer是一个运行在RaidNode上的一个后台进程,周期性地检查DRFS配置的所有路径的状态。当发现一个有丢失或损坏块时,这些块会被重新计算并放回文件系统中。

从Namenode获得损坏文件列表,source文件通过“解码”来重新构造,parity文件通过“编码”来重新构造。

当前BlockFixer有两种实现:

RaidShell

RaidShell是一个允许管理维护和检查DRFS的工具,支持手动触发重新计算坏数据块的命令,允许管理查看不可修复文件列表。

运行以下命令可以检验文件系统的完整性:

$HADOOP_HOME/bin/hadoop org.apache.hadoop.raid.RaidShell -fsck [path]

这会打印已损坏文件列表。

ErasureCode

ErasureCode是被BlockFixer和RaiNode用来生成parity块和修改parity/source块的一组件,ErasureCode实现编码和解码。当在编码时,ErasureCode取几个source字节并生成一些parity字节。当在解码时,ErasureCode通过剩余的souce字节和parity字节来生成丢失的字节。

能被恢复的丢失的字节的个数等于被创建的parity字节的个数。比如,我们把10个source字节编码成3个parity字节,我们能通过剩下的10个字节来恢复任意3个丢失的字节。

ErasureCode有两种实现:

使用Reed-Solomon,source文件的副本数能减少到1而不造成数据丢失。1个块只有1个副本的不足是只能通过1个固定的机器来读取1个块,减少了并行性。因此,Reed-Solomon应该用在不会被频繁使用的数据。

参考资料

  1. HDFS and Erasure Codes (HDFS-RAID)
  2. HDFS-RAID

后记

文中若有错误或疏漏之处,烦请批评指正。