同程旅行吴祥平:同程湖仓一体应用与实践

时间:2022-12-02 01:09:39

  本文根据吴祥平老师在【第十五届中国系统架构师大会(SACC2022)】线上演讲内容整理而成。

   本文摘要:

  为了解决数仓存在的一些问题比如:数仓的实时性,资源消耗,更新需求日益变多,我们跟进业界步伐实践了从数仓到湖仓的转变。目前我们将大多数hive表改造湖仓表,替换内部数仓base层hive表为hudi表,时效性由T+1降低为分钟级延迟,同时基于hudi实现了流式宽表,实时join等场景的落地,为业务降低了大量计算资源的使用。

  本次分享,湖仓架构的演进实践。分享内容包括:数仓架构和规模,碰到过什么问题、数据湖与数仓的区别,为什么选择hudi、湖仓架构在同程旅行的实践过程,架构演进思路是什么、湖仓实践过程中的问题等。同时,对湖仓技术方案未来发展、实践经验与思考等内容。

   同程旅行数仓现状

  在引入湖仓之前,我们采用Lambda架构数仓,一条实时链路和一条离线链路,实时链路基于Kafka和Kudu实现,离线链路基于Hive和olap引擎如GP/CK/StarRocks等加速数据应用。

  我们目前有80%的离线场景,每天8万+离线任务,40万+hive表;20%实时场景,4000+实时任务。要知道Lambda架构在大数据时代主导了很长时间,但随着数据应用场景的不断丰富,实时性需求越来越多,Lambda架构的缺点就被逐渐放大。  

同程旅行吴祥平:同程湖仓一体应用与实践

  基于Lambda架构数仓痛点主要体现在四个方面:

  1,数据计算冗余:Binglog实时入仓,离线任务每天定时合并,且业务计算需要等待。

  2,开发和维护困难:两条链路,逻辑一致性保障,技术要求不一样,结果往往不一样。

  3,数据存储冗余:合并产生大量临时表,中间结果表等数据急速膨胀造成存储压力,实时离线可能多份。

  4,计算压力变大:夜间计算窗口可能完不成白天累积的数据。

   数据湖与数仓区别

  正因为Lambda架构问题居多,我们开始调研数据湖相关技术,数据湖与数仓的区别有很多,我主要从两个维度来分享。

  区别一:计算模型。数据湖能够支持增量更新的方式增量流读,但数仓是基于全量或分区覆盖的方式,不支持局部更新。

  区别二:数据管理。数据湖基于统计信息,索引管理文件,能够更细粒度的管理数据文件,加速数据入湖或数据在湖上查询,而数仓更多是基于分区管理。

  不仅如此,数据湖还具备如快照、时间旅行、结构演进等数仓不具备的特性。

   数据湖基本概念和原理

  选择hudi的原因是因为其包含了数据湖的多个基本特性,如ACID事物支持、Merge-On-Read、Bulk Load、Incremental Query、Time travel等等;其次,hudi在设计开始就拥有任务自管理功能,包括快照commit、过期快照清理、小文件合并、mor表的定期压缩、rollback、回滚等;最后是因为比较键、Payload抽象,比较键既能应对CDC场景又包括普通消息,payload能够在合并阶段完成包括更新,局部更新等特殊场景。  

同程旅行吴祥平:同程湖仓一体应用与实践

  在hudi整体应用架构方面,hudi是介于HDFS或对象存储和查询引擎之间的抽象,自身提供了数据湖的基本功能之外,还包括自带的数据摄入模块,同时在应用架构中还划出了增量流读的过程,为后续构建流式数仓提供了可能性。

  hudi如何进行数据更新?模式一:Copy-On-Write,写时合并,写放大,读优化;模式二:Merge-On-Read,读时合并/定期合并,读放大,写优化;

  hudi的最大特点是具有索引技术,数据湖索引包括如Bloom/bucket/hbase等,我们可以通过主键索引实现高效局部更新,还可基于索引优化查询。

  时间抽也是hudi不得不提的一个概念,一个时间轴由三部分组成:Action:COMMITS,CLEANS;State:REQUESTED,INFLIGHT和time。时间轴是hudi实现快照流读,回滚不可或缺的一个设计。

   湖仓一体实践

  在湖仓一体整体架构上,我们采用了批流一体的统一实时离线链路,并自研了数据集成方案。  

