

由于流量红利逐渐消退,越来越多的广告企业和从业者开始探索精细化营销的新路径,取代以往的全流量、粗放式的广告轰炸。精细化营销意味着要在数以亿计的人群中优选出那些最具潜力的目标受众,这无疑对提供基础引擎支持的数据仓库能力,提出了极大的技术挑战。
在数据平台建设中,不少企业开始引入OLAP引擎,以提升对营销活动的数据实时查询和相应效果,提升精准投放表现。OLAP引擎的特点在于能处理大规模的数据集,并快速地提供多维度的数据分析的结果。
ByteHouse则是火山引擎推出的一款基于开源ClickHouse构建的OLAP引擎,具备云原生的特点,能提供极速数据分析服务,支撑实时数据分析和海量数据离线分析,对内经过字节跳动大量业务检验,对外也已在互联网、游戏、金融、汽车等领域落地,并产生了良好业务效果。
本篇文章则聚焦ByteHouse技术和落地经验,以字节跳动内部场景为例,具体拆解广告业务的实现逻辑和业务效果。




数据预估:广告主需要对选定的人群组合进行预估,以便判断投放情况并确定投放预算。但人群包数据量多,基数大。平台的用户数上亿,仅抖音的 DAU 就几亿,抖音、头条对应的人群包在亿级别,早期的预估版本采用ElasticSearch,但由于数据过于庞大,只能采用1/10抽样存储,导致10%的误差,业务难以接受。
查询性能:广告主可以设定一个非常复杂的圈选条件,导致计算复杂(单次计算可能包含几百上千个人群包),Hive和ES等方案在处理大数据量时,查询速度会变得非常慢,如果需要查询某个广告主的所有用户,需要扫描整个用户库,而这个过程可能需要几分钟甚至几个小时,无法满足实时性要求。
存储空间大:Hive和ES等方案需要额外的索引结构,导致存储空间变大,从而增加了存储成本。例如,如果需要对用户属性进行索引,就需要额外的存储空间来存储索引数据。
不支持高并发:Hive和ES等方案在处理高并发请求时,容易出现性能问题,无法支持高效的广告投放。例如,如果同时有多个广告主需要查询用户信息,就可能会出现查询阻塞或响应延迟等问题。
数据查询效率:采用ClickHouse支持预估,但随着数据量的增长,ClickHouse在当前存储引擎的支持下也难以保证查询时间。这导致了数据查询效率的问题,影响了用户体验。

CREATE TABLE cdp.tag_uids_map (tags String,uids BitMap64 BitEngineEncode)ENGINE = HaMergeTree('/clickhouse/xxxx/{shard}', '{replica}')ORDER BY tag
SELECT bitmapCount('A&B') FROM tag_uids_map
人群包:广告主自定义规则计算出来的人群数据,标签是dmp团队根据市场需求定义的人群数据。
标签ID:每天定时根据产出规则更新一次,人群ID是自增的,每天根据广告主需求进行新建计算。
1. 完成编码后,会先把字典数据统一写入hive表中,便于字典的各种使用场景。
2. 在数据经过分区和编码之后,ClickHouse可以以多种数据导入格式将数据以bitmap64类型存入磁盘。
假设存在四个bitmap,分别为a,b,c,d;则(a | c) & (b | d)不一定等于(a & b) | (c & d)。
人群包按照一定的规则划分为多个区间,任意两个区间之间的人群包没有交集
一个计算线程只读取同一个区间的人群包进行计算,得到一个中间结果
最终的中间结果只需要简单的进行bitmap or计算即可
不同分区的文件不会交叉读取(ClickHouse的文件读取粒度小于文件粒度,会存在多个线程先后读一个文件的情况,一个分区也可能由多个文件组成),即一个线程只会读A_1,B_1,不会在这之间读取A_2或者B_2。
一个分区读取完成后,可以立即触发聚合计算,执行bitmap之间的计算逻辑,获得中间结果。即A_1,B_1 读取完成后,可以立即计算A_1 & B_1。
线程计算完中间结果后,可以继续读其他文件
如果需要计算的结果是bitmap的基数的时候,BitEngine直接将各个中间结果的基数相加
如果计算结果需要的是bitmap,BitEngine直接将所有的bitmap合并起来,这里合并指的是bitmap or计算

数据存储空间缩小了 3 倍+
导入时间缩小了 3 倍+
查询 avg/pct99/max 都下降明显,pct99 从 5 s 降低到 2 s
CPU 使用下降明显,PageCache 节省 100 G+
查询误差从10% 下降到 0%
/ BitEngine上线前后查询耗时监控




产品介绍









