HDFS目前存储文件的方案是将一个文件切分成多个Block进行存储,通常一个Block 64MB或者128MB,每个Block有多个副本(replica),每个副本作为一个整体存储在一个DataNode上,这种方法在增加可用性的同时也增加了存储成本。ErasureCode通过将M个数据block进行编码(Reed-Solomon,LRC),生成K个校验(parity)block, 这M+K个block组成一个block group,可以同时容忍K个block失败,任何K个block都可以由其他M个block算出来. overhead是K/M.
以M=6,K=3为例,使用EC之前,假设block副本数为3,那么6个block一共18个副本,overhead是200%,使用EC后,9个block,每个block只需一个副本,一共9个副本,其中6个数据副本,3个校验副本,overhead是3/6=50%.
HDFS-RAID
HDFS-RAID 这个方案是facebook在 Hadoop 0.20-append分支上做的,为了不引入复杂度,基于HDFS,没有修改HDFS。只支持离线(异步)EC。RaidNode定期扫描配置发现需要转成EC的文件,转换过程可以本地计算也可以通过MapReduce Job。RaidNode内部有一个BlockFixer线程定期检查被配置成EC的文件路径,如果文件有丢失的block或者corrupt的block,就本地重算或者通过MapReduce Job来重算,然后将生成的block插入文件系统中。客户端方面,不需要修改任何代码,只需要修改配置告诉它使用的文件系统是DistributedRaidFileSystem,它封装了DFSClient,截获DFSClient的请求,当DFSClient抛出CheckSumException或者BlockMissingException时,DRFS捕获这些异常,定位到相应的parity file,然后重新算出丢失的block,随后返回给客户端. HDFS-RAID 详解看这
集成EC在HDFS中
HDFS-7285 和HDFS-RAID不同,它是社区最新的正在开发中的将编码过程集成到HDFS内部的方案,需要对整个HDFS内部实现进行改造,包括DataNode,NameNode还有DFSClient,该方案同时支持在线和离线EC。
在线EC
当前HDFS block的副本作为一个整体连续(contiguous)的存储在一个DataNode上,在locality上具有一定的优势,特别是对于MapReduce这样的应用,但是这种方法不好做在线EC。当前社区方案不以block为单位进行EC,而是以strip为单位进行EC(HDFS依旧管理Block)设计思路参考了QFS。对于配置了EC的文件,客户端写入时将文件的数据切成一个个的64KB的strip,相邻的strip发往不同的DataNode,比如当前使用(6,3)-Reed-solomon编码,当前正在写的文件有6个strip: strip1, strip2, strip3, strip4, strip5, strip6, 那么这6个strip和相应的编码出来的3个校验strip共9个strip会并行的发往9个不同的DataNode。这种方式写入性能更好,但是也会对网卡出口带来一些压力,同时牺牲了locality。如果文件大小不是64KB * 6的整数倍(本文例子),那么最后一个strip group显然不是满的,这时客户端还会将最后一个strip group的长度记在校验块中,后续读的时候,可以根据这个长度和数据块长度还有文件长度来校验。
对于append和hflush操作,最后一个parity strip group很可能还没有切换成新的strip group,这就需要DataNode更新最后一个parity strip的数据。
读操作,丢失block时,只需要读9个DataNode中任意6个DataNode即可修复。修复过程需要读多个DataNode,耗费网络带宽和磁盘IO。Xorbas在facebook的HDFS-RAID基础上增加了LRC实现,LRC修复数据需要读的分片数更少,因此比Reed-Solomon修复数据更快,但是在存储成本上高14%.
ECClient模块封装了以上这些读写操作。
离线EC
该方案也支持离线EC,可以异步的将多副本文件转成EC文件,通过集成在NameNode中的ECManager和DataNode上的ECWorker来支持。命令行工具提供replication和ec之间的转换,可以通过命令行配置哪些文件/目录使用EC. 在转换方程中,不支持append。facebook的f4系统同样做的是离线EC,在做到磁盘,主机,机架,数据中心容错的情况下,存储因子做到2.1,看这里
结论
第二个方案比HDFS-RAID更全面,性能更好,在线EC可以马上降低存储成本。但是处于开发中,看状态还需要很久才能完成。如果需要尽快用上EC,使用HDFS-RAID,但是也需要进行port工作。