微盟实时链路构建用户数据平台

167 阅读13分钟

文章摘要:本文主要分享了 WOS 下 CDP 实时用户数据平台的设计探索,从宏观的角度阐述 CDP 建设过程中遇到的问题和探索的方案。

本文首发自 微盟技术中心 微信公众平台~

一、前言

微盟CDP(Customer Data Platform) 是以消费者为中心的客户数据赋能平台,聚焦于企业数字化转型路上遇到的数据管理难题。微盟 CDP 依托于微盟数字生态系统, 无缝将商户域的企业微信、微商城、智慧零售、CRM 等多渠道多场景的用户数据进行实时采集、实时分析、实时分群打标及实时营销触达, 帮助企业获取、管理和应用私域数据,打破数据孤岛,建立统一全面的用户360视图及精细化的客户标签体系,从数据上获得更大的价值, 以数据驱动业务构建全链路自动化营销和智能化运营,实现企业的业务增长。

二、微盟CDP建设

微盟CDP整体数据架构如下:
图片其中:

  • 数据接入:数据接入层通过不同的方式将外部用户全渠道全场景的数据接入到系统中。接入方式有 Kafka 消息推送、MySQL CDC 主动同步、Hive 全量数据同步等。接入的用户数据有用户属性、用户行为、商城订单、商品、渠道、企业微信、导购等。
  • 数据实时处理包括:
    • 数据预处理:对数据进行适配、清洗、格式校验、字段填充等操作,将数据标准化归一化。然后将标准数据按优先级进行分流。
    • 数据建模:按照分析模型对用户数据进行建模分析,提取用户特征。
    • 数据存储:对于用户明细数据、聚合分析数据,按照不同场景进行存储,场景分为实时业务高并发点查场景、离线圈人场景、多维检索场景。
    • 数据同步:数据同步支撑数据在不同存储、不同系统间的高效流转。
    • ID引擎:ID引擎主要识别用户的唯一身份,将不同渠道不同身份标识的用户识别成唯一自然人。同时对于用户身份的合并事件提供数据合并支持。
  • 数据应用:业务层核心服务包括标签服务、能力透出服务、数据推送服务、自动化营销服务,为上层应用提供 CDP 核心数据能力。

1.离线处理和实时处理

目前市面上的大多数 CDP 平台都是基于离线引擎和离线数据的分析平台,对数据的处理时延比较高,用户数据到来后并不会立即被处理,而是周期性处理(如T+1H),或者用户手动触发(AD-HOC查询)。然而数据的价值会随着时间的推移变得越来越少,尤其是数据时代的今天,数据是新型货币,不能有效及时的处理和分析数据带来的是无形的损失。微盟 CDP 从系统建设之初就将其定位于实时的用户全场景系统,无论是在接入分析环节还是在营销触达环节,数据的实时性有着举足轻重的地位。然而实时系统与离线系统有天生的不同,在离线处理中数据是先行的,数据在一段时间内被收集完成之后再进行处理, 处理时数据是完备可见的,处理过程是明确的可复现的且是可试错的。而对实时处理而言,计算是先行的。计算逻辑被首先定义,源源不断的事件流随后进入系统中, 数据在系统中是一个一个被处理的, 处理时其他数据是不可见的;如果想要数据之间可见,也就是想要跨数据分析,需要有状态参与。并且实时处理中数据的顺序也会直接影响计算结果。离线处理和实时处理对比如下图:图片

由此可见,实时系统相较于离线系统具有天生的复杂性。然而与批处理相比,流处理也有众多优点,低延迟、可扩展性、灵活性,使得实时处理越来越流行。

数据流有一些区别于其他类型数据的关键特征,包括:

  • 连续性: 数据连续不断的产生,源源不断的流入系统,没有明确的终止时间。
  • 无界性:数据没有时间边界和数量边界,数据有可能延迟到达,有可能突然增长。
  • 异构性:数据从不同数据源流入系统,不同数据源的数据格式、数据质量会有一定的差异。
  • 时效性:数据处理对时间往往是比较敏感的,大部分场景要求在秒级内处理完成。
  • 高容量:通常以非常高的速率生成,这使得它们难以被处理。