同程旅行吴祥平:同程湖仓一体应用与实践

  目前,我们的湖仓一体现状是:700+核心ODS表入湖;基于ODS清洗任务启动时间提前至:0:05;核心ODS层数据新鲜度由T+1提升至分钟级;完成多个业务线流式数仓场景落地。

  在流式数仓场景上,我们从底层数据、数仓模型到报表全面切到湖仓一体中,支撑用车业务能更及时监控坏账、经营数据。同时,我们还运用局部更新Payload实现了实时关联维度数据打宽。

  在增量统计场景上,我们结合Flink Cumulate窗口实现数据增量统计入hudi。

  在数据湖应用过程中碰到了一些挑战:如何让业务更快的入湖?元数据多引擎多次声明如何解决?入湖的数据脱敏和数据质量怎么做?数据丢失?

  数据集成选型我们有两种方案,即Flink CDC和自研基于MQ。虽然Flink CDC已经很完善了,但是我们内部还是出于数据安全和MQ复用这两点的考虑选择自研。  

同程旅行吴祥平:同程湖仓一体应用与实践

  数据集成架构V1的优点和问题:优点是适合中等数据量场景,可实现在线补数(全量、增量)。问题是全量数据参与了入湖Upsert计算,数据量较大时全量集群IO压力大,并行任务数受限。  

同程旅行吴祥平:同程湖仓一体应用与实践

  数据集成架构V2做出了优化,其更适合超大数据量场景,同时并行多任务。通过优化,我们屏蔽了相关资源申请、Flink同步任务、Hudi参数等细节,实现一键同步功能。  

同程旅行吴祥平:同程湖仓一体应用与实践

  下一个挑战是元数据的问题:Flink任务声明Hudi表,开启同步到Hive,Flink流读/批任务需再次重新声明Hudi表;Mq表的声明同样,多次消费多次定义;数据血缘采集困难。  

同程旅行吴祥平:同程湖仓一体应用与实践

  我们如何解决上述问题呢?以元数据声明为例,我们针对痛点提供了一套统一元数据方案,具体实现方式是:改造Hive-Connector,使用原生Meta列属性;Flink使用通过like方式修改属性;扩展hive引擎支持通过Hive Sql查询消息队列。

  统一元数据之后,实现Flink/Hive/Spark/Presto多引擎共用,一次声明多次使用。  

同程旅行吴祥平:同程湖仓一体应用与实践

  在数据脱敏方面,如何取样落在MQ中的数据源?我们自研了Flink sql数据预览,基于On yarn Session集群实现,支持多Flink版本,可复用FlinkTaskManager(1小时过期),最快5s内返回结果。在预览脱敏方面,我们即席预览数据,通过自定义加密函数进行数据脱敏。

  下一个挑战是数据质量的问题:每日凌晨MQ数据抽样数据时间;批处理前置增加数据质量监控依赖。

  在数据丢失方面,主要有两个代表性的情况,HUDI-4311和HUDI-3912。同时,我们对hudi应用过程中还有很多其他的修复。

  给大家分享一些部分hudi使用建议,在提升入湖速度方面,可以增加任务Checkpoint时间间隔,增加相邻两次Checkpoint间隔,减少管理内存大小(Bucket Index),增加Hudi合并内存大小。

  在提升入湖稳定性方面,增加Flink任务堆外内存的配比(合并阶段,Flink默认为0),设置合理的保留策略避免.hoodie路径下文件过多,关注存储RPC压力情况。

   未来规划

  针对未来,我们还将不断完善在数据湖上的应用,具体方向包括:提升湖仓易用性,扩大湖仓应用范围和完善湖上分析能力。

  嘉宾介绍

  吴祥平,同程旅行数据中心计算集群研发组技术负责人。2012年毕业于浙江海洋大学,热爱Coding、热爱开源,是flink、hudi开源社区贡献者。