Byte(1) - 类型标识生成
VarInt(SerializedSizeInBytes) - 序列化后的字节长度
ByteArray(RoaringBitmap) - RBM序列化
定制序列化的整体实现
Spark和ClickHouse生成的RBM序列化数据比对
ClickHouse中生成的RBM数据:
Spark中定制生成的RBM数据:
Spark生成RBM导入ClickHouse实现
创建ClickHouse表
使用Spark JDBC方式导入
查询CK表中数据验证
64位RoaringBitmap(RBM)定制序列化实现
ClickHouse是由号称“俄罗斯Google”的Yandex公司开发并在2016年开源。ClickHouse是一个列存储数据库,是原生的向量化执行引擎。目前ClickHouse在OLAP领域得到了广泛的使用,其首要原因是查询速度快。
在大数据处理中,海量数据的判重和基数统计是两个绕不开的基础问题。ClickHouse的解决方案是使用RoaringBitmap,其已有丰富的
bitmap操作函数
支持,可以实现非常灵活方便的判重和基数统计操作。
Bitmap用位图的方式来存储id数值信息,可以实现精确地基数统计。但因为Bitmap在数值稀疏时会造成很大空间浪费,因此提出了用RoaringBitmap(RBM)对稀疏位图进行压缩,减少内存占用并提高效率。RBM的主要思路是:将32位无符号整数按照高16位分桶,即最多可能有2^16=65536个桶,又称为container。存储数据时,按照数据的高16位找到container(找不到就会新建一个),再将低16位放入container中。也就是说,一个RBM就是很多container的集合。其详细的原理可参考
文章
。
在查看了ClickHouse的文档及搜索了各公司的实践方案(如
腾讯
和
头条
)后,发现目前只能将原始明细的id数据导入到ClickHouse后,再通过创建物化视图的方式构建RBM结构进行使用。但是原始明细数据量往往非常大,这不仅给数据ETL处理造成了很大的负担
文章目录简介ClickHouse简介RoaringBitmap(RBM)原理ClickHouse中使用RBM存在的问题RoaringBitmap(RBM)定制序列化实现ClickHouse中RoaringBitmap的结构解析Spark中RoaringBitmap的实现定制RBM序列化方式以兼容ClickHouseByte(1) - 类型标识生成VarInt(SerializedSizeInBytes) - 序列化后的字节长度ByteArray(RoaringBitmap) - RBM序列化定制序列化的整体
位集(也称为位图)通常用作快速数据结构。 不幸的是,它们会占用过多的内存。 为了补偿,我们经常
使用
压缩的位图。
咆哮的位图是压缩的位图,其性能通常优于传统的压缩位图,例如WAH,EWAH或Concise。 在某些情况下,咆哮的位图可以快数百倍,并且它们通常可以提供更好的压缩效果。 它们甚至可以比未压缩的位图更快。
咆哮的位图在许多重要应用中均能很好地工作:
尽可能
使用
Roaring
进行位图压缩。 不要
使用
其他位图压缩方法( )
做出使我的软件运行速度提高5倍的荣誉(BigML的Charles Parker)
项目中
使用
到了
ClickHouse
的bimtap结构,来分析下
ClickHouse
中bimtap的具体实现。
ClickHouse
中
bitmap
结构的类型为 AggregateFunction(group
Bitmap
, UInt32),对应如下源码:
template<typename T>
struct AggregateFunctionGroup
Bitmap
Data
Roaring
Bitmap
With
Small
Set
<T, 32>
在CH中产生位图
使用
普通函数
bitmap
Build可以由无符号整形数的数组直接产生位图,e.g.
WITH
bitmap
Build([32, 65, 127, 1026]) AS bm
SELECT bm,toTyp...
文章目录简介源码实现
Spark
SQL
使用
示例
Bitmap
是用来实现基数统计的一种常用方法,它可以实现精确的基数统计。为了提高
bitmap
对稀疏位图的压缩率,提出了
Roaring
Bitmap
(RBM)对稀疏位图进行压缩,减少了内存占用并提高了
使用
效率。
在Java中实现RBM的常用库是
Roaring
Bitmap
,其已经在
Spark
、Kylin和Druid等系统中得到了应用。那是不是可以将
Roaring
Bitmap
库封装成
Spark
SQL
的udf函数,从而可以对
bitmap
结构数据进行方便的计算操作,实
前几天遇到一个任务,从前也没太注意过这个任务,但是经常破9点了,执行时长正常也就2个小时。
看逻辑并不复杂,基本是几段
SQL
的JOIN操作,其中一个最耗时间的就是要根据底表数据Lateral view explode(array(字段, ‘all’)),一共lateral了4个字段,相当于数据量要扩大16倍。并且可怕的场景,lateral view之后还对11个字段进行了去重。
select
a22 as a,
b22 as b,
c22 as c,
d22 as