简介:数据银行是阿里巴巴集团官方打造的品牌商消费者运营商业数据产品,为品牌商客户提供丰富的消费者分析能力。由于数据银行的消费者数据产品的定位需要在一份海量消费者数据之上实现不同延时要求和计算要求的分析场景,我们基于阿里云AnalyticDB MySQL最新发布的实时湖仓能力,将数据仓库和数据湖割裂的体系进行融合,高性价比的支撑了上万品牌商的分析场景,在10PB+和十万亿级数据规模下,将天级别的数据延迟改善成实时无缝的处理和查询,满足实时数据处理和秒级复杂分析需求(30+张表Join),同时整体成本下降20%+,平稳扛住了2022年双11大促的业务峰值压力。
数据银行介绍
数据银行是阿里官方打造的品牌商消费者运营商业数据产品。数据银行通过id-mapping等技术,从不同业务端对消费者数据进行处理和管理,提供包括人群圈选、实时算人数、链路流转分析、画像透视、算法放大优选、人群洞察报告等在内的丰富分析能力。面对复杂的分析场景,用低成本资源实现高性能、稳定性的计算,一直是数据银行的重要技术挑战和业务诉求。
人群圈选/计算人数
人群圈选是消费者运营产品的核心能力。基于全链路状态、以场圈人、属性圈人等各类集合条件,以OLAP查询亚秒级的响应速度,圈选生成人群,并随时随地可以查看人数。
人群优选放大
人群优选放大是人群圈选的有效补充,通过算法预测的类型对人群进行优选(缩小)或者放大,帮助提升人群运营效率。因为涉及算法预测,需要使用具有算法能力的计算引擎来获取人群等数据,进行计算。
人群画像
人群画像是消费者运营产品的核心能力,数据银行除了可以针对用户沉淀的具体人群进行画像操作,还可以对链路流转的人群进行画像以帮助品牌分析消费者关系变化的原因(如下图,某品牌去年双11是购买状态但今年双11是流失状态的人群画像,非真实数据)。
人群分析报告
人群分析报告。数据银行每天会生成数万~数十万人群,对圈选人群,会从多个维度进行指标计算、趋势分析,提供全面的人群洞察。这是一个批处理场景,适合使用离线计算引擎分析。
业务挑战
过去,数据银行一直在使用“三驾马车”支撑不同场景的分析计算(见下图)。在离线分析层面,使用MaxCompute作为人群优选放大、人群分析报告等场景的计算引擎;在OLAP分析层面,使用AnalyticDB MySQL作为主计算引擎,提供标准的OLAP分析能力;使用AnalyticDB PostgreSQL作为副计算引擎,提供基于bitmap的加速计算能力,满足实时算人数等高性能需求场景。
三个引擎独立消耗存储、计算资源,带来了以下几大挑战:
1. 同时使用三份系统资源,两个OLAP引擎,涉及10PB+级别数据量的计算和存储消耗,业务成本压力大;
2. 三个引擎间需要通过数据同步来大量共享数据,数据分析的时效性存在巨大的挑战;以人群透视为例,用户在离线放大生成人群后,只能第二天批量同步到AnalyticDB MySQL,或者立即实时同步到AnalyticDB MySQL,才能进行透视,但前者会让人群生成后第二天才能透视;后者对AnalyticDB MySQL存储节点压力较大,大促期间往往会关闭实时同步以保障稳定性;
3. 保存三份数据副本,对应三次数据建模,三条数据生产&导出链路,需要投入大量运维工作来保证数据一致性。
调研发现,湖仓一体技术能很好地解决我们遇到的问题。湖仓一体(Lakehouse)旨在用一个完整的架构,同时结合数据湖和数据仓库的优点,即在廉价的云存储构建的数据湖存储之上,构建类似于数据仓库的数据模型和数据管理体系,一份存储,支持多种计算负载。
我们在过去一年的时间里,利用AnalyticDB MySQL的强大计算引擎和数据湖存储,将湖仓一体技术的实践落地,并在双11期间得到验证,取得了很好的业务效果。
为什么选择AnalyticDB MySQL做湖仓一体
AnalyticDB MySQL针对企业有强烈降本增效诉求的背景,并且考虑到目前数据仓库和数据湖割裂的体系导致体验、系统复杂度、数据一致性和成本等各方面的挑战,在AnalyticDB MySQL作为数据仓库的基础上推出了AnalyticDB MySQL湖仓版,帮助客户可以同时使用数据仓库和数据湖中的数据自由平衡性价比,并且保持全过程同一体验和数据一致性。AnalyticDB湖仓版的特点之一就是可以只存储一份数据同时服务多个不同的业务场景,跟数据银行的场景非常的契合。下图是AnalyticDB MySQL湖仓版的技术架构图:
从底向上看AnalyticDB MySQL湖仓版支持从RDS/SLS等等不同的数据源进行数据的采集,让数据可以方便的到湖仓存储里面;其中在湖里用户有两种存储可以选择:一种是内置的自研存储,其特点是高性能,支持数据的高QPS实时读写,另外一种开源的数据格式Hudi,如果对于查询性能要求相对有那么高,可以考虑Hudi,再往上是计算引擎层,目前支持自研引擎XIHE的MPP引擎(性能好)、XIHE的BSP引擎(支持的数据量大)、以及开源的Spark引擎;再上面就是可扩展的应用访问层了。
我们数据银行的数据湖还有一些特征:数据量非常的大(数十万亿行原始数据,10PB级别),分区特别的多(单表最多可达几十万-百万级别分区数,上百张表),计算非常的复杂(单SQL允许30+张表join计算),如果没有针对性的优化,查询的性能将会是几十秒甚至分钟级,满足不了用户对人群进行实时圈选,实时分析的诉求,因此我们跟AnalyticDB MySQL团队一起针对性的进行优化,通过对湖存储支持多版本使得我们一份数据可以供多个引擎同时读写;通过支持分区映射让我们可以在湖存储上实现远高于普通外表的性能;通过对RoarningBitmap的支持让我们大幅提高人群圈选的计算性能。
湖仓数据实时一致性:基于Hudi的多版本和实时写能力
传统数仓的解决方案大致是离线引擎(比如Spark/odps) + 在线OLAP引擎的方案,该方案存在两个痛点:
- 一致性:因为是两套引擎,在线离线一致性无法保证,也就是对于某个特定的分区,如果离线引擎在更新,在线引擎如果读到了同一个分区数据那么数据可能是不准确的。
- 实时性:传统解决方案中,离线引擎负责写入数据,在线OLAP负责查询。然而,离线ETL引擎spark/odps在写入的时候,任务调度往往是分钟级别的,因此业界大部分的圈人系统对最终用户很不友好,往往圈人完毕需要等几分钟甚至几十分钟才能够使用结果数据。
针对以上两个痛点,在湖仓版中,AnalyticDB MySQL集成了Hudi的多版本能力和实时写的能力,以支持用户在线秒级圈人场景的业务诉求。业务端可以同时在多套引擎中写同一份数据,且AnalyticDB MySQL的写入是实时的,圈人SQL端到端耗时是秒级(简单标签圈人<500ms, 复杂行为圈人<10s)的。
湖仓人群计算加速:支持RoaringBitmap
RoaringBitmap是一种高效的进行bitmap交并差计算的数据结构,在没有支持RoaringBitmap的情况下,我们在对不同人群之间求交集、并集的时候只能把两个不同的人群的数据都查询出来,然后依赖COUNT DISTINCT/JOIN/UNION等算子进行计算,这样计算的数据量大,性能差,而与基于原始id计算相比,Roaringbitmap计算使用Roaringbitmap数据结构更小,是id列表存储大小的1/5左右,能极大降低计算过程IO的数据量。同时bitmap交并差聚合运算,相比于COUNT DISTINCT/JOIN/UNION计算,性能上也是有明显的优势的。综合考虑,我们将Roaringbitmap计算作为数据银行OLAP场景的主要计算模式
ADB的MPP计算引擎及Roaringbitmap算子,实现了完整的分布式Roaringbitmap计算过程。相比原始id计算,资源消耗降低70%以上,计算性能提升2倍以上。
湖仓数据分析加速:Bucket Table
AnalyticDB MySQL的计算引擎是MPP架构的,数据会根据一定的Hash规则被分布到不同的计算节点进行计算从而利用上整个集群的算力。默认情况下,由于计算引擎感知不到用户外表的数据分布,数据读取之后会进行一次shuffle来把数据重分布到对应的计算节点,shuffle的代价包括 R(数据的行数)次hash计算 + M(上游节点数) * N(下游节点数)次网络开销,在数据量比较大,集群规模比较大的场景下,shuffle的代价很大,导致数据分析性能不理想。对此AnalyticDB MySQL对湖存储表支持了Bucket的特性,用户可以自定义bucket数和hash function,AnalyticDB MySQL计算引擎会将bucket相同的数据文件直接调度到相同的计算节点进行计算,从而避免额外的数据shuffle开销,提升计算性能。下图以Join的场景举例:
由于有了bucket的能力,整个join是每个bucket里面的数据各自join,最后再汇总即可,而不用把join两边的所有数据进行shuffle,会大大提升性能。
湖仓支持大规模历史数据:分区映射
我们数据银行的特点是数据量特别的大,表的分区数特别的多,会达到千万级的水平,这个分区的数据本身也变成了“大数据”,传统的方案是把这些分区保存在元数据系统里面,然后计算引擎在计算的的时候把一个表的所有分区从元数据系统里面拖出来再根据用户的查询对分区进行过滤,但是在我们的数据量下这个元数据系统本身会成为瓶颈,使得查询的性能会很差。
我们观察到虽然每个表总的分区量很大,但是每次计算真正会参与计算的分区数并没有那么多,因此我们跟AnalyticDB MySQL团队一起设计实现了分区映射的能力。分区映射简单来说就是用户在创建表的时候指定表的路径与分区之间的关系,这样用户实际查询的时候我们自动根据这个“关系”推算出参与这个计算的分区,比如用户建表的时候这样指定:
create external table person ( id int, name string, age int ) partitioned by ( dt string ) LOCATION 'oss://bucket001/person/' tblproperties( 'projection.dt.type' = 'date', 'projection.dt.range' = '2021-02-01, NOW', 'projection.dt.format' = 'yyyy-MM-dd', 'projection.dt.interval.unit' = 'days', 'storage.location.template' = 'oss://bucket001/person/${dt}/' );
我们知道这个表有一个名字叫dt的分区,它的类型是date, 它的取值范围是2021-02-01到现在,它的格式是yyyy-MM-dd, 每个分区数据存放路径是 oss://bucket001/person/${dt}/, 那么现在用户来查询:
select * from person where dt = '2022-01-01'
我们可以直接计算出要扫描数据的路径就是: oss://bucket001/person/2022-01-01/这个计算相比从元数据系统里面拉取千万级别的元数据来说不管是从性能还是稳定性来说都要好很多。
业务价值
总体来说,AnalyticDB MySQL对数据银行湖仓一体架构的业务价值主要体现在如下几个方面:
1. 数据实时性大大提升:计算产生的数据,无需任何数据同步/导出过程,立即可以跨引擎读取分析,数据产出时效性从过往的小时级甚至天级别,直接提升到无缝使用;
2. 成本大幅下降:通过强大的外表计算和数据检索能力,支持数据银行使用一份数据同时支撑了OLAP和离线计算,在保证性能的同时,使用成本大幅下降20%以上;3. 应对大促的弹性能力:利用AnalyticDB MySQL的云原生弹性能力,可以在大促/日常期间实现快速资源伸缩,以应对计算负载的变化;
4. 高性能的OLAP引擎:在数据银行数十万亿条数据的背景下,通过高性能OLAP计算能力及RoaringBitmap能力的支持,实现了平均1-3秒的读写查询响应,为用户提供了灵活高效的分析工具;
5. 稳定性提升:通过对共享数据湖存储的支持,大大减少了数据生产和同步链路,降低了系统复杂度,化解了维护数据一致性的负担,极大减轻了数据运维压力。
*以上性能/成本数据均由数据银行业务大促前及大促期间监控及测试得出
/ End /