AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

贝壳 DMP 平台建设实践

  • 2021-02-19
  • 本文字数:7403 字

    阅读完需:约 24 分钟

贝壳DMP平台建设实践

DMP 是一个大家讨论已久的话题,尤其广告领域,是以 DMP 为基础来展开工作的。由于每个公司所面临的业务场景不同、问题不同,所以在具体落地时的做法也不尽相同。今天主要和大家分享贝壳如何进行 DMP 落地。


主要内容包括:

  • 贝壳为什么做 DMP?

  • 贝壳 DMP 的整体设计

  • DMP 平台效果

  • 本次总结

为什么做 DMP?

从几个案例出发介绍

1. APP 消息推送

DMP 的数据与贝壳 APP 的推送系统整合后,可以做到千人前面来推送消息,避免用户收到的推送消息千篇一律、一模一样。比如,有用户偏好北京回龙观总价 400 万的两居室,那我们可以在推送文案以及文案的落地页上加入跟用户感兴趣房子相关的一些数据,这样用户点击的意愿就会被提高很多。

2. DSP 广告

贝壳的推广有一部分是 DSP 广告,也即我们在刷百度信息流的时候会刷到贝壳的广告。最早的投放方式是基于城市维度,每个人看到的都是和自己所在城市相关,比如北京的用户只看到了北京的一些广告文案。但是和 DMP 结合之后,就会跟兴趣挂钩。比如你昨天浏览了一个小区,那么第二天系统推送的时候,就会把这个小区的文案放在推送内容里面,这样用户的点击率意愿就会提高很多。进而整个广告的 CTR 也提升了,大概提升五到十倍左右,效果还是非常不错的。



3. 站内推荐

APP 的首页有三部分:第一部分是专属二手房源,属于导购页的一个分发,是一个导购专题,里面都是关于房子的一些专题信息,这些专题信息也是和用户兴趣挂钩的;第二部分是列表页,业务方会根据用户不同的兴趣给出不同的排版策略,排新房、排租房与用户兴趣相关,这里的策略就是依据 DMP 的数据做的;第三部分是整个房源列表,这块的展示也是基于 DMP 做到千人千面,把用户最感兴趣的一些房子第一时间展示给用户,吸引用户发生浏览、进而提升留存和转换。

4. 搜索

搜索,跟推荐类似,都是把用户最感兴趣的一些房源展示给用户,促进用户留存。



5. 潜客召回

我们通过一些数据分析会发现,用户跟经纪人产生联系之后,它后续转委托以及转带看的概率就会高很多。所以我们会实时去计算用户的数据,当用户的搜索、浏览房源、以及查看经纪人的相关信息等行为量达到一定程度后,我们计算认为他的行为足够丰富,这个时候就会做潜客召回,也即给用户弹一个框,引导用户去留资,留资完后就把其信息分发给经纪人,这样经纪人通过电话就可以与用户产生联系。

6. 商机引导

这是 IM 场景下的一个例子,就是当用户跟经纪人产生联系后,我们会把用户的画像数据推送给经纪人,经纪人可以直观地了解用户的偏好,方便其更好的去与客户进行沟通,如果沟通效果不错,则客户会留下手机号,之后顺带的就会产生一次委托,成为委托客。客户成为委托客后,经纪人就可以在委托客分析 B 端查看到客户更详细的一些信息,比如说最近的活跃状态,最近的一些行为数据,浏览了哪些小区,所浏览小区房价的变化趋势,还有客户喜欢什么时间在线上浏览、喜欢什么时间出来带看,这些信息可以辅助经纪人做好后续的约带看安排。

从上面这些案例可以看出,无论是站外的老客召回,还是站内的精细化运营,DMP 都在发挥着非常重要的一些作用。


那么到底什么是 DMP 呢?



其实 DMP 就是把用户各种各样的数据,包括结构化数据以及非结构化数据,进行整合计算然后标签化,通过标签来描述刻画用户 I,理解用户。比如,通过标签,我们解读到一个北京的用户,想看郑州的房子,喜欢 400 万的两居室。通过用户的标签,我们可以非常直观的了解用户。然后基于这些结构化的标签数据,我们也可以很方便地跟各个下游系统做对接,实现站外或者站内的精细化运营。

