沙龙回顾|ClickHouse 在字节广告 DMP& CDP 的应用

本文介绍了ClickHouse在字节跳动广告DMP和CDP中的应用,重点讨论了第一版技术方案,包括明细存储、SQL优化以及在面对复杂查询和大查询时的不足。第二版方案引入了RoaringBitmap,通过位图计算优化了查询性能,减少了数据传输和资源消耗。文章还提到了RoaringBitmap的局限性及其改进,包括编码优化、并行计算和读取优化,展示了在ClickHouse上进行位图处理如何提升计算效率。
摘要由CSDN通过智能技术生成

那么首先是我们的第一版技术方案,这个技术方案的背景是,业务提出来希望能够尽快上线,时间比较紧。

我们采用明细存储的方式,表有 2 列,分别是 tag_id 和 uid。每一个 tag_id 表示一个人群包,uid 是对应的用户 id。那么如果是一个比较大的人群包,可能需要用上亿行来表示。我们对 tag_id 建立了主键,因此可以快速的找出对应的用户 id 集合。集合的交集操作会转化为 in,并集为 or,补集为 not in 表示。

我们看一个具体的例子。如果我们要求 A 交上 B 和 C 的并集。那么对应的 sql 就是如此。其中,交集是采用 in 子查询的方式。并集直接用 or 表示。其中,SELECT distinct uid FROM tag_uid_map WHERE (tag_id = B) OR (tag_id = C) 用来表示 B | C。SELECT count distinct(uid) FROM tag_uid_map WHERE tag_id = A 表示集合 A,uid IN 表示求交集计算。

A&(B|C)

SELECT count distinct(uid)

FROM tag_uid_map

WHERE tag_id = A

AND uid IN (

SELECT distinct uid

FROM tag_uid_map

WHERE (tag_id = B) OR (tag_id = C)

)

在这种情况下,我们想要快速的求出 sql 的结果,采用了 2 个优化方向:

  1. 因为 clickhouse 是分布式数据库,我们希望尽可能并行计算,减少节点之间数据传输,把计算下推下去,减少汇聚节点的计算压力。

  2. 因为最后要获取去重后的用户数,看看如何能够快速计算 count distinct。上一次分享也有人问字节是否在 count distinct 做过一些优化?我们也做了一些优化和尝试。

我们继续看之前的场景, A 交上 B 和 C 的并集。我们有没有办法能够划分不同的区间进行并行计算呢?答案当然是有的。

如果我们把用户 id 按照奇数偶数分为 2 个区间,可以保证一个用户只会在一个区间内,因为用户的 id 要么是奇数要么是偶数,且区间之间用户 id 不重复。那么 A B C 也同样划分为奇偶两个区间。在这样的基础上,可以在区间内单独的计算子集合的结果最后对区间计算结果进行汇总。A 交上 B 和 C 的并集就等于 A_奇数集合 交上 B_奇数集合和 C_奇数集合的并集 并上 A_偶数集合 交上 B_偶数集合和 C_偶数集合的并集的结果。对于人群预估来说,我们更关心集合的数目。A 交上 B 和 C 的并集所对应用户的个数可以转化为,A_奇数集合 交上 B_奇数集合和 C_奇数集合的并集所对应用户的个数加上 A_偶数集合 交上 B_偶数集合和 C_偶数集合的并集的用户数。因此,通过把用户 id 划分到不同的集合,我们可以在每个集合上并行计算。最后只需要把每个集合的用户数做一次累加就可以,我们的计算方式就是这样的。

以 A 交 B 为例:

我们在数据导入的时候按照用户 id 划分为 4 个区间,分别导入到 4 台不同的机器,保证每台机器上的用户不重复。这样在每一台机器计算完结果后,直接把结果进行汇总。同时,在人群预估的场景下,我们返回的是子区间 count distinct 结果,而不是对应的聚合函数中间状态。这样可以大大减少输的数据量。同时,最后只需要做一次累加,不需要把聚合函数中间状态进行 merge 后求去重后结果。实际场景的话我们划分的区间数可能要比机器数要多,这样才可能并行导入。

因此,在 clickhouse 上的改动主要

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值