火山引擎ByteHouse:一套方案,让OLAP引擎在精准投放场景更高效
更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群
广告精准投放场景
人群预估
- 人群预估主要是根据一定的圈选条件,确认命中的用户数目。在广告精准投放过程中,广告主需要知道当前选定的人群组合中大概会有多少人,用于辅助判断投放情况进而确定投放预算,通常要求计算时间不能超过 5 秒。
广告投放
广告精准投放过程中遇到的问题与痛点:
- 数据预估:广告主需要对选定的人群组合进行预估,以便判断投放情况并确定投放预算。但人群包数据量多,基数大。平台的用户数上亿,仅抖音的 DAU 就几亿,抖音、头条对应的人群包在亿级别,早期的预估版本采用ElasticSearch,但由于数据过于庞大,只能采用1/10抽样存储,导致10%的误差,业务难以接受。
- 查询性能:广告主可以设定一个非常复杂的圈选条件,导致计算复杂(单次计算可能包含几百上千个人群包),Hive和ES等方案在处理大数据量时,查询速度会变得非常慢,如果需要查询某个广告主的所有用户,需要扫描整个用户库,而这个过程可能需要几分钟甚至几个小时,无法满足实时性要求。
- 存储空间大:Hive和ES等方案需要额外的索引结构,导致存储空间变大,从而增加了存储成本。例如,如果需要对用户属性进行索引,就需要额外的存储空间来存储索引数据。
- 不支持高并发:Hive和ES等方案在处理高并发请求时,容易出现性能问题,无法支持高效的广告投放。例如,如果同时有多个广告主需要查询用户信息,就可能会出现查询阻塞或响应延迟等问题。
- 数据查询效率:采用ClickHouse支持预估,但随着数据量的增长,ClickHouse在当前存储引擎的支持下也难以保证查询时间。这导致了数据查询效率的问题,影响了用户体验。
ByteHouse BitEngine方案
方案简介
新查询引擎
- 针对广告人群预估业务开发的新查询引擎,基于ClickHouse提供的MergeTree Family系列引擎,添加了新的bitmap64类型和一系列的相关聚合函数。BitEngine提供的bitmap64类型适合存储和计算大量的用户ID之间的关系;在广告人群预估业务中,bitmap64类型用于存储人群包数据,然后将人群包之间的交并补计算转化为bitmap之间的交并补,从而达到远超普通查询的性能指标。
实现步骤
CREATE TABLE cdp.tag_uids_map (
tags String,
uids BitMap64 BitEngineEncode
)ENGINE = HaMergeTree('/clickhouse/xxxx/{shard}', '{replica}')
ORDER BY tag
| tag | uids |
| A | {10001,20001,30001,40001,50001,60001,70001,80001,90001} |
| B | {10001,20001,20002,20003,20004,20005,20006,20007,20008} |
要查询 A&B 的结果 SQL 为
SELECT bitmapCount('A&B') FROM tag_uids_map
BitEngine实现逻辑
核心思想
- 对数据做分区划分和编码,保证每个区间的数据之间不存在交集,然后使用roaring bitmap保存数据;
- 计算时每个分区的数据可以独立的做聚合计算,充分利用机器的并行能力,每个分区内部的聚合计算就是多个bitmap之间的交并补,利用roaring bitmap高效的交并补计算降低CPU和内存的使用;
- 通过字典将编码的结果反解回来,数据编码是为了让数据的分布尽可能稠密,roaring bitmap在存储和计算的时候就可以获得更好的性能。
业务应用
业务关键要素
- 人群包:广告主自定义规则计算出来的人群数据,标签是dmp团队根据市场需求定义的人群数据。
- 标签ID:每天定时根据产出规则更新一次,人群ID是自增的,每天根据广告主需求进行新建计算。
统一编码
- 为了对标签数据和人群数据的uid统一编码,编码服务先将标签数据中的uid和人群数据中的uid提取出来进行统一编码,将全量uid均匀hash到一万个桶中,桶编号为i[0<=i<=9999],uid在每个桶内由1开始顺序编码,每个桶的范围为i*2^40 - (i+1)*2^40。
- uid数据每天都在增加,因此需要支持增量编码, 编码服务每天会先获取增量uid,hash后顺序放置到每个桶中。
数据存储
- 完成编码后,会先把字典数据统一写入hive表中,便于字典的各种使用场景。
- 在数据经过分区和编码之后,ClickHouse可以以多种数据导入格式将数据以bitmap64类型存入磁盘。
数据计算
假设存在四个bitmap,分别为a,b,c,d;则(a | c) & (b | d)不一定等于(a & b) | (c & d)。
- 人群包A = [10001, 20001,30001,40001,50001],人群包B = [10001, 20001,20002,20003,20004]
- 通过BitEngine计算A&B = [10001, 20001]
- 人群包按照一定的规则划分为多个区间,任意两个区间之间的人群包没有交集
- 一个计算线程只读取同一个区间的人群包进行计算,得到一个中间结果
- 最终的中间结果只需要简单的进行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上线前后查询耗时监控
BitEngine上线后CPU负载对比
PageCache 使用情况(lower is better)
案例总结
点击跳转云原生数据仓库ByteHouse 了解更多
火山引擎ByteHouse:一套方案,让OLAP引擎在精准投放场景更高效的更多相关文章
- 高性能、快响应!火山引擎 ByteHouse 物化视图功能及入门介绍
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 物化视图是指将视图的计算结果存储在数据库中的一种技术.当用户执行查询时,数据库会直接从已经预计算好的结果中获取数据 ...
- cocos2d-x 多分辨率适配详解(转载),以前北京团队设计的游戏,也是用这套方案
http://blog.csdn.net/kyo7552/article/details/17163487 多种分辨率的适配一直都是一个蛋疼的问题,各家公司可能都有自己的一套方案.今天我为大家介绍的是 ...
- [转帖]OLAP引擎这么多,为什么苏宁选择用Druid?
OLAP引擎这么多,为什么苏宁选择用Druid? 原创 51CTO 2018-12-21 11:24:12 [51CTO.com原创稿件]随着公司业务增长迅速,数据量越来越大,数据的种类也越来越丰富, ...
- OLAP了解与OLAP引擎——Mondrian入门
一. OLAP的基本概念 OLAP(On-Line Analysis Processing)在线分析处理是一种共享多维信息的快速分析技术:OLAP利用多维数据库技术使用户从不同角度观察数据:OLAP ...
- 分布式大数据多维数据分析(olap)引擎kylin[转]
Apache Kylin是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay 开发并贡献至开源社区.它能在亚秒内查询巨大的Hiv ...
- OLAP引擎:基于Druid组件进行数据统计分析
一.Druid概述 1.Druid简介 Druid是一款基于分布式架构的OLAP引擎,支持数据写入.低延时.高性能的数据分析,具有优秀的数据聚合能力与实时查询能力.在大数据分析.实时计算.监控等领域都 ...
- 从0开发3D引擎(八):准备“搭建引擎雏形”
大家好,现在开始本系列的第三部分,按照以下几个步骤来搭建引擎雏形: 1.分析引擎的需求 2.实现最小的3D程序 3.从中提炼引擎原型 4.一步一步地对引擎进行改进,使其具备良好的架构 5.实现与架构相 ...
- JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述
可以后端开发的 javascript引擎有 Chrome V8 基于C++ java的Rhino引擎(JDK6被植入),Java8 被替换为Nashorn Rhino和Nashorn都是用Java实现 ...
- Fixflow引擎解析(一)(介绍) - Fixflow开源流程引擎介绍
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- mongodb底层存储和索引原理——本质是文档数据库,无表设计,同时wiredTiger存储引擎支持文档级别的锁,MMAPv1引擎基于mmap,二级索引(二级是文档的存储位置信息『文件id + 文件内offset 』)
MongoDB是面向文档的数据库管理系统DBMS(显然mongodb不是oracle那样的RDBMS,而仅仅是DBMS). 想想一下MySQL中没有任何关系型数据库的表,而由JSON类型的对象组成数据 ...
随机推荐
- nginx、rabbitmq、redis、zookeeper、zkui安装脚本
nginx安装脚本 #!/bin/bash yum install -y wget pcre-devel openssl openssl-devel gcc ###安装perl### cd /usr/ ...
- JVM-Java语法糖与Java编译器
基本类型和其包装类型之间的自动转换,也就是自动装箱.自动拆箱,是通过加入[Wrapper].valueOf(如 Integer.valueOf)以及[Wrapper].[primitive]Value ...
- 分享一次公司晋级考试的SQL题目,非常有趣的案例(postgresql 标量子查询 where lie 谓词过滤条件)
同事今天晋级高级工程师考试,发来一道公司出题目让我帮忙进行优化,其中场景二的案例非常有意思. 题目内容如下: 原始SQL: scott=> explain analyze scott-> ...
- 本地MQTT协议消息服务远程连接教程介绍
Mosquitto是一个开源的消息代理,它实现了MQTT协议版本3.1和3.1.1.它可以在不同的平台上运行,包括Windows.Linux.macOS等.mosquitto可以用于物联网.传感器.移 ...
- “技能兴鲁”职业技能大赛-网络安全赛项-学生组初赛 Crypto WP
babyRSA 查看代码 from gmpy2 import * from Crypto.Util.number import * flag = 'flag{I\'m not gonna tell y ...
- 查看API官方文档
盛年不重来,一日难再晨.及时宜自勉,岁月不待人. 学习一门语言, 了解其开发文档必不可少.开发文档就是我们在编程开发.维护.升级过程中的参考最全面.最权威的资料.我认为就是开发者为后人方便理解留下 ...
- iNeuOS工业互联网操作系统,高效采集数据配置与应用
1. 概述 2. 通讯原理 3. 参数配置 1. 概述 某生产企业世界500强的集团能源管控平台项目建设,通过专线网络实现异地厂区数据集成,每个终端能源仪表都有IP地址,总共有1000多台能源表 ...
- Django笔记四十四之Nginx+uWSGI部署Django以及Nginx负载均衡操作
本文首发于公众号:Hunter后端 原文链接:Django笔记四十四之Nginx+uWSGI部署Django以及Nginx负载均衡操作 这一篇笔记介绍如何使用 Nginx + uWSGI 来部署 Dj ...
- Nougat:结合光学神经网络,引领学术PDF文档的智能解析、挖掘学术论文PDF的价值
Nougat:结合光学神经网络,引领学术PDF文档的智能解析.挖掘学术论文PDF的价值 这是Nougat的官方存储库,Nougat是一种学术文档PDF解析器,可以理解LaTeX数学和表格. Proje ...
- IIS下使用SSL证书
IIS下使用SSL证书 本文介绍windowsServer下SSL证书配置及IIS站点配置 1. 生成SSL证书 在阿里云申请免费SSL证书 登录阿里云管理控制台,打开SSL证书管理 选择免费证 ...