DMP 的整体设计

1. DMP 整体设计


贝壳 DMP 的整个架构设计,从下往上总共分成了五层:

① 最下面一层,也即第五层是数据收集层:收集层主要负责采集两类数据。第一类是用户在 APP 上的各种行为数据,比如搜索什么样的房子,浏览了什么样的房子,以及关注了什么样的房子等等。第二类是业务 DB 的各种线下数据,比如线下的带看、转委托等。这两类数据都会收集到 hive 里面。APP 上用户的行为数据采集,通过系统罗盘来实现,这个系统是贝壳专门用来进行埋点管理和埋点数据收集的。


② 第四层是数据加工层:数据采集到仓库里面后,会对数据进行各种的加工,然后产生相应的主题宽表。比如针对用户,我们会建一张用户主题宽表,将用户所有线上线下的数据打通,然后将数据整合到宽表里,基于这个宽表,我们可以做相关的数据分析以及模型计算。最终产出人房客的基础标签数据。


③ 第三层是应用数据存储层:数据加工后产生的标签数据都是在 hive 里面的,大家知道 hive 其实是一个分析型的数据库,它的查询速度非常慢,是不能够支撑各种业务上高速查询的需求。所以我们需要一个应用存储层。目前对于存储,我们做了三种:第一种是 Hbase,主要满足高并发场景下的 KV 高并发的查询;第二种是 clickhouse,这是比较新的一种 OLAP 引擎,主要做 SQL 形式的人群圈包和人群的洞察;第三种是 Mongo,在圈人群包之后,我们会将各种 ID 数据同步到 Mongo,然后与业务系统对接满足业务上的查询需求。比如我们给用户推送消息时,push 系统会把我们生产的人群包里面的设备数据拉走,然后按照设备给用户做推送,这里就会涉及到高稳定性高并发的分页查询。


④ 第二层是应用层:基于存储层,我们搭建了应用层,主要提供的功能如下:

  • 标签管理,主要支持把 hive 数据快速的导入到 CK 里面或者 Hbase 里面,以及快速把数据上线到标签层;

  • 标签集市,可以让大家快速的了解我们现在都有什么样的标签;

  • 人群圈选,支持以可视化的拖拽形式来自由的组合标签来圈选用户;

  • 人群洞察,在圈选人群包之后,可以通过人群洞察来看人群的构成是什么样子,比如地域分布、性别分布等等;

  • 人群拓展,这个功能在广告领域是用的比较多的一个功能,它可以通过一个少量的种子用户,然后扩展出一个海量的用户群体。


⑤ 最上面的一层就是 API 层:API 层主要做的是一个统一的数据输出功能,且包含了鉴权、流控、容灾等各种控制。基于 API 层,我们可以对接各种业务系统,如推荐搜索、人群分析、push 系统。另外,从数据层到 API 层,我们做了一个比较完整的监控报警功能,这样可以保证我们整个数据的可用性和 API 的高可用性。

2. 逐层介绍

接下来我们逐层看一下每层是怎么做的,以及遇到的问题和相应的解决方案。

① 数据加工层:



在数据加工层,我们一共产出 4 种数据,2 份偏基础的数据-基础数据、行为数据,2 份偏核心的数据-偏好数据、预测数据。

  • 第 1 种是基础数据,包括地理位置、APP 相关、活跃相关。比如用户的常驻地,这个是根据 IP 解析获得,而工作地与居住地的商圈划分,则根据 GPS 在时间上的分配来确定,白天时间段多的定为工作地,晚上时间段多的定为居住地。比如用户是否安装 APP,是 IOS 还是安卓,对应的版本是什么,使用习惯是什么,以及何时注册、何时激活、最后一次活跃的时间。

  • 第 2 种是行为数据,主要是统计一段时间内行为的累计情况,通过一些简单的统计分析就能得到这些数据。这些累计数据主要是围绕着贝壳整个的找房路径来就展开了,比如:用户进入 APP 后产生搜索、然后浏览房源、关注房源、……、一直到最后的成交。相应的数据有:近 X 天搜索次数、近 X 天浏览次数、近 X 天带看次数等。

  • 第 3 种是偏好数据,这块数据是最核心的一块数据,前面讲到的各种系统应用,其实都是偏好数据在发挥各种各样的作用。我们主要围绕用户对房子上的各种各样的偏好(如商圈、价格、面积等),通过一个公式来计算其偏好;这个公式是比较通用的,是通过行为次数乘以行为权重再乘以衰减因子然后得到一个得分,也即偏好得分。这里的行为就是围绕着找房路径的那些行为。不同行为的权重会分别不同,比如一个 400 电话可能相当于五次浏览,一次带看可能相当于十次浏览等,权重的初期值可以与业务方沟通确定一个,后期的话可以依赖算法的能力去计算。衰减因子主要用来刻画用户兴趣渐变的过程,用户的兴趣是不停变化的,用户越近的一些数据,行为权重可能会越高,越早远的一些数据,权重就会越低一些。

  • 第 4 种是预测类数据,这部分数据主要是通过一些机器学习、一些计算模型来获取的,用来阐述用户未来发生某种行为的概率。比如用户未来几天内产生商机的概率、产生委托、产生带看、成交的一些概率。前面说到的潜客召回,就利用了这里商机概率的数据。

  • 另外,除了以上用户角度的四份数据之外,我们还有经纪人的数据,有了用户数据,有了经纪人数据,我们就可以做各种匹配和使用,比如给用户推荐经纪人,比如经纪人任务系统打通,然后通过一个调度系统来调度经纪人以提高效率。


在建设这些数据的过程中,我们遇到了很多问题。比较核心和突出的问题有三个。

  • 第一个问题:用户数据如何做归一,这个问题是所有做 DMP 或者做用户数据绕不开的一个问题,比如一个用户有两个手机,一个 IOS,一个安卓,安卓手机上链家 APP 和贝壳 APP,IOS 手机上面安装了贝壳 APP,如果没有做用户归一,我们可能会把这个用户识别成三个用户,这样刻画用户显然是不完整不精确的。我们的解决方式是:不同设备的按照手机号做归一、同一设备上不同 APP 的按照手机设备号 IMEI 归一,具体的实现方式是:通过 Spark 把用户所有的节点数据加载在一起,然后使用 GraphX 来去构建图关系,根据图关系的连通性生成用户的唯一实体。

  • 第二个问题:DMP 的数据是用 180 天的数据来计算的,每次计算可能会涉及到上百亿的数据量,在这种海量的数据量下,我们如何保证数据产出的及时性?这里我们主要用了四种方法,第一种方法是列裁剪,主题宽表的字段非常多,但是标签计算只需要其中某些字段,因此我们基于宽表生成很多临时表,只把所需字段给裁剪出来;第二种方法是预聚合,每天我们都需要计算产生很多的行为统计数据,但没必要每次都从明细数据算,可以每天预聚合一次,通过每天的预聚合来合成所需要的统计数据;通过列裁剪和预聚合,整个数据量降低到原先的 1/10 到 1/20,进而相应的数据计算量也减少了很多;第三种方法是增量计算,我们每天都是横跨近 180 天的数据来计算,采用增量计算来处理,每次把最新的加进来,把最老的给去掉,这样就没必要每次都计算 180 天的数据;第四种方法是集群资源隔离,最早的时候 DMP 任务使用公共队列,公共队列有个问题,就是如果新上一批任务,它的效率可能会非常差,然后整个队列任务会变得非常卡,DMP 数据产出的稳定性就会受到影响,所以我们为 DMP 单独申请了一个独立的队列,这样产出及时性就得到了保障。

  • 第三个问题:50+的偏好标签如何在迭代中快递开发和上线。房屋的字段是非常多的,因为涉及到二手房、新房、房屋租赁等业务,而且每个业务线有其各自特点,所以标签数据就非常多。虽然数据很多,但是计算公式其实是相同的,也即指标是类似的,每次计算只是维度不同而已,比如有些是按照价格段维度计算,有些是按照商圈维度计算,因此我们可以实现配置化,通过一个数据库来去维护所有标签的维度信息,根据这些信息动态的生成 SQL,然后通过 Spark 运行这些 SQL 来生成各种各样的标签数据,也即标签化。当标签计算要增加一种用户行为的话,通过配置化修改数据库的生成逻辑即可完成一次标签上线。