2.数据接入及清洗

2.1.数据接入

数据接入层对接上游各个业务方数据源,将数据从外部接入到内部系统中。图片

2.2.数据清洗

由于数据是异构的,对于不同来源的数据需要做不同的数据清洗和适配逻辑。在数据处理环节中,数据清洗是最繁重凌乱的工作,每个业务方都有自己特殊的数据风格;然而脱离业务的通用逻辑是存在的,微盟 CDP 在实现的时候,将通用的清洗逻辑下沉成公共的组件,组件遵循开闭原则,对外支持多种的组件参数可按需配置,组件沉淀成组件库,存储在数据库中。组件之间通过流程配置进行编排;数据处理时通过动态编译技术将组件库和流程配置动态加载到 Flink 中,根据流程配置和参数动态编排组件,实现了组件可动态扩展、编排配置可实时热加载更新的机制。ETL 流程编排如下图所示:图片其中,ETL 流程包括多个子流程,子流程包括多个流程项,每个流程项有前置条件、数据转换器、失败策略。当前置条件满足时执行数据转换器、当转换失败时触发失败策略执行。在 ETL 流程中,前置条件、数据转换器、失败策略均为可重用组件,通过流程配置编排,通过动态编译热加载。基于 SPI 及动态编译技术,构建 CDP 数据处理的通用框架,实现业务处理环节80%可配置化(包括 ETL,聚合规则,入库规则,用户ID 合并规则等),实现框架和业务逻辑分离。组件库及热加载机制如下图:图片

2.3.突发流量应对

实时数据处理要求高时效性,但在数据接入环节往往由于数据不可控会出现各种各样的突发场景,比如:

  • 数据迁移场景:大量迁移数据均为历史数据,数据迁移的数据量大但由于是历史数据对数据的时效性要求并不高。
  • 商户做活动场景:当某个大商户做活动时,会有短时间特点事件的突发流量到来,特点是时间单一、短时间流量大。
  • 刷数据场景:目前部分业务数据直接实时同步业务库,当上游有刷数据动作时,会集中收到大批量数据变更。

不能有效地应对这些突发场景势必会导致实时数据处理时效性受到影响,因此在系统设计上实现了数据多通道机制,实现了历史数据流量限流、不同优先级数据分流机制。如下图:图片

  • 对于历史数据,根据预设的系统吞吐量,优先保证实时数据通行,仅在系统处理有余量的时候适量放行历史数据。
  • 对于实时数据,按照优先级(动态可配)将数据划分到不同优先级通道中,下游在消费时可根据优先级通道调整速率。

3.数据分析及聚合数据分析是提取用户特征进行用户洞察的重要环节,Flink 默认提供了开箱即用的数据分析能力。但是由于 CDP 业务处理的复杂性,Flink 原生数据处理方式并不能高效支撑 CDP 的数据处理场景。
例如,对于用户消费特征分析场景,要统计用户维度的消费数据,字段如下:图片如果使用 Flink 原生开窗能力处理方式如下:图片Flink 原生开窗聚合能力开箱即用使用方便,但存在以下问题:

  • Flink 原生开窗只支持表级别同一维度同一窗口大小,每个字段不能有不同的窗口大小。
  • Flink 默认的滑动窗口使用重叠窗口重叠状态的方式实现,导致状态膨胀。比如30天的窗口每天滑动一次,状态膨胀30倍,严重浪费资源。
  • Flink 默认窗口及聚合逻辑是静态编译的,任务启动时编译生成拓扑,运行时不可更改。修改逻辑需要修改代码重新部署。
  • 对于多种不同的聚合窗口,需要多个不同的 Flink 任务,浪费计算和内存资源。

为了解决 Flink 原生窗口聚合的问题,微盟 CDP 基于 Flink 自己实现了一套细粒度可配的开窗聚合方案,如下:

图片

