引自个人blog: http://jiangbo.me/blog/2012/12/21/hdfs-raid/
一、背景
HDFS是构建在普通机器上的分布式文件系统,而这类系统需要解决的一个首要问题就是容错,允许部分节点失效。而为了解决数据的可靠性,HDFS采用了副本策略。默认会为所有的block存放三个副本(具体参见HDFS设计文档)。 副本机制能够有效解决部分节点失效导致数据丢失的问题,但对于大规模的HDFS集群,副本机制会带来大量的存储资源消耗。例如为了存储1PB的数据,默认需要保留3个副本,这意味着实际存储所有副本需要至少3PB的空间。存储空间浪费达到200%。减小浪费的方式主要是减少副本数,而当副本数降低到小于3时,数据丢失的风险会非常高。而HDFS RAID的出现主要是解决降低副本数之后,通过RAID机制中的Erasured Code来确保数据的可用性。
二、整体结构
HDFS RAID的实现(Facebook的实现)主要是在现有的HDFS之上增加了一个包装contrib。之所以不再HDFS上直接修改,原设计者的解释是“HDFS的核心代码已经够复杂了,不想让它更复杂”。
2.1 使用的角度看HDFS RAID(Client端)
HDFS RAID的使用场景主要有两个:raid数据管理和raid数据读取。
2.1.1 Raid数据的管理
对于DRFS的管理,包括DFS中那些文件需要进行raid化,查询raid文件的状态等,主要通过HDFS-RAID提供的RaidShell工具来完成。本质上RaidShell作为一个client工具,通过RPC与集群中的RaidNode通信,完成各种管理操作。
2.1.2 Raid数据读写
使用HDFS RAID的client端需要配置fs.hdfs.impl为DistributedRaidFileSytem,DRFS包装了DFS的读(只是读)请求,当block读取时发生block丢失(抛出MissingBlockException)或损坏(CorruptionException)时,DRFS会捕获这两个异常,并向RaidNode发送RPC对失效的数据进行恢复。
2.2 RaidNode结构(Server端)
RaidNode是HDFS-RAID中除NameNode和JobTracker之外的第三个master node,主要是接收client端的RPC请求和调度各守护线程完成数据的raid化和数据修复,parity文件删除等操作。
2.2.1 两种实现
LocalRaidNode: 在RaidNode本地进行parity计算,parity文件的生成是一个计算密集型任务,而本地计算能力有限,因此该方式的扩展性有限。
DistributedRaidNode: 通过提交mapreduce job来进行parity计算
2.2.2 主要线程
TriggerMonitor: 周期性检查raid-policy配置,根据最新的配置来进行对相应的数据raid化。raid化的调度周期主要收两个配置的影响,raid.config.reload.interval (重新加载raid-policy配置的周期,默认10s)和raid.policy.rescan.interval(重新扫描需要raid化的src的间隔,默认1小时)。简单讲,当新增了一个policy时,默认10s内该policy会被加载执行。而在一个已经raid化的目录中新增了一个文件时,该文件将在1个小时内被raid话。
BlockIntegrityMonitor: 负责通过DFS的fsck来对DRFS中已经raid化的数据进行检查,检查内容主要包括corrupt(损坏)和decomssion(丢失)的文件。一旦检测到这类文件的存在,BlocIntegrityMonitor会通过其维护的CorruptMonitor和DecomissionMonitor的两个线程来进行数据的修复。BlockIntegrityMonitor对应local和dist两种模式有两个实现,分别为LocalBlockIntegrityMonitor和DistBlockIntegrityMonitor。(可通过raid.blockfix.classname配置项设置,默认为dist)。区别主要在获取的corruptionMonitor和DecomissionMonitor的实现不同。
LocalBlockIntegrityMonitor: 提供了CorruptMonitor实现会循环通过fsck检查corrupt文件,通过BlockReconstructor.CorruptBlockReconstructor重建这些文件。但该实现不提供Decomissioning文件的监控处理。local模式下corrput文件的重建是在RaidNode上进行的,对大量数据的重建,会对RaidNode有较大的压力。