写点什么

vivo HDFS EC 大规模落地实践

  • 2025-10-16
    广东
  • 本文字数:3837 字

    阅读完需:约 13 分钟

作者:Gu Ruinan -  互联网大数据团队- Zhao Yongxiang

Erasure Coding(简称 EC),是一种纠删码。EC 编码能够对部分缺失的数据进行数据恢复,广泛应用于存储与通信领域。在 Hadoop3.0 版本中,作为一种新的冗余存储的方式引入进来。使用 EC 编码的方式替代原来的三副本存储,保证数据可靠性的同时可以节约存储。相应地,付出的代价是读取性能的下降,对于访问频率不高的数据,使用 EC 编码很合适。

vivo 目前 HDFS 集群节点达万台级别,数据规模接近 EB 级别,并且业务数据规模还在以较高速度持续增长中。在推进压缩算法缓解存储压力的同时,EC 编码的推进也是存储降本的一大有力手段。


1 分钟看图掌握核心观点👇

一、背景

Reed-Soloman 编码(简称:RS 码),是 EC 里一种经典的编码算法。下面简单介绍一下 Reed-Soloman 编码过程(不涉及数学原理的详细解析)。

假设我们的输入数据以 D1,D2,...D5 的向量来表示,矩阵 B 为编码矩阵,进行编码后得到 D 和 C 组成的矩阵,其中 D 为数据块(data block),C 为校验块(parity block)。我们的数据写入都需要经过编码后才能进行存储。


假设我们抹除掉了 D1,D4,C2。


我们能通过编码矩阵得到一个用于恢复的矩阵,将这个矩阵与剩余块相乘,可得到原来完整的输入数据,再次进行编码后可恢复 C2。


二、存储布局的改变

EC 编码对 HDFS 的应用,使数据块存储的结构发生了改变。

在传统三副本的策略中,一个文件被划分为不同的块(block)进行存储,一个数据块对应三个副本(replication),每个副本存储的内容完全一致,数据的存储时连续的,这种布局称为连续块存储布局(Contigous Block Layout)。


在 EC 策略中,一个文件被划分为不同的块组(Block Group)进行存储,一个块组内划分为多个内部块(Internal Block),其中,内部块又分为数据块(Data Block)和校验块(Parity Block)。数据块存储文件的数据,校验块存储由数据块生成的校验内容。一个块组内,可容忍的块丢失数量与校验块数量相同,如果丢失块的数量大于校验块数量,则数据不可被恢复。


在块组中,数据并不像三副本策略一样连续存储在一个块中,而是将连续的数据拆分为多个 Cell,分散存储在不同的内部块中,形成一个个条带(Stripe)。这种布局称为条带存储布局(Striped Block Layout)。


我们集群目前采用 EC 策略 RS6-3-1024k,其中 6 表示块组中数据块数量,3 表示块组中校验块数量,1024k 表示 Cell 大小。


三副本是 HDFS 默认的冗余存储方式,优点是当有机器宕机,数据丢失时,不会影响用户的读取,补块的方式也仅仅是副本的复制,简单高效。缺点也很明显,存储的冗余度高,三副本的存储冗余度达到 200%。


EC 编码通过编码的存储方式,来进行冗余存储。优点是存储的冗余度低(具体的冗余度取决于不同的存储策略),可靠性高。缺点是写入需要编码,造成性能的下降(大概 3-4 倍),补块时间长(校验块越多,补块时间越长),读取时如果遇到 DN 宕机,也需要额外的资源与时间进行解码恢复。


三、HDFS EC 码应用实践

3.1 兼容性问题

3.1.1 服务端

早在 2020 年,EC 已经在 vivo 的 HDFS 集群中投入使用。EC 是 Hadoop3.0 后推出的新特性,要想正常使用,服务端和客户端都需要升级到 3.0 或以上版本。


由于离线集群规模庞大,升级的调研和实施需要耗费比较长的时间。因此,我们临时搭建了一套基于 3.1 版本的冷备专用集群,使用 EC 来存储冷备数据,如下图:


冷备集群使用 3.1 版本的 Yarn,可以同时访问热数据与冷数据,3.1 版本的 HDFS 专门用来存储 EC 编码的冷数据。


由于新增冷备集群的方案增加了集群运维的成本,架构也不够优雅,只是暂时的解决办法。在 2021 年,我们离线集群完成了 HDFS 从 2.6 到 3.1 的全面升级,正式支持 EC 编码,在 2022 年,我们完成绝大部分冷备集群的数据到离线集群的迁移,增量数据全部写到离线集群中。


3.1.2 客户端

我们没有对 Client2.x 客户端访问 EC 文件做兼容性的开发,更多是通过推动用户升级客户端来访问 EC 文件,例如 Spark2 任务切换至 Spark3 任务。该方案增加了用户迁移的成本,但同时也减少了 HDFS 侧的开发成本,用户任务逐步往 Spark3 迁移也更符合未来的规划。


3.2 EC 异步转换

由于 EC 编码会带来对文件读写性能的下降,对 EC 编码的定位主要应用在冷数据的存储,业务并不直接写 EC 数据,而是采用后台转储的方式,把三副本数据转储成 EC 数据。对不同业务而言,对"冷"的标准都不一致,不能用统一的标准来衡量数据的冷热。在推广 EC 编码的过程中,平台并不用统一的标准来“强制”把用户数据转为 EC,是否转为 EC 的最终决定权在用户。我们向用户提供分区访问频率的数据作为参考,帮助用户来了解不同分区路径的访问频次,让用户更好地选择哪些分区转为 EC 编码。用户可以通过大数据开发者平台(Big data developer platform)设置 x 天前的数据转为 EC 存储,后台程序会将相应分区通过 Hadoop distcp,将三副本写入到已设置 EC 策略的目录中,再用新目录替换掉原目录,其中目录名称不变,保证了元数据一致,用户无需修改代码。


3.3 Distcp 数据校验

先来介绍一下 HDFS 两种校验和的方式。


3.3.1 MD5MD5CRC

此方式为 HDFS 默认的校验方式,这种校验方式会进行两次 MD5 计算一次 CRC 计算,从名字就可以反映出来。

  • 块级校验和:所有 chunk CRC 的级联的 MD5 值。(an MD5 of a concatenation of chunk CRCs)

  • 文件级校验和:所有块校验和的级联的 MD5 值。(the MD5 of the concatenation of all the block checksums)


由定义可知,这种方式对于 HDFS 分块大小敏感,不同的分块大小块级校验和不一样,导致文件校验和也会不一样。


3.3.2 Composite CRC

Composite CRC 一个新的校验和计算方式。

当计算块校验和不是简单地将 chunk CRC 进行级联(concatenation),而是将 chunk CRC 进行数学式的组合(mathematically compose),计算文件校验和时对文件所有的 chunk CRC 进行数学式组合。因此,对于文件校验和,该计算方式对于分块大小并不敏感。 CRC 算法相关论文。


在数据进行 distcp 的过程中,HDFS 会进行校验和校验,确保 distcp 的源数据与新数据一致,但正如前文所说,EC 编码会带来存储布局的改变,相同的文件三副本与 EC 数据存储的块大小,块数量都不一致,这让 HDFS 默认的 MD5MD5CRC 的方式变得不再适用。


需要将校验方式改为 COMPOSITE CRC。


可通过 dfs.checksum.combine.mode 改变校验和校验的方式(MD5MD5CRC(默认值) or COMPOSITE_CRC)。


即使 distcp 过程中会进行校验,为了确保万无一失,我们还会对前后的分区目录的校验和校验。(目录校验和计算方式为将目录下文件 MD5 值排序,再进行 MD5 计算)为了保证转 EC 前后文件的一致性,多加一道校验的"工序"是值得的。


3.4 文件损坏与修复

