Hudi 在 vivo 湖仓一体的落地实践
作者:vivo 互联网大数据团队 - Xu Yu
在增效降本的大背景下,vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能。主要应用在流批同源、实时链路优化及宽表拼接等业务场景。
一、Hudi 基础能力及相关概念介绍
1.1 流批同源能力
与Hive不同,Hudi数据在Spark/Flink写入后,下游可以继续使用Spark/Flink引擎以流读的形式实时读取数据。同一份Hudi数据源既可以批读也支持流读。
Flink、Hive、Spark的流转批架构:
Hudi流批同源架构:
1.2 COW和MOR的概念
Hudi支持COW(Copy On Write)和MOR(Merge On Read)两种类型:
(1)COW写时拷贝:
每次更新的数据都会拷贝一份新的数据版本出来,用户通过最新或者指定version的可以进行数据查询。缺点是写入的时候往往会有写内存放大的情况,优点是查询不需要合并,直接读取效率相对比较高。JDK中的CopyOnWriteArrayList/
CopyOnWriteArraySet 容器正是采用了 COW 思想。
COW表的数据组织格式如下:
(2)MOR读时合并:
每次更新或者插入新的数据时,并写入parquet文件,而是写入Avro格式的log文件中,数据按照FileGroup进行分组,每个FileGroup由base文件(parquet文件)和若干log文件组成,每个FileGroup有单独的FileGroupID;在读取的时候会在内存中将base文件和log文件进行合并,进而返回查询的数据。缺点是合并需要花费额外的合并时间,查询的效率受到影响;优点是写入的时候效率相较于COW快很多,一般用于要求数据快速写入的场景。
MOR数据组织格式如下:
1.3 Hudi的小文件治理方案
Hudi表会针对COW和MOR表制定不同的文件合并方案,分别对应Clustering和Compaction。
Clustering顾名思义,就是将COW表中多个FileGroup下的parquet根据指定的数据大小重新编排合并为新的且文件体积更大的文件块。如下图所示:
Compaction即base parquet文件与相同FileGroup下的其余log文件进行合并,生成最新版本的base文件。如下图所示:
1.4 周边引擎查询Hudi的原理
当前主流的OLAP引擎等都是从HMS中获取Hudi的分区元数据信息,从InputFormat属性中判断需要启动HiveCatalog还是HudiCatalog,然后生成查询计划最终执行。当前StarRocks、Presto等引擎都支持以外表的形式对Hudi表进行查询。
1.5 Procedure介绍
Hudi 支持多种Procedure,即过程处理程序,用户可以通过这些Procedure方便快速的处理Hudi表的相关逻辑,比如Compaction、Clustering、Clean等相关处理逻辑,不需要进行编码,直接通过sparksql的语句来执行。
1.6 项目架构
1. 按时效性要求进行分类
秒级延迟:
分钟级延迟:
当前Hudi主要还是应用在准实时场景:
上游从Kafka以append模式接入ods的cow表,下游部分dw层业务根据流量大小选择不同类型的索引表,比如bucket index的mor表,在数据去重后进行dw构建,从而提供统一数据服务层给下游的实时和离线的业务,同时ods层和dw层统一以insert overwrite的方式进行分区级别的容灾保障,Timeline上写入一个replacecommit的instant,不会引发下游流量骤增,如下图所示:
1.7 线上达成能力
实时场景:
支持1亿条/min量级准实时写入;流读延迟稳定在分钟级
离线场景:
支持千亿级别数据单批次离线写入;查询性能与查询Hive持平(部分线上任务较查询Hive提高20%以上)
小文件治理:
95%以上的合并任务单次执行控制在10min内完成
二、组件能力优化
2.1 组件版本
当前线上所有Hudi的版本已从0.12 升级到 0.14,主要考虑到0.14版本的组件能力更加完备,且与社区前沿动态保持一致。
2.2 流计算场景
1. 限流
数据积压严重的情况下,默认情况会消费所有未消费的commits,往往因消费的commits数目过大,导致任务频繁OOM,影响任务稳定性;优化后每次用户可以摄取指定数目的commits,很大程度上避免任务OOM,提高了任务稳定性。
2. 外置clean算子
避免单并行度的clean算子最终阶段影响数据实时写入的性能;将clean单独剥离到
compaction/clustering执行。这样的好处是单个clean算子,不会因为其生成clean计划和执行导致局部某些Taskmanager出现热点的问题,极大程度提升了实时任务稳定性。
3. JM内存优化
部分大流量场景中,尽管已经对Hudi进行了最大程度的调优,但是JM的内存仍然在较高水位波动,还是会间隔性出现内存溢出影响稳定性。这种情况下我们尝试对 state.backend.fs.memory-threshold 参数进行调整;从默认的20KB调整到1KB,JM内存显著下降;同时运行至今state相关数据未产生小文件影响。
2.3 批计算场景
1. Bucket index下的BulkInsert优化
0.14版本后支持了bucket表的bulkinsert,实际使用过程中发现分区数很大的情况下,写入延迟耗时与计算资源消耗较高;分析后主要是打开的句柄数较多,不断CPU IO 频繁切换影响写入性能。
因此在hudi内核进行了优化,主要是基于partition path和bucket id组合进行预排序,并提前关闭空闲写入句柄,进而优化cpu资源使用率。
这样原先50分钟的任务能降低到30分钟以内,数据写入性能提高约30% ~ 40%。
优化前:
优化后:
2. 查询优化
0.14版本中,部分情况下分区裁剪会失效,从而导致条件查询往往会扫描不相关的分区,在分区数庞大的情况下,会导致driver OOM,对此问题进行了修复,提高了查询任务的速度和稳定性。
eg:select * from `hudi_test`.`tmp_hudi_test` where day='2023-11-20' and hour=23;
(其中tmp_hudi_test是一张按日期和小时二级分区的表)
修复前:
修复后:
优化后不仅包括减少分区的扫描数目,也减少了一些无效文件RPC的stage。
3. 多种OLAP引擎支持
此外,为了提高MOR表管理的效率,我们禁止了RO/RT表的生成;同时修复了原表的元数据不能正常同步到HMS的缺陷(这种情况下,OLAP引擎例如Presto、StarRocks查询原表数据默认仅支持对RO/RT表的查询,原表查询为空结果)。
2.4 小文件合并
1. 序列化问题修复
0.14版本Hudi在文件合并场景中,Compaction的性能相较0.12版本有30%左右的资源优化,比如:原先0.12需要6G资源才能正常启动单个executor的场景下,0.14版本 4G就可以启动并稳定执行任务;但是clustering存在因TypedProperties重复序列化导致的性能缺陷。完善后,clustering的性能得到30%以上的提升。
可以从executor的修复前后的火焰图进行比对。
修复前:
修复后:
2. 分批compaction/clustering
compaction/clustering默认不支持按commits数分批次执行,为了更好的兼容平台调度能力,对compaction/clustering相关procedure进行了改进,支持按批次执行。
同时对其他部分procedure也进行了优化,比如copy_to_table支持了列裁剪拷贝、
delete_procedures支持了批量执行等,降低sparksql的执行时间。
3. clean优化
Hudi0.14 在多分区表的场景下clean的时候很容易OOM,主要是因为构建
HoodieTableFileSystemView的时候需要频繁访问TimelineServer,因产生大量分区信息请求对象导致内存溢出。具体情况如下:
对此我们对partition request Job做了相关优化,将多个task分为多个batch来执行,降低对TimelineSever的内存压力,同时增加了请求前的缓存判断,如果已经缓存的将不会发起请求。
改造后如下:
此外实际情况下还可以在FileSystemViewManager构建过程中将 remoteview 和 secondview 的顺序互调,绝大部分场景下也能避免clean oom的问题,直接优先从secondview中获取分区信息即可。
2.5 生命周期管理
当前计算平台支持用户表级别生命周期设置,为了提高删除的效率,我们设计实现了直接从目录对数据进行删除的方案,这样的收益有:
-
降低了元数据交互时间,执行时间快;
-
无须加锁、无须停止任务;
-
不会影响后续compaction/clustering 相关任务执行(比如执行合并的时候不会报文件不存在等异常)。
删除前会对compaction/clustering等instants的元数据信息进行扫描,经过合法性判断后区分用户需要删除的目录是否存在其中,如果有就保存;否则直接删除。流程如下:
三、总结
我们分别在流批场景、小文件治理、生命周期管理等方向做了相关优化,上线后的收益主要体现这四个方向:
-
部分实时链路可以进行合并,降低了计算和存储资源成本;
-
基于watermark有效识别分区写入的完成度,接入湖仓的后续离线任务平均SLA提前时间不低于60分钟;
-
部分流转批后的任务上线后执行时间减少约40%(比如原先执行需要150秒的任务可以缩短到100秒左右完成 ;
-
离线增量更新场景,部分任务相较于原先Hive任务可以下降30%以上的计算资源。
同时跟进用户实际使用情况,发现了一些有待优化的问题:
-
Hudi生成文件的体积相较于原先Hive,体积偏大(平均有1.3 ~ 1.4的比例);
-
流读的指标不够准确;
-
Hive—>Hudi迁移需要有一定的学习成本;
针对上述问题,我们也做了如下后续计划:
-
对hoodie parquet索引文件进行精简优化,此外业务上对主键的重新设计也会直接影响到文件体积大小;
-
部分流读的指标不准,我们已经完成初步的指标修复,后续需要补充更多实时的任务指标来提高用户体验;
-
完善Hudi迁移流程,提供更快更简洁的迁移工具,此外也会向更多的业务推广Hudi组件,进一步挖掘Hudi组件的潜在使用价值。
END
猜你喜欢
本文分享自微信公众号 - vivo互联网技术(vivoVMIC)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
2023 开源&创业总结
2023即将结束,与往年一样,今年发生了很多事情,与往年不一样,今年发生了很多历史性的大事情,我们很荣幸地正在经历着经济发展的完整周期。回想起多年前,那时候国内经济上行,高速发展,社会上鲜有35岁危机之说。但当时我已不在国内多年,困顿于波澜不惊的职场,身不疲但心已惫,每天上班如坐针毡。无论办公室,看到什么,听到什么,都生理性厌恶。于是毅然裸辞,从那年算起到现在,折腾了好几个年头,大部分时间是在交学费。为失败的产品交学费,为失败的团队交学费,为傻缺的认知交学费,为懒惰与不自信交学费。好在赡养家庭的能力还在,生存压力不大,得以坚持。最近经常听黄明志与吴宗宪合唱地那首《慢慢做起来》,颇有感触。2023年,我们也在慢慢地做着RustDesk。往年那些错误判断,在今年全部被放下,时间教会很多东西。生逢AI元年,所有聚焦都在AI,身处喧嚣之外,我们正好可以“慢慢”地做对的事情。过去两年,我几乎每天都要看 RustDesk 的开源增长,并与同行作比较。相较2022下半年增长放缓,进入稳定的自然增长状态。有感于言多必失,人性矛盾无法调和,我们一贯奉行无为而治的开源治理,对于偶发的争议也采取不予置评的冷...
- 下一篇
人工智能中的文本分类:技术突破与实战指导
在本文中,我们全面探讨了文本分类技术的发展历程、基本原理、关键技术、深度学习的应用,以及从RNN到Transformer的技术演进。文章详细介绍了各种模型的原理和实战应用,旨在提供对文本分类技术深入理解的全面视角。 关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。 一、引言 文本分类作为人工智能领域的一个重要分支,其价值和影响力已经深入到我们日常生活的各个角落。在这个数据驱动的时代,文本分类不仅是机器学习和深度学习技术的集中展示,更是智能化应用的基础。 文本分类的重要性 文本分类的核心是将文本数据按照其含义或属性分配到预定义的类别中。这听起来简单,但在实际操作中却极具挑战性。为什么文本分类如此重要?其实,无论是个人用户还是大型企业,我们都在日常生活中与海量的文本数据打交道。例如,电子邮件自动分类系统可以帮助我们区分垃圾邮件和重要邮件,社交媒体平台利用文本分类来过滤不恰当的内容,而在商业智能中,文本分类帮助企业从客户反馈中...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS关闭SELinux安全模块
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2整合Thymeleaf,官方推荐html解决方案