共计 3383 个字符,预计需要花费 9 分钟才能阅读完成。
RAID Node 调研
1. 简介
分布式文件系统主要用于解决海量数据存储的问题,如 Goolge、Facebook 等大型互联网企业都使用分布式文件系统作为数据存储的基础设施,并在其上构建很多服务,分布式文件系统通常采用三副本的策略来保证数据的可靠性,但随着应用数据量的不断膨胀,三副本策略为可靠性牺牲的存储空间也越来越大,如何在不降低数据可靠性的基础上,进一步降低存储空间成本?Facebook 将 erasure code 应用到内部 HDFS 集群中,该方案使用 erasure code 代替传统的三副本策略,在保持集群可用性不变的情况下,节省了数 PB 的存储空间,Facebook 的实现方案 (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 中的一部分。
2. 概况
HDFS RAID 模块提供一个使用 Hadoop 分布式系统(DFS)的分布式 Raid 文件系统(DRFS),在 DRFS 中存储的文件被分成多个由块组成的 stripe。对于每个 stripe,若干 parity(校验)块存储在与源文件对应的 parity 文件中。这使得当源文件或 parity 文件中的块丢失或损坏进可以重新计算并恢复成为可能。
DRFS 的主要好处是增加针对数据损坏的保护,有了这样的保护,可以采用更低的副本数来保持同样的可用性保障,将会节省很大的存储空间。
架构与实现
DRFS 总体架构(Distributed Raid File System)
Raid 是 Hadoop mapreduce 的一个 contrib,Hadoop 0.21.0 以上版本就有。
HDFS Raid 包含几个软件模块:
- DRFS client:为应用提供访问 DRFS 中文件的接口,当在读文件时能透明地恢复任意损坏或丢失的块;
- RaidNode:为存储在 DRFS 的所有数据文件创建和维护 parity 文件的后台进程;
- BlockFixer:周期性重新计算已经丢失或损坏的块;
- Raidshell:允许管理员手动触发丢失或损坏的块的重新计算或检查已遭受不可恢复损坏的文件;
- ErasureCode:提供对块中字节的编码及解码。
1) DRFS client
DRFS client 作为 DFS client 之上的一软件层,拦截所有进来的请求并传它们传递给下边的客户端。当下边的 DFS 抛出 ChecksumException 或 BlockMissingException 异常,DFS client 捕获这些异常,定位当前 source 文件的 parity 文件,并在返回丢失的块给应用前将它们重新计算。
值得注意的是,DRFS client 在读到损坏的文件重新计算丢失的块时,并不会将这些丢失的块存到文件系统中,它在完成应用的请求后将其忽略。BlockFixer 和 RaidShell 能用来永远地修改损坏的块。
2) RaidNode
RaidNode 定期扫描配置指定的所有路径,对于每个路径,递归地检查所有拥有超过 2 个块的文件并选择那些最近(默认是 24 小时内)没被修改过的文件。一旦选择了一个 source 文件,它会遍历该文件的所有 stripe 并为每个 stripe 创建合适数量的 parity 块,最后所有的 parity 块会被合并在一起并存储在与 source 文件相关的 parity 文件。RaidNode 也会定期删除那些已经孤立或过时的 parity 文件。
当前 RaidNode 有两种实现:
LocalRaidNode:在 RaidNode 本地计算 parity 块,因为计算 parity 块是一个计算密集型任务,所以这种方法的可扩展性受到限制;
DistributedRaidNode:分配 MapReduce 任务来计算 parity 块。
3) BlockFixer
BlockFixer 是一个运行在 RaidNode 上的一个后台进程,周期性地检查 DRFS 配置的所有路径的状态。当发现一个有丢失或损坏块时,这些块会被重新计算并放回文件系统中。
从 Namenode 获得损坏文件列表,source 文件通过“解码”来重新构造,parity 文件通过“编码”来重新构造。
当前 BlockFixer 有两种实现:
LocalBlockFixer:在 RaidNode 本地重新计算损坏的块;
DistBlockFixer:分配 MapReduce 任务来重新计算块。
4) RaidShell
RaidShell 是一个允许管理维护和检查 DRFS 的工具,支持手动触发重新计算坏数据块的命令,允许管理查看不可修复文件列表。
运行以下命令可以检验文件系统的完整性:
$HADOOP_HOME/bin/hadoop org.apache.hadoop.raid.RaidShell -fsck [path]
这会打印已损坏文件列表。
5) ErasureCode
ErasureCode 是被 BlockFixer 和 RaiNode 用来生成 parity 块和修改 parity/source 块的一组件,ErasureCode 实现编码和解码。当在编码时,ErasureCode 取几个 source 字节并生成一些 parity 字节。当在解码时,ErasureCode 通过剩余的 souce 字节和 parity 字节来生成丢失的字节。
能被恢复的丢失的字节的个数等于被创建的 parity 字节的个数。比如,我们把 10 个 source 字节编码成 3 个 parity 字节,我们能通过剩下的 10 个字节来恢复任意 3 个丢失的字节。
ErasureCode 有两种实现:
- XOR:只允许创建一个 parity 字节;
- Reed-Solomon:允许创建任意给定数目的 parity 字节。
使用 Reed-Solomon,source 文件的副本数能减少到 1 而不造成数据丢失。1 个块只有 1 个副本的不足是只能通过 1 个固定的机器来读取 1 个块,减少了并行性。因此,Reed-Solomon 应该用在不会被频繁使用的数据。
相关阅读:
Ubuntu 13.04 上搭建 Hadoop 环境 http://www.linuxidc.com/Linux/2013-06/86106.htm
Ubuntu 12.10 +Hadoop 1.2.1 版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm
Ubuntu 上搭建 Hadoop 环境(单机模式 + 伪分布模式)http://www.linuxidc.com/Linux/2013-01/77681.htm
Ubuntu 下 Hadoop 环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm
单机版搭建 Hadoop 环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm
搭建 Hadoop 环境(在 Winodws 环境下用虚拟机虚拟两个 Ubuntu 系统进行搭建)http://www.linuxidc.com/Linux/2011-12/48894.htm
更多 Hadoop 相关信息见Hadoop 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=13