作者:vivo互联网服务器团队- Liu Xianchao
本文基于营销自动化数据驱动场景,分析介绍了Presto+大宽表方案、Bitmap方案、StarRocks方案的架构演进。
1分钟看图掌握核心观点👇
图 1 VS 图 2,您更倾向于哪张图来辅助理解全文呢?欢迎在评论区留言。
一、业务背景
从增量市场进入存量市场,粗放型的运营已经无法为企业带来更多的市场份额和营收增长。这一现状也驱动企业思考精细化运营,通过精细化运营挖掘出用户最大价值,从而提升用户LTV。精细化运营落地的重要举措就是数据驱动。通过门店数字化运营,可以实现打通品牌与导购与消费者的全程触点,沉淀、留存场景化交互数据,深度挖掘客户需求,为用户提供个性化服务。例如:线下的门店开业或者做一些促销活动,通过短信、富媒体短信、企业微信、导购朋友圈等触点将活动信息传递给门店周边有需要的用户,吸引用户到店。
二、基础架构
vivo通过智能手机以及智能手机售卖渠道的运营,积累了全渠道,全场景的门店相关数据。
- 标签数据:用户画像的关键点在于通过提取标签的方式将用户特征凸显出来,现有存量用户数据量级5亿+。
- **事件数据:**通常画像标签的产出需要数据团队清洗加工,算法介入,上架等一系列操作,生产成本较大,且灵活性和实时性都有不足。事件数据基于其强大的场景化表现能力,加工简单,上架速度快的特点,成为标签之外的另一个重要数据来源。
- 门店LBS数据:线下营销要点通常是吸引用户到店,体验门店产品,从而促成交易。而门店有其独特的组织架构,因此门店相关的LBS也是重要的数据源之一,数据团队基于存量用户数据预计算门店LBS关系数据膨胀至90亿+。
综合了标签、事件、门店LBS数据的受众筛选,成为精细化营销的一大难点。
首先MySQL的性能不足以支撑亿级数据多表且或非逻辑实时计算,通过调研以及公司海量计算组团队的方向,我们采用了OLAP(用于分析和查询大规模数据集的计算处理技术)引擎Presto,利用Presto的SQL on Everything特性,实现了多数据源综合的受众圈选。
图中为营销自动化平台数据驱动整体架构,分为业务层、计算层、数仓层。
- **数仓层:**主要为Hive数据仓库,数据由大数据团队整合标签、门店、事件,以及用户自定义上传的人群包数据。
- **计算层:**由OLAP引擎-Presto构成,执行SQL、获取Hive数仓数据进行实时计算。
- **业务层:**提供人群受众筛选、受众人群固化、渠道人群下发逻辑业务处理能力;对外主要提供受众筛选-标签+事件+人群的预估能力。
基于这套架构的痛点:
- 标签数据来源DMP系统,大数据团队需先上架DMP系统,再上架自有CMS系统中,时效T+2起步。
- 标签宽表随着标签字段增长,一个宽表300+字段,维护成本高。
- 标签+门店LBS大表,查询性能分钟级别响应,用户体验不佳。
三、架构迭代
为解决以上问题点,通过与大数据、DMP团队合作优化底层标签数据结构,采用Bitmap数据结构设计标签优化底层数据源。
3.1 Bitmap方案
3.1.1 设计与实现
数据结构设计如下:
基于用户维度预计算自增id,作为Bitmap下标,将标签列值转换为行值,每行都存储所有用户压缩成Bitmap的数据。
由于引入DMP标签服务,需对现有OLAP引擎进行改造。
**底层数据源:**由于Presto SQL On Everything的特性,支持各种存储在不同数据库中的数据,通过开发Presto Connector Plugin获取DMP平台标签服务,大部分数据还是在Hive数仓表中。如:事件数据/门店数据等。
**Presto计算层:**在Presto服务,主要开发了Presto Bitmap相关的UDF Plugin,Presto Connector获取DMP平台标签,通过Presto源码改造实现 Select In Bitmap能力。 进行上述改造后,计算层就可以通过统一的SQL实现各种服务。
使用示例:
select count(user_id) from user_id_mapping where day='${day}'and user_rn in(select bitmap from dmp.virtual_table where rule='#标签规则')
通过虚拟化DMP表,在Presto中解析后查询DMP标签Bitmap用户数据返回下标数组与id_mapping表进行计算。
3.1.2 实现效果
营销自动化核心流程中移除了对大宽表依赖,新标签上架可由原来1.5人天提升到0.5人天。
查询耗时由当前的分钟级别优化到秒级别(P90=38s),其中纯标签场景可以低至毫秒级别。
3.1.3 Presto + Bitmap的局限
此次迭代解决了查询性能和标签上架效率问题,但随着业务复杂度增加,现有架构面临新的技术挑战:
- 复杂查询性能瓶颈: 面对多表关联(Join)和复杂聚合的查询场景,特别是在门店LBS数据表的基础上进行多表Join时,性能与内存管理面临压力。
- 技术阻塞业务安全: Presto无法写入加密Hive表,直接阻碍了数据安全合规的落地,成为一项待解决的技术债务。
3.2 引入StarRocks方案
为解决上述局限,并为下一代实时数据分析业务场景做好准备,我们评估并引入StarRocks,其存算一体架构、向量化执行引擎,有望在实时分析场景带来突破性提升。
3.2.1 与Presto现有架构对比
为体现切换StarRocks的升级价值,从高性能、高可用、高安全维度进行对比。
3.2.2 现状场景分析
通过3.2.1的调研对比,明显确定了StarRocks的优势,因此对现有业务系统场景分析,提前将StarRocks需要兼容的点改造完成。
3.2.3 落地规划
将切换StarRocks需要改造的点都准备完成后,我们将遵循“由简到繁、由读到写、分阶段推进”的原则,分为四个阶段改造业务系统,控制切换风险及平滑过渡:
经过以上迭代后架构如下:
计算和数仓层变为存算层:计算和数仓一体化,整体由StarRocks控制。
3.2.4 实现效果
- 资源降本:原有Presto集群53台,当前StarRocks搭建的集群为3台,费用成本降低约93%。
- 性能提升:查询P95耗时从65s降低至6s。
- **数据安全:**底层无HDFS文件,当前可使用StarRocks函数对数据进行加解密,后期由海量计算组同事开发自动加解密功能。
3.2.5 切换后的问题
问题一:
营销短信任务下发场景中,仅部分数据下发(如总量下发一千万条,实际仅允许下发一百万条)
分析验证:
- 通过日志分析发现,当查询任务涉及上千万数据时,实际仅返回一百万条结果,超出数据丢失。相关查询SQL示例如下:select channel_id from table where crowd_id=100。由于该SQL在迁移至StarRocks过程中未做语法改造,初步判断为StarRocks限制所致。
- 查阅StarRocks官方文档,确认存在系统变量 sql_select_limit,用于限制查询结果的数据量。相关说明详见:StarRocks系统变量文档。
- 为验证该判断,在测试集群中分别将该参数设置为100万、200万,并本地环境进行验证,结果符合预期:查询结果数量受限于所设参数值。
解决方案:协调集群运维同事,调整线上StarRocks集群的系统变量 sql_select_limit,解除100万条结果集限制,并在重启集群后问题得以解决。
问题二:
服务频繁Full GC,且GC耗时1s以上,导致服务请求超时
分析验证:
- 超时请求在服务端的接收时间至处理返回时间均在1s内,但客服端记录的请求时间早于服务接收时间,且差值超过1s,经与运维沟通确认,排除网络问题。
- 在统一可观测平台中查看该服务应用监控,发现超时时间点存在Full GC现象,且GC耗时超过1s,随后配置JVM参数生成GC日志便于进一步分析。
- 使用Memory Analyzer Tool分析生成的堆转储文件,发现主要是大对象为RowDataStatic,该对象在获取数据库数据时是将所有结果集加载至内存中。由于此前已解除100万数据查询限制,当数据量达到老年代空间临界值时,触发Full GC。
- 定为到查询明细数据的代码逻辑存在问题。Presto是流式查询,而StarRocks基于MySQL协议连接,需配置相应参数才能启用流式查询机制。
- 在本地环境中,通过调整PreparedStatement的fetchSize参数进行对比测试,复现了线上服务GC暂停现象:当未启用流式查询时,GC暂停时间长达10s。
解决方案:通过改造代码中MySQL JDBC的配置参数,启用流式查询功能。
四、结语
本文主要介绍了营销自动化数据驱动-OLAP架构演进史,最初为解决业务诉求,支撑业务快速上线,基础架构采用Presto+大宽表方案。
随着数据量及标签维度的激增,为提升标签上架效率,引入Bitmap方案实现预聚合计算,通过标签上架统一至DMP,显著降低响应延迟;在满足业务诉求的同时,针对数据安全方向进行深入探索OLAP引擎能力,从Presto切换为StarRocks引擎,不仅在数据安全方面有保障,同时也提升了查询性能以及完成机器资源的降本。