② 存储层:


在存储层我们面对的问题主要有四个。

  • 第一个是:亿级调用量下数据查询的稳定性如何保障?现在整个 DMP 调用量是非常大的,基本上用户在 APP 里每一次行为都会涉及到调用 DMP,通过 DMP 来做业务决策和 APP 端的策略响应。

  • 第二个是:秒级人群预估。运营同学在做投放等运营时,需要预估计算人群的用户数量,通常的做法是不断建人群包来查看人群包的大小直到人群包的大小达到预期,这种做法效率非常低下。是否可以有人群预估的功能,支持通过拖拽的形式,快速的预估到人群包的大小。

  • 第三个是:分钟级的人群计算,我们每天大概需要计算 200 到 500 个左右的人群包,我们怎么去保障这些人群包可以尽快的被计算出来然后投入到业务使用中?

  • 第四个是:目前我们有 1300+的标签,如何才能做到标签快速上线?

基于上述这些问题,我们首先看一下整体存储层的设计。



  • 第一部分:最左边是 hive 里的四份核心的数据,然后通过 BulkLoad 把数据导入到 HBase,BulkLoad 的导入方式能实现效率的最大化,同时可以避免性能上的开销;数据汇总到一起后,我们通过 API 的方式对外提供服务。这个地方我们做了几点优化,一个是为 HBase 申请了 SSD 的磁盘,HBase 主要是支持海量数据的写入,数据查询的话,基本上都在几十毫秒到几百毫秒,无法满足我们五毫秒左右的查询时间需求,我们希望可以通过缩短查询时间,来给业务策略争取更多的时间;另一个是为 API 做了 Redis 预缓存,业务频繁调用的用户数据基本上是最近活跃的用户数据,所以我们每天通过 Spark 把 hive 里最近七天活跃的用户导入到 Redis 里做预缓存,同时也做了流控、容灾控制等来保障 API 的高可用。

  • 第二部分:通过 Spark 将 hive 里的数据导入到 ClickHouse,然后再通过 SQL 的形式做圈人群包和人群洞察。最早的圈包是使用 SQL 来做,也即通过标签的拖拽,对应到标签的与或非,然后再翻译成 ClickHouse 的 and 操作或者 or 操作。但是 ClickHouse 对 join 支撑并不好,join 的时候会带来一些问题,比如当标签非常复杂的时候,如 20 到 50 个标签组合圈选一个人群包,对应的 SQL 发送到 ClickHouse,要么把 ClickHouse 查挂,要么查询非常慢而不能满足业务方的性能需求。这个地方我们通过引入 Bitmap 来解决,它是做人群圈选常用的一个技术。首先我们构建一个用户 ID 表,然后通过 Spark 加载用户的各种标签数据,加载之后通过各种维度来聚合,生成各种维度上的 Bitmap 数据,也即通过 Spark 生成 ClickHouse 底层所需要的 Bitmap 数据,其实 ClickHouse 底层 Bitmap 数据的存储结构是 Roaring Bitmap,因此我们通过 Spark 生成的是 Roaring Bitmap 数据,再经过序列化之后会存储到 ClickHouse 里的 Bitmap 表里。举例说明下如何使用,比如性别有男女,我们会给男生生成一个 Bitmap,给女生生成一个 Bitmap,如果圈选用户时选择城市是北京、性别是男,我们只要把性别是男的 Bitmap 查出来,再把城市是北京的 Bitmap 查出来,然后做一次与运算,就能得到这个圈选人群了,而且通过 bitmapCardinality 函数可以很快得到人群的基数,这样就可以实现秒级的人群预估,这就是 Bitmap 的实现方式。但是这里有一个问题需要我们考虑,就是我们有各种各样的行为的数据是连续的,比如用户近几天浏览了多少套房子,对这种连续性数据,我们该怎么做呢?整个底层的实现的话,我们对浏览了 8 套房子的用户,会生成一个大于等于 8 的 Bitmap 进行存储,同时会生成大于等于 7 一直到大于等于 0 的 Bitmap 且一并存储。这样的话我们做标签与或非的时候,如果选择小于 8 的用户,我们就可以把大于等于 0 和大于等于 7 的用户做一个异或,然后得到小于 7 的用户群体。通过这种方式,我们就可以对应的翻译成异或的形式来实现各种大于、等于、小于的逻辑操作。利用 Bitmap 我们确实取得了一个非常大的进步,把人群包的圈选从原先的 15 分钟到 20 分钟,降低到现在的 1 分钟,整个人群包(200-500 个)的构建时间也从原来的十几个小时压缩到现在的 4-5 个小时。


