本文整理自百度爱番番业务部 团队技术负责人李新建在QCon 2022 北京站的演讲分享,主题为“百度爱番番 RT-CDP 架构实践”。
随着公域流量红利褪去,企业更加注重私域精细化运营、营销。越来越多的企业需要基于 CDP 解决数据孤岛问题,帮助其更快的加温线索、促活客户。但对于中小企业来说,在搭建强大平台能力的同时,如何合理化资源,最大程度降低资源成本也是一个重要课题。本次分享既有先进架构的整体介绍,也有在资效方面上的设计考量,来最大化的帮助企业降本增效。
以下为演讲实录。
我叫李新建,目前在百度工作已有七八年。我此次分享的主题是关于百度爱番番的实时 CDP 实践。我之前写过一篇关于这个 CDP 架构的文章,包括一些选型和设计实践。此次分享是为了贴合资效平衡这个主题,因为我们在这个架构的过程中有几个核心指标和主题密切相关,所以我也参加了这次的会议。需要说明的是,这个 PPT 是半年前制作的,在制作过程中由于多次调整会议时间,PPT 没有同步迭代。另外,涉及业务变更的内容也没有更新到最新状态,但我认为其中的很多方法论、思想和目标在当前仍然适用,因此我想分享给大家,让大家了解当时我们是如何做的。
我之前写的一篇文章,已经发布并受到了不少关注。这次的 PPT 缺少一些前期背景和业务问题的详细说明,因此可能会更难理解。如果有问题,可以在最后一页的“彩蛋”中找我交流。
这次分享主要涵盖几个大块,其中最重要的是介绍资效平衡实践在架构中的应用。
业务背景
简单介绍一下我们的业务和整体的价值。我们主要是在营销领域开展业务,主要服务于广告主。随着互联网的发展,公域流量的增长已经趋于饱和,中小企业获取客户的成本越来越高,而且难以制定贴近客户的营销方案,以获取更高的客户转化率。因此,我们开始针对私域进行建设,以满足客户的需求。对于百度来说,公私域的业务都很重要。
当时,整个营销环境的主要问题是广告成本和缺乏创新的营销方案,而且客户的需求变化非常迅速。以前,只要提供了一个产品或服务,客户基本上能够很快地接受它,并且他们的需求变化不会太大,门槛要求也不是很高。但是现在,由于信息量越来越大,客户对自己的想法,包括对企业和客户的想法变化得非常快。客户对数据和信息变化的时效要求也越来越高。
基于多方面的需求,爱番番提供了完整的营销解决方案。这包括公共和私人领域的服务,其中包括百度的广告业务,后续的客户转化链路以及维护环节。通过与百度的整体业务对接,形成了一个强大的闭环系统。我现在分享的主要是关于私领域营销的内容。我们的实时 CDP 是与私域营销紧密合作的。这包括数据分析和整个数据链的串联,确保数据的及时性。
关于 CDP,我们需要考虑两个方面。第一个方面是要确定业务的本质,而第二个方面则是需要了解标准 CDP 所需要满足的要求和特征。在业务层面,我们可以通过一张简图来了解我们在私域场景下为客户和企业提供的标准能力是哪些。因为我们面向多租户,所以需要在数据模型上支持 ToB 和 ToC。比如,如果一个企业是 ToB 企业,我们需要管理企业和客户数据,它们是多层的关系。然而,在国内大多数 CDP 场景下,ToB 数据模型基本上没有得到很好的建设,而往往是以 ToC 为方向来打平数据。这也是我们面临的挑战之一。
另外,我们还需要考虑多渠道营销。如何赢得营销?首先,我们提供了灵活的数据配置化画布能力。比如,一个企业想要如何向客户进行营销,客户通过访问其官网、H5 或其他渠道的媒体信息,企业需要了解客户在不同媒体之间的整体访问轨迹,然后提供灵活的触达,包括活动信息和优惠券等。第三个是解决方案的链路需要多样化,因为无论是涨粉、推广还是直播,其业务需求的链路都不一样。具体的业务场景可能需要更加深入地讨论。
CDP 特征
下面介绍下 CDP,这是我想着重想分享几个关键点之一。首先,CDP 的标准定义是什么?CDP 在 2013 年就已经被提出来了,包括其官方定义和分类。但是在国内,很多公司仍然将其称为 MA、数据洞察,并推出了很多不同的产品。甚至包括我们自己的团队在做这个东西的时候,对于 CDP 的理解和标准也存在很大的差异。
如果你对 CDP 感兴趣,那么这一页是必须要了解的。基本上,所有现在提到的营销链路的东西都是 CDP 的范畴。然而,CDP 对应的能力集不同,因此需要考虑业务分析和技术指标,列出我们要做的 CDP 应该是什么样子的。有两个主要的细节:一是灵活支持 ToB 和 ToC 两类模型,即私有部署和适应多种业务场景;二是统一画像的存储;三是实时的多渠道打通,以保证跨渠道数据的实时同步读写。此外,考虑时效性,即跨渠道数据打通的实时性和海量数据下的实时性。为了满足这些要求,我们进行了很多调优,包括整条链的,服务链的,数据层面的和混部等。
整体架构
我们的架构指标归纳为四个:多租户,高性能,低成本和实时。这四个指标之间存在一些相互冲突,需要权衡,我们花了很大的力气去实现。
我们先了解整体的数据流向,从多元数据对接到采集、处理和输出。这个逻辑架构图中最重要的部分是红色的三个块,这些部分需要结合具体的详细设计和资效平衡来了解。关注这三个部分对应的位置、功能和需要解决的问题是很重要的。虽然其他块比如实时数据处理和统一存储也进行了成本优化和控制,但这三个块是更典型的。因此首先讨论这三个块。
在下面这个图中重点想介绍下公共组件与云原生的结合。我们部门是百度内部比较早将功能服务、微服务和数据服务全都拉到 K8S 生态下的部门之一。CDP 平台涉及了许多组件选型和与 K8S 结合的问题。我们在做这个图服务的时候也遇到了很大的问题。从 Dgraph 迁移到 Nebula Graph 的过程中也踩了很多的坑。
架构/资效均衡实践
Schema 自定义模型
今天的重点是讨论三个问题:Schema、实时的 IDM 和实时的规则引擎。这三个对应的问题比较典型,Schema 的关键词是降低成本和提高效率,IDM 是资源均衡和性能优化,规则引擎是极致性能和弹性伸缩。在 Schema 中,我们需要将中小企业的数据用很低成本地接进来,这对于不同的企业来说是非常重要的。虽然其他的数据平台都会考虑这个问题,但这个问题的复杂程度并不小。
首先,我们面临的是业务问题,即如何更快地将各种企业、各种维度的数据接入我们的 CDP 平台。为了解决这个问题,我们先进行了一层抽象,将数据转换为 CDP 平台中群组的标准数据。我们将这些数据抽象为三类业务实体,其中两大类是身份信息和行为轨迹,包括属性信息、时序信息和数据变化记录。然后,我们在这个业务抽象的基础上又做了一层内置的标准 Schema,这个 Schema 针对特定行业的结构化数据,内置了标准字段,比如企业信息、企业地址和企业名称等。
在营销场景下,比如微信场景和直播场景,我们对各个场景的标准字段进行抽象内置,并进行简化,以提高效率。稍微配置一下就可以在几分钟内完成数据导入,而以前可能需要一两天。
在我们做这个抽象之后,将其转换为一个简单的模型,这个模型可以处理多个实体之间的 1 对 n 的关系,以及一个实体本身的 1 对 n 的关系,可以复制继承并在多机上使用,最终将其转换为一个 结构化的 JSON,带有一些业务含义。当企业使用时,我们将其原始数据打入我们的库中。企业在扩展时,主要是通过子 Schema 进行扩展,最后统一存储。至于其他模块涉及到业务拆分,不再细说。
对于 Schema,我们面临两个问题。首先是多租户的支持,如何统一存储而不会导致建表量特别多?第二个问题是,如果表量不多,如何存储这些字段?对于第一个问题,我们需要保证建表量不会过多,以降低维护成本。对于第二个问题,如果采用大宽表的方式进行存储,虽然在数据分析时可能会有一个聚合的大宽表,但对于多租户的情况,数据会非常离散,这对于查询成本来说是不划算的。因此,在数据处理方面,我们通过对原始数据结构的映射,将无业务概念的数据字段抽象为数值型、字符型等几类,上层通过 Schema 进行查询和 SQL 转换。有了这一机制,我们只需在企业的字段数量超过内置字段限制时才需要干预,添加几个内置字段并自动进行映射转换。在我们底层统一存储使用的 Apache Kudu,字段数量官方建议有几百个限制。
万级 QPS 实时 IDM
我们也在性能和实时 QPS 调优方面做出了一定的努力。虽然我们在万级 QPS 的场景下进行了测试,但这需要在 3-6 个 pod 的情况下进行,且存储是读写分离的,包含 3 个存储节点和 3 个查询节点。考虑到数据处理过程是基于图结构且深度为 4,我们能够处理几万 QBS 的数据量级,这表明它具备了很强的性能。
从模型的角度来看,IDM 就是 ID 的关联,在我们的场景中代表着客户从官网访问后,在微信上登录小程序后需要进行关联。当访问官网时,如何营销和触达客户是一个重要的问题。官网的数据通常只有临时数据,如 Cookie ID,且它们是设备粒度的。微信授权可能使用的是百度的 OpenID,这些数据是片段化的。解决这个问题的关键是如何将客户数据打通,并在多个渠道上进行营销。这通常涉及到在不同媒体上发布的数据,并使用图的方式来处理这些数据。
大多数企业通常倾向于使用结构化的数据表进行离线计算,以获得历史关系数据。与这种方法的区别在于,我们的关系是实时打通的,这是因为如果不实时打通客户,即使在同一个媒介下,也可能无法确定应该归属于哪个人,在统一结构之后,他们会有一个 CDP 唯一标识。
在使用图数据库时,需要考虑使用实体属性值还是实体关系和实体结构来存储数据,因为不同的数据库的数据切分方式是不同的。在实现图数据库时,最初采用了点切分的方式,但由于数据模型下的节点类型有限,加上多租户的需求,导致数据倾斜问题严重。为解决这个问题,系统采用了边切分的方式,并使用了国内的 Nebula Graph 数据库进行存储。Nebula Graph 相对于国外的 Dgraph 更加成熟,且有较好的发展前景。
因为天然的图数据库拥有适合的架构,无论是在计算存储还是底层分布式存储方面都有优点,因此它天然具备伸缩能力。在分布式系统中,有一个常见的小点用于控制 Redis 的伸缩,这是一个参考。
在逻辑处理方面,我们对锁和连接池进行了优化,并对查询的 SQL 进行了调优。我们与图数库的人合作做了很多配合,效果明显,无论是在机型稳定性还是性能方面,对于资源消耗都有很大提升。
最后一个部分是 IDM 部署,提到部署是因为它与水平伸缩和部署方式相关,对成本和资源有天然的优势。我们对存储计算节点的部署,在混部方式、网络和负载方面以及磁盘上做了很多
优化,才达到了之前提到的效果。
实时规则引擎(RTRE)三次演进
在实时规则引擎方面,一个问题是数据量很大,存储的原生数据海量。另一个问题是对于多租户,实时流入的数据量也很大,在实时 IDM 的前提下,每条数据都需要实现实时读写,实时关系打通并进行处理。我们进行了两三次迭代,最终达到了预期,在性能和资源伸缩方面都有所提升。
我们的实时规则引擎主要应用于营销场景,并且需要配置对话流程。简而言之,当客户触发某些规则时,我们将采取相应的措施。这些规则相对复杂,例如,在企业的 7 天内,客户未打电话,且之前提供了手机号码但没有提供微信号码;在最近的 3 分钟内访问过企业的 H5 页面等。这些条件需要进行组合,包括两组和三组条件,AND OR 关系,因此相对复杂。其次,一旦流程配置完成,我们希望能够实时触发,即在一条数据到达后的毫秒级别内进行响应和触达。尽管规则实验是相同的,但在时效性和数据量方面却有所不同。
接下来介绍一个关键点,就是数据查询中是主动还是被动的。传统的数据平台会在设计一堆规则之后,通过查询语句来搜索海量数据。而我们的思路是数据主动查询,在数据流的关键阶段进行重要数据的补充,以确保在进行规则判断时有足够的数据,并进行结果处理。此外,目前还有一些流式数据库,也是非常重要的方向和思路。
在实现这个引擎时,我们持续迭代了实现机制。第一版实现比较粗糙,基于 Flink 进行实现,需要建立许多 Flink 的 job,并使用 Flink SQL 进行编写。但我们当时遇到的问题是窗口风暴,这意味着处理每分钟数据与近一分钟数据的实验处理方式不同。当滑动窗口很大时,例如几天或几个月,使用 Flink 消耗资源和实现程度都面临很大挑战和问题。Flink 提供了复杂事件组合处理的标准组件,但目前它主要适用于固定窗口和小滑动窗口场景,例如实时监控日志报警。
基于这些前提,我们重新自研了一套实时规则引擎,并进行了拆分和定制化策略以更好地与抽样 SQL 解析和规则引擎对接。我们还优化了片段规则的结果复用和资源控制。
在部署资源时,我们面临多租户的情况,每个 job 都占用很多 CPU 和内存资源。对于数据高峰,我们对处理节点进行了分类,有些偏管理,有些偏数据计算和存储,还有些是纯计算。这样,当高峰过去时,我们可以快速消除或解除纯计算节点。第二次演进,我们在百度云的基础上升级了计算平台搭建。我们支持的伸缩策略可以分为两类:一类是固定时间段的,缺乏动态性;另一类是基于指标的,这与在云原生场景下的情况非常相似。
第三次演进是迁移到云原生,因为在最初建设计算平台时,云原生链路尚未完全建立,现在有了之后,可以在多租户场景下进一步缩减资源,主要考虑客户成本和运维方面的因素,尤其是在线业务链路方面,长时间的响应时延是不可接受的。在云原生上,我们能够实现的主要是集群力度和服务力度的伸缩,以及通过虚拟化场景下的预 pod 管理来减少 pod 启动时延。如下图,通过 AP、CA、HPA 三个圈来代表这些方面。
在这三类前提下,我们将所有的 Flink 作业迁移到云上。在云上,我们遵循官方实践,将 Flink 作业运行在高可用模式下。现在,我们的几百个作业可以通过几个物理机承载,并且能够很好地进行伸缩。我们可以将这些资源与其他业务的 pod 进行整体的复用和资源均衡,使得计算集群所占用的资源非常少。
总结与展望
下图整理了平台能够实现的能力和之后想要实现的一些功能。我们的 CDP 平台是一个数据平台,主要关注流批一体的数据处理。然而,与智能湖仓相比,我们还有很大的差距,这是我们未来想要探索的方向。
以上是我们平台的一些内容,如果您有任何问题,随时可以联系我们进行交流。谢谢!
相关阅读:
评论