基于 SPI 和动态加载机制,将字段级别的聚合功能封装成组件库,并提供多种配置化参数;基于自己实现的聚合功能,我们获得了以下优势:

  • 支持字段级别细粒度可配的开窗聚合能力,每个字段可以有独立的窗口独立的聚合逻辑,动态可配。
  • 滑动窗口状态只存储一份,避免状态膨胀资源浪费
  • 基于可重用组件的思想,将通用逻辑下沉到组件库,对外暴露动态参数,实现组件重用、逻辑可配。
  • 对于多种不同的聚合窗口,只需要一个 Flink 任务即可,避免原生资源浪费的问题。

4.用户数据合并

微盟用户中台对于用户身份使用用户ID进行识别,CDP 同样也是如此。对于用户的身份会有身份合并的场景,比如当一个用户通过不同渠道进入微盟体系时,最初由于无法识别两个为同一个自然人,在用户中台给用户在不同渠道各分配一个身份标识用户ID1和用户ID2。当用户的信息不断被完善,用户中台识别到用户ID1和用户ID2为同一个自然人,此时会发起用户身份合并的通知。当 CDP 收到用户身份合并通知时,需要对用户的数据进行合并。但对于实时系统来说数据合并并没有那么简单,需要考虑一下场景

  • 子用户ID数据是否全部到达?如果没到达不能进行合并
  • 子用户ID数据是否全部入库?如果没有入库则获取不到全部子用户ID数据,存在合并时数据丢失的风险
  • 数据是否有状态?比如用户首次消费金额统计,用户ID1和用户ID2合并时该如何取值?再如最近一周消费金额,当数据合并时窗口的边界何时被触发?
  • 数据合并完后再出现子用户ID数据该如何处理?
  • 在分布式环境中,如何保证数据的严格准确地被处理?

针对这些问题,我们采用了多级分布式栅栏的思想,通用处理流程如下:

图片

  • 当收到用户ID合并消息时,向用户数据流 Kafka 中的每个分区发送一个用户ID合并栅栏并标记唯一ID和数量,代表已接收到该子用户ID的所有数据,后续数据流中不会有该子用户ID的数据出现。
  • Flink 消费数据的同时收集用户ID合并栅栏,当某个栅栏收集完毕后,意味着该子用户ID数据已经被完全消费,并不一定会完全处理。(数据分区逻辑不同)此时向 Flink 每个分区(并行度)中发送一个入库栅栏并标记唯一ID和数量,代表该子用户ID的数据全部被消费完等待入库,随入库数据流下推。
  • 数据在入库的同时同步收集入库栅栏,当某个栅栏收集完毕后,发起正式用户ID合并。
  • 用户ID合并时,先从数据库中查出所有子用户ID的数据,然后从状态中查出子用户ID数据所对应的状态,同主用户ID的状态进行合并,合并后同时更新数据库和状态。
  • 数据流中出现已合并的子用户ID数据时,为了保证数据的准确性,构造用户ID合并补偿消息,再次发起用户ID合并流程。

5.实时用户打标

CDP 作为用户数据平台,承担着为各个业务方提供标签、分群、画像等能力的目标,是实时用户分析服务的最重要的一环。实时打标是用户特征和标签规则碰撞的结果,处理如下:

图片

其中:

  • 用户特征为上游实时数据分析产生的分析结果,规则为商户自定义标签规则或系统人群规则。
  • 实时标签服务不断接收实时用户特征,不断完善补全用户特征,使用用户特征集去碰撞标签规则,并且为结果创建人和标签关系。
  • 实时标签服务不仅支持特征的补全,同时支持特征的撤回。当用户不再持有某个特征时,上游会发送撤回消息,标签服务收到撤回消息后撤回特征并进行规则再次碰撞。

三、结语

微盟 CDP 的建设之路充满了探索和挑战,本文主要分享了 WOS 下 CDP 实时用户数据平台的设计探索,从宏观的角度阐述 CDP 建设过程中遇到的问题和探索的方案。目前 CDP 已服务于微盟内部企业微信、CRM、商城、导购等多条产品线,对外提供包括360用户画像、用户标签、人群细分、自动化营销在内的用户数据能力支撑。后续我们继续探索更加合理高效的数据平台建设思路。