实时画像



另外,说一下实时画像。关于实时画像,大家都比较质疑,对于房产领域这种长周期的业务,到底有没有做实时画像的必要。在我们做数据分析的时候,发现用户生命周期是分几个阶段的,在早期的时候他的需求是不确定的,可能会随着时间的变化快速地发生变化,只有经过一段时间的沉淀之后,他的偏好才会稳定下来。如果没有实时画像的话,就无法捕获到用户前期兴趣的快速变化,在做差异化服务的时候效果就会打折扣,因此是有必要做实时画像的。具体的操作实践为:把线上的所有行为数据收集到 kafka 里面,线下所有的数据通过 binlog 的形式收集到 kafka 里面,然后通过行为聚合模块(也即 Spark Streaming)消费 kafka 的数据,再加上房屋的各种数据,来统计汇总用户在各种各样行为上的次数。比如浏览了 3 次回龙观、浏览了 5 次 400 万以上的房等。基于这些次数,再结合 kafka 消费传递过来的用户信息,通过偏好计算模块和行为模块就可以得到用户的偏好数据。偏好数据的计算方式就是之前讲过的一个公式,用户行为次数乘以行为的权重再乘以时间衰减。表示偏好的得分数据最终存储到 Redis 里面,通过 API 对外提供服务。补充说明下,上述过程中的行为次数统计数据是存储在 HBase 中的,且汇总为小时级,每个小时会存一份数据,为了使偏好计算模块可以快速的查询数据,采用宽表的形式进行存储。实时画像主要应用在推荐和搜索,业务效果明显, CTR、CVR 提升幅度在 3%~10%+。


最后讲一下标签的快速上线,也就是如何把 hive 的数据快速的导入到 CK 里面。



这里我们通过配置化的管理,可以知道 hive 的表和字段在 CK 里面是映射到哪张表哪个字段,以及对应字段是枚举值还是个连续值。如果枚举值的话,就维护它的码表相关数据。通过 Spark 可以动态化的把数据导入到 CK 里面,导入 CK 后,就可以做标签配置了。通过这个标签配置管理,可以把 CK 的各种数据上线到标签层、以及标签的上下线、还有层级的维护。基于这些标签,就可以做可视化的圈包了,任意的拖拽标签之后,就可以看到这个标签组合下有多少人群,数量是多少,同时也可以做这种人群的各种细粒度多维度数据分析,比如这个人群的地域分布、性别分布、活跃情况等。


DMP 平台效果

1. 全场景、海量用户覆盖



横贯打通了贝壳和链家两个 APP,其中也整合了 PCM 站、APP、以及小程序,把所有数据整合到一起,总共涵盖 4 亿的用户;业务线涵盖了二手房、新房、租房、海外、装修,这些业务 APP 用户达到 6000 万。

2. 丰富的标签体系和强大的人群计算能力



总共有 1300+标签, APP 用户偏好覆盖率达到 60%,每天产出 200~500 的人群包,分钟级的人群构建,秒级别人群预估。

3. 稳定、可靠的 API 服务


API 目前已经有 6 亿的调用量了,高峰的时候有 8 亿的调用量,响应时间在五毫秒左右,SLA 达到 4 个九。