文件损坏与丢块是 HDFS EC 应用绕不开的一个话题,原因是在 Hadoop EC 特性新推出的过程中,有若干与文件损坏相关的 bug。EC 文件损坏的过程主要发生在补块阶段,计算结果的不准确导致了新补的块与原来的块内容不一致。我们在 EC 推广的过程中,也狠狠地踩过文件损坏的“坑”。如何避免文件损坏,如何对补块的结果进行校验,如何修复损坏文件是三个重要的需要解决的问题。


3.4.1 如何避免文件损坏

通过对社区的调研,我们打了若干的 patch 来解决文件损坏与丢块的问题。


3.4.2 对补块结果的校验

我们引入了 HDFS-15759,Patch 提供了一个对 EC 补块的校验功能,在 DN 执行补块任务时,对补块结果进行校验。如果校验失败会抛出异常,并且补块任务会进行重试。


3.4.3 EC 批量校验工具

我们对开源的 EC 批量校验工具进行了定制化的改造,工具能够对 EC 目录进行批量扫描,扫描出目录中的损坏的 EC 文件,在此感谢 Stephen O'Donnell 对工具的开源。


原理大致如下,对数据块进行 EC 编码,通过比对新生成的校验块和原来的校验块,来验证是否存在文件损坏。如果比对通过,则没有文件损坏,如果比对不通过,则存在文件损坏。


工具支持 MR,可以分布式执行,此外,也可只对一个条带进行比对,只生成校验块的第一个条带,比对与原校验块第一个条带是否一致,这些都大大提高了批量校验 EC 文件的效率。


工具地址:

https://github.com/sodonnel/hdfs-ec-validator


3.4.4 修复损坏文件

在我们的集群,绝大部分损坏的文件都是 ORC 文件,ORC 文件发生损坏时,由于其元数据分布的方式,会出现元数据的损坏,ORC 无法解析。


假设一个块组内,数据块编号为 1~6,校验块编号为 7~9,数据块 1 损坏,我们可以通过读取数据块 2~6 加上任一一个校验块,得到"完好"的文件,对于 ORC 文件而言,判断是否完好取决于能否正常解析。


HDFS 客户端 get 文件的时候默认只会读取数据块,我们通过改造 HDFS 客户端,使我们能够读取块组内指定编号的块,通过各种排列组合,得到一个"完好"的文件,之后将"完好"的文件覆盖掉 HDFS 上的损坏文件,来达到文件修复的目的。


3.5 机器异构 &存储策略

由于 EC 数据访问频率低,将 EC 数据存储到大存储的机器上,利用机器异构降低我们的单位存储成本。


在 HDFS 中,如果文件写入的路径设置了 hot 存储策略的目录,则会优先把文件存储到 disk 存储介质当中,如果设置了 cold 存储策略的目录,则会优先把文件存储到 archive 存储介质当中。


因此,当我们将大存储机器的盘都设置为 Archive,并且将 EC 目录设置为 Cold 存储策略,即可将 EC 数据存放到大存储机器上,使 TCO 降低,进一步实现存储降本。


四、总结与展望

vivo 的 HDFS 集群已存有几百 PB 的数据采用 EC-RS6-3-1024k 策略存储,相比三副本 EC-RS6-3-1024k 方式能带来 50%的存储收益,节省了数百 PB 的存储空间,为公司带来了巨大的收益。目前我们推荐用户将访问频次较少的数据转为 EC,因为 EC 会带来读取性能的下降,如何减少 EC 带来的读取性能下降?以及后续细化对用户数据的冷热分层,对越冷的数据采用冗余度越低的 EC 策略,EC 补块速度优化等,都是后续继续大规模推进 EC 需要解决的重要难题。

发布于: 刚刚阅读数: 2
用户头像

官方公众号:vivo互联网技术,ID:vivoVMIC 2020-07-10 加入

分享 vivo 互联网技术干货与沙龙活动,推荐最新行业动态与热门会议。

评论

发布
暂无评论
vivo HDFS EC 大规模落地实践_大数据_vivo互联网技术_InfoQ写作社区