背景
美团点评酒旅运营需求在离线场景下,已经得到了较为系统化的支持,通过对离线数据收集、挖掘,可对目标用户进行T+1触达,通过向目标用户发送Push等多种方式,在一定程度上提高转化率。但T+1本身的延迟性会导致用户在产生特定行为时不能被实时触达,无法充分发挥数据的价值,取得更优的运营效果。
在此背景下,运营业务需要着手挖掘用户行为实时数据,如实时浏览、下单、退款、搜索等,对满足运营需求用户进行实时触达,最大化运营活动效果。在运营实时触达需求中,存在如下具有代表性的业务场景:
- 用户在30分钟内发生A行为次数大于等于3次
- 用户为美团酒店老客,即用户曾购买过美团酒店产品
- 用户在A行为前24小时内未发生B行为
- 用户在A行为后30分钟内未发生B行为(排除30分钟内用户自发产生B行为的影响,降低对结果造成的偏差)
本文以该典型实时运营场景为例,围绕如何设计出可支撑业务需求高效、稳定运行的系统进行展开。
早期方案
运营实时触达需求早期活动数量较少,我们通过为每个需求开发一套Storm拓扑相关代码、将运营活动规则硬编码这一“短平快”的方式,对运营实时触达需求进行快速支持,如图1所示:
问题
早期方案是一种Case By Case的解决方式,不能形成一个完整的系统。随着实时运营业务开展,相关运营活动数量激增,线上维护着多套相似代码,一方面破坏了DRY(Don't Repeat Yourself)原则,另一方面线上维护成本也呈线性增长,系统逐渐无法支撑当前的需求。
为解决早期方案中出现的问题,对系统建设提出了以下挑战:
- 硬编码活动规则的方式产生了大量重复代码,开发成本较高,需求响应时间较长。
- 业务规则修改困难,调整运营活动条件需要修改代码并重启线上拓扑。
- 线上服务较多,资源利用率、系统吞吐量低,统一维护成本较高。
- 缺乏完善的监控报警机制,很难早于业务发现系统及数据中存在的稳定性问题。
针对以上挑战,结合业务规则特点,美团点评数据智能团队调研并设计了酒旅运营实时触达系统。
技术调研
实时计算
前面已经提到,美团点评酒旅运营需求在离线场景下,已经得到了较为系统化的支持,通过对离线数据收集、挖掘,可对目标用户进行T+1触达,通过向目标用户发送Push等多种方式,在一定程度上提高转化率。但T+1本身的延迟性会导致用户在产生特定行为时不能被实时触达,无法充分发挥数据的价值,取得更优的运营效果。运营业务需要着手挖掘用户行为实时数据,如实时浏览、下单、退款、搜索等,对满足运营需求用户进行实时触达,最大化运营活动效果。对比若干开源实时计算系统,我们最终选择了Flink作为我们的实时计算系统,主要原因在于几点:
流式处理语义完备
Flink作为第三代大数据计算引擎(第一代为Hadoop及周边计算引擎,第二代为Spark,第三代为Flink),其流式方面相比于Spark有绝对优势,包括完整窗口语义、乱序数据处理、复杂事件处理等等。
提供多层次抽象接口
Flink提供针对流式处理完备的SQL/Table/DataStream,之前在Storm和Spark任务上大量的底层代码开发全部可以使用SQL来解决,进一步提升了流式任务开发效能。
性能突出
比较项 | Apache Storm | Apache Spark | Apache Flink |
---|---|---|---|
语义保证 | At least once | Exactly once | Exactly once |
延迟 | 低 | 高 | 低 |
吞吐 | 低 | 高 | 高 |
计算模型 | 流 | 微批 | 流 |
容错开销 | 高 | 低 | 低 |
流控 | 较差 | 较差 | 好 |
业务灵活性(业务和容错分离) | 部分 | 紧耦合 | 分离 |
规则引擎
提高灵活度需要从业务规则和系统代码解耦和入手,规则和代码耦合直接导致了重复代码增多、业务规则修改困难等问题。那如何将业务规则和系统代码解耦和呢?我们想到使用规则引擎解决这一问题。
规则引擎是处理复杂规则集合的引擎。通过输入一些基础事件,以推演或者归纳等方式,得到最终的执行结果。规则引擎的核心作用在于将复杂、易变的规则从系统中抽离出来,由灵活可变的规则来描述业务需求。由于很多业务场景,包括酒旅运营实时触达场景,规则处理的输入或触发条件是事件,且事件间有依赖或时序的关系,所以规则引擎经常和CEP(复合事件处理)结合起来使用。
CEP通过对多个简单事件进行组合分析、处理,利用事件的相互关系,找出有意义的事件,从而得出结论。文章最前面背景中提到的业务场景,通过多次规则处理,将单一事件组合成具有业务含义的复合事件,进而提高该类仅浏览未下单的用户的下单概率。可以看出,规则引擎及CEP可以满足业务场景的具体需求,将其引入可以提高系统面对需求变化的灵活度。
我们对业界已有的规则引擎,主要包括Esper和Drools,进行了调研。
Esper
Esper设计目标为CEP的轻量级解决方案,可以方便的嵌入服务中,提供CEP功能。
优势
- 轻量级可嵌入开发,常用的CEP功能简单好用。
- EPL语法与SQL类似,学习成本较低。
劣势
- 单机全内存方案,需要整合其他分布式和存储。
- 以内存实现时间窗功能,无法支持较长跨度的时间窗。
- 无法有效支持定时触达(如用户在浏览发生后30分钟触达支付条件判断)。
Drools
Drools开始于规则引擎,后引入Drools Fusion模块提供CEP的功能。
优势
- 功能较为完善,具有如系统监控、操作平台等功能。
劣势
- 学习曲线陡峭,其引入的DRL语言较复杂,独立的系统很难进行二次开发。
- 以内存实现时间窗功能,无法支持较长跨度的时间窗。
- 无法有效支持定时触达(如用户在浏览发生后30分钟触达支付条件判断)。
以上两个问题在Flink的CEP已经能够解决,因此我们考虑使用FlinkCEP作为规则引擎实现的基础。由于我们最终是基于阿里云平台构建我们实时推送平台,最终选择使用阿里云实时计算Flink作为我们的基础计算引擎,相比于社区而言,云上FlinkCEP已经具备SQL表达能力,因此我们可以更加简单使用上FlinkCEP功能。
技术方案
确定引入规则引擎后,围绕规则引擎的设计开发成为了系统建设的主要着力点。通过使用实时数据仓库中的用户实时行为数据,按业务运营活动规则,组合成有意义的复合事件,交由下游运营业务系统对事件的主体,也就是用户进行触达。将系统抽象为以下功能模块:
规则编排和翻译
规则配置基本实现由业务分析师、产品经理或运营人员自助完成。
规则配置系统是基于FlinkSQL之上提供了一层规则的封装,方便大量对于底层大规模分布式流式处理原理不明白的业务人员使用我们的规则系统。该规则系统将常见的规则计算逻辑封装为一个个独立的组件,使得上层业务人员可以仅了解业务流程即可实现规则编排。
考虑到仍然有部分非常复杂的业务规则,使用界面方式不易表达,我们仍然保留了FlinkSQL作为业务人员编写规则入口,确实有部分高级业务人员和技术团队愿意使用SQL作为规则编写方式。
实时数据采集
目前规则引擎主要监控的是实时用户行为数据,主要来自于用户使用APP操作产生的服务器日志,以及相关交易行为产生的数据库日志(Mysql binlog)信息,两部分数据我们都使用工具采集进入Kafka作为消息队列。如下图:
实时计算引擎
这部分是运行的核心逻辑,规则系统编排的所有规则(排除直接使用FlinkSQL的规则)将翻译为底层FlinkSQL并提交到底层实时计算系统。
在线系统对接
对于实时计算完成的结果,系统将数据写出到三个结果端:
HBase: 计算完成的结果推给在线系统存储HBase,用户使用APP在请求在线服务时候,运营系统将会结合到这份实时规则引擎的结果数据,给用户推送相应的促销、打折等运营信息。
Kafka: 部分实时计算的结果写入Kafka,为后续其他实时计算系统、在线系统消费这份实时数据使用。
部分业务DEMO
用户在30分钟内发生A行为次数大于等于3次
INSERT INTO payment_frequency
SELECT
uid as action_uid,
HOPPING_START()
count(*) as action_count
FROM
app_click
用户为美团酒店老客,即用户曾购买过美团酒店产品
用户在A行为前1小时内未发生B行为
用户在A行为后30分钟内未发生B行为
总结与展望
酒旅运营实时触达系统已上线稳定运行一年多时间,是运营业务中十分重要的环节,起到承上启下的作用,在系统处理能力及对业务贡献方面取得了较好的效果。未来,该系统将结合到Flink在Batch、ML方面的,会考虑在几个点深入:
- 提供更加多样化的规则设置,方便业务人员完成复杂规则界面化配置。
- 当前规则引擎是一套专家规则系统,未来结合到机器学习,将会更多在算法沉淀更多运营规则。