本文作者喻兆靖,介绍了为什么 B 站选择 Flink + Hudi 的数据湖技术方案,以及针对其做出的优化。主要内容为:
1.传统离线数仓痛点
2.数据湖技术方案
3.Hudi 任务稳定性保障
4.数据入湖实践
5.增量数据湖平台收益
6.社区贡献
7.未来的发展与思考
一、传统离线数仓痛点
1. 痛点
之前 B 站数仓的入仓流程大致如下所示:
在这种架构下产生了以下几个核心痛点:
总结一下就是:
2. 痛点思考
3. 解决方案: Magneto - 基于 Hudi 的增量数据湖平台
以下是基于 Magneto 构建的入仓流程:
二、数据湖技术方案
1. Iceberg 与 Hudi 的取舍
统计截止至 2021-08-09
大致可以分为以下几个主要纬度来进行对比:
综合对比,我们选择了 Hudi 作为我们的数据湖组件,并在其上继续优化我们需要的功能 ( Flink 更好的集成、Clustering 支持等)
2. 选择 Flink + Hudi 作为写入方式
我们选择 Flink + Hudi 的方式集成 Hudi 的主要原因有三个:
我们部分自己维护了 Flink 引擎,支撑了全公司的实时计算,从成本上考虑不想同时维护两套计算引擎,尤其是在我们内部 Spark 版本也做了很多内部修改的情况下。
Spark + Hudi 的集成方案主要有两种 Index 方案可供选择,但是都有劣势:Bloom Index:使用 Bloom Index 的话,Spark 会在写入的时候,每个 task 都去 list 一遍所有的文件,读取 footer 内写入的 Bloom 过滤数据,这样会对我们内部压力已经非常大的 HDFS 造成非常恐怖的压力。Hbase Index:这种方式倒是可以做到 O(1) 的找到索引,但是需要引入外部依赖,这样会使整个方案变的比较重。
我们需要和 Flink 增量处理的框架进行对接。
3. Flink + Hudi 集成的优化
针对 Hudi 0.8 版本集成暴露出来的问题,B站和社区合作进行了优化与完善。
背景: 支持在已经存在 Hudi 表启动 Flink 任务写入,从而可以做到由 Spark on Hudi 到 Flink on Hudi 的方案切换
原方案:
问题: 每个 Task 处理全量数据,然后选择属于当前 Task 的 HoodieKey 存入 state 优化方案。
效果: 通过将 Bootstrap 功能单独抽出一个 Operator,做到了索引加载的可扩展性,加载速度提升 N (取决于并发度) 倍。
背景: 在 Hudi 0.8 版本的 StreamWriteFunction 中,存在极端情况下的数据一致性问题。
原方案:
问题: CheckpointComplete不在CK生命周期内,存在CK成功但是instant没有commit的情 况,从而导致出现数据丢失。
优化方案:
背景 :Append 模式是用于支持不需要 update 的数据集时使用的模式,可以在流程中省略索引、 合并等不必要的处理,从而大幅提高写入效率。
主要修改:
三、Hudi 任务稳定性保障
1. Hudi 集成 Flink Metrics
通过在关键节点上报 Metric,可以比较清晰的掌握整个任务的运行情况:
2. 系统内数据校验
3. 系统外数据校验
四、数据入湖实践
1. CDC数据入湖
由于目前开源的各种方案都没办法直接支持 TiDB 的数据导出,直接使用 Select 的方式会影响数 据库的稳定性,所以拆成了全量 + 增量的方式:
MySQL 的入湖方案是直接使用开源的 Flink-CDC,将全量和增量数据通过一个 Flink 任务写入 Kafka topic:
2. 日志数据增量入湖
五、增量数据湖平台收益
六、社区贡献
上述优化都已经合并到 Hudi 社区,B站在未来会进一步加强 Hudi 的建设,与社区一起成。
部分核心PR
七、未来的发展与思考
本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载者并注明出处:https://www.jmbhsh.com/shipinzhuangshi/36609.html