总结



贝壳是做人房客信息匹配的,标签在里面起到了非常好的连接作用,通过标签可以给客推荐房子,也可以给客推荐经纪人,同时也可以辅助经纪人更好地了解客户,同时也可以辅助经纪人给委托客推荐感兴趣的房子。通过分享中涉及到的案例,大家也能看到,DMP 在业务上的应用还是非常广泛的。


后续我们的工作重心会放在完善数据的准确性和提高数据的覆盖率上,使其在业务上发挥更大的价值,同时我们也会做用户生命周期的管理。前面给大家讲的案例,都是在一个一个的点上发力,但是其实用户是需要有一个全生命周期的运营策略,比如怎么做站外触达、接下来怎么做站内精细化运营,站在一种统筹的高度做用户生命周期状态的管理,让用户尽可能的往成熟期去发展,然后最终产生商业价值。


今天的分享就到这里,谢谢大家。


本文转载自:DataFunTalk(ID:datafuntalk)

原文链接:贝壳DMP平台建设实践

2021-02-19 07:004016

评论

发布
暂无评论
发现更多内容

JDK 从8升级到11,使用 G1 GC,HBase 性能下降近20%。JDK 到底干了什么?

毕昇JDK社区

Hbase 入门详解

Se7en

黄金圈法则解读数据中台(1):为什么需要数据中台

水滴

数据中台 黄金圈法则 8月日更

2020-2021阿里巴巴Java面试真题解析

Geek_f90455

Java 程序员 后端

Vue组件通信之ref

Augus

8月日更

NLP随笔(三)

毛显新

人工智能 自然语言处理 神经网络 深度学习

【最不佳实践】函数计算的函数是什么意思

刘宇

Serverless

弱口令到底是什么牛马?

网络安全学海

黑客 网络安全 信息安全 渗透测试 漏洞挖掘

12年高级工程师的“飞升之路”

Geek_f90455

Java 程序员 后端

Windows10下JDK8下载及java环境配置

Bob

8月日更

2020-2021京东Java面试真题解析

Geek_f90455

Java 程序员 后端

在线网页快捷方式创建工具

入门小站

工具

SpringBoot 中的事务处理

xcbeyond

事务 springboot 8月日更

趁着课余时间学点python(二)缩进 标识符 保留字 注释 输入输出的理解

ベ布小禅

8月日更

第一次凡尔赛,字节跳动3面+腾讯6面一次过,谈谈我的大厂面经

编程菌

Java 编程 程序员 面试 计算机

各种消息队列设计要点与对比

海明菌

消息队列 消息队列对比 消息队列系统设计

我测了啊,我真测了!

QualityFocus

测试 质量保障 线上问题 缺陷

缓存数据历险记(一)--被缓存警察上课一天

卢卡多多

redis 缓存 8月日更

一个好的产品需要一个好的产品

刘宇

产品经理

再见 Jenkins!几行脚本搞定自动化部署,这款神器有点厉害

编程菌

Java 编程 程序员 计算机 技术宅

【最不佳实践】文件上传并不简单

刘宇

Python Serverless 文件上传

从未如此简单:基于Serverless架构的博客

刘宇

Serverless Hexo 博客

Elasticsearch VS ClickHouse

Se7en

奥运“哮喘”运动员为什么越来越多?

脑极体

为什么需要数据库连接池

赖猫

MySQL 数据库 后端 连接池

Linux之watch命令

入门小站

Linux

「SQL数据分析系列」15. 元数据

Databri_AI

sql 脚本 元数据

王者并发课-钻石2:分而治之-如何从原理深入理解ForkJoinPool的快与慢

MetaThoughts

Java 多线程 并发

网络攻防学习笔记 Day94

穿过生命散发芬芳

网络攻防 8月日更

DDD领域驱动设计·学习应用·一

小诚信驿站

领域驱动设计 领域驱动模型DDD 中台架构 领域驱动

2020-2021华为Java面试真题

Geek_f90455

Java 程序员 后端

贝壳DMP平台建设实践_大数据_DataFunTalk_InfoQ精选文章