Q&A

Q:如图。

A:当然是自带的。其实RoaringBitmap正是ClickHouse位图的底层实现(笑

RoaringBitmap的预备知识请见这里。

在CH中产生位图

使用普通函数bitmapBuild可以由无符号整形数的数组直接产生位图,e.g.

WITH bitmapBuild([32, 65, 127, 1026]) AS bm
SELECT bm,toTypeName(bm);┌─bm─┬─toTypeName(bm)─────────────────────────┐
│  A� │ AggregateFunction(groupBitmap, UInt16) │
└────┴────────────────────────────────────────┘

可见,位图在CH中的本质是AggregateFunction(groupBitmap, UInt*)类型的(*由位图中的最大值弹性决定),即groupBitmap这个聚合函数产生的中间结果。根据聚合函数的combinator语法,加上-Merge后缀再查询一次:

WITH bitmapBuild([32, 65, 127, 1026]) AS bm
SELECT bm,groupBitmapMerge(bm);┌─bm─┬─groupBitmapMerge(bm)─┐
│  A� │                    4 │
└────┴──────────────────────┘

也就是说,groupBitmap函数返回的是位图的基数(即1的数量)。显然,与-Merge后缀相对,我们还可以用-State后缀来对某一列生成位图:

SELECT groupBitmapState(toUInt64(user_id)) FROM ods.analytics_access_log_local
WHERE ts_date = today();-- 这个位图很长,所以显示大量乱码hhh

ClickHouse提供了很多位图操作的函数,参见官方文档,稍后会给出示例。

翻翻源码

既然位图都是从groupBitmap函数构建出来的,就来看看与其相关的实现吧。来到AggregateFunctionGroupBitmapData.h,定义如下:

template <typename T>
struct AggregateFunctionGroupBitmapData
{bool doneFirst = false;RoaringBitmapWithSmallSet<T, 32> rbs;static const char * name() { return "groupBitmap"; }
};

其核心就是RoaringBitmapWithSmallSet这个数据结构,继续看代码:

template <typename T, UInt8 small_set_size>
class RoaringBitmapWithSmallSet : private boost::noncopyable
{
private:using Small = SmallSet<T, small_set_size>;using ValueBuffer = std::vector<T>;Small small;roaring_bitmap_t * rb = nullptr;void toLarge(){rb = roaring_bitmap_create();for (const auto & x : small)roaring_bitmap_add(rb, x.getValue());}public:// ......
}

roaring_bitmap_t就是RBM在CRoaring库中的实现,SmallSet又是什么鬼?其实它的定义位于SmallTable.h中,是一个限定大小(无法扩容)的小集合,底层用数组来存储。在前面的结构体里,模板参数small_set_size设为32,说明它最多只能容下32个元素。

继续向下读一段:

public:bool isLarge() const { return rb != nullptr; }bool isSmall() const { return rb == nullptr; }~RoaringBitmapWithSmallSet(){if (isLarge())roaring_bitmap_free(rb);}void add(T value){if (isSmall()){if (small.find(value) == small.end()){if (!small.full())small.insert(value);else{toLarge();roaring_bitmap_add(rb, value);}}}elseroaring_bitmap_add(rb, value);}UInt64 size() const{return isSmall()? small.size(): roaring_bitmap_get_cardinality(rb);}// ....

这下就非常明显了:当位图的基数少于32时,仅使用SmallSet存储;一旦超过此阈值,就调用toLarge()方法转化为RoaringBitmap,此后都在RoaringBitmap上操作。之所以有这种区别,想来是因为SmallSet在小数据量下的性能比RBM更优吧。

当然,在RoaringBitmapWithSmallSet之间进行运算时,就需要分情况讨论了。举个栗子,两个CH位图做按位与运算(对应bitmapAnd函数),对应方法如下:

void rb_and(const RoaringBitmapWithSmallSet & r1)
{ValueBuffer buffer;if (isSmall() && r1.isSmall()){// intersectfor (const auto & x : small)if (r1.small.find(x.getValue()) != r1.small.end())buffer.push_back(x.getValue());// Clear out the original valuessmall.clear();for (const auto & value : buffer)small.insert(value);buffer.clear();}else if (isSmall() && r1.isLarge()){for (const auto & x : small)if (roaring_bitmap_contains(r1.rb, x.getValue()))buffer.push_back(x.getValue());// Clear out the original valuessmall.clear();for (const auto & value : buffer)small.insert(value);buffer.clear();}else{roaring_bitmap_t * rb1 = r1.isSmall() ? r1.getNewRbFromSmall() : r1.getRb();roaring_bitmap_and_inplace(rb, rb1);if (r1.isSmall())roaring_bitmap_free(rb1);}
}
  • 当this为小位图时,遍历this并逐个检查其中的元素在r1是否存在(只是根据r1的大小不同调用的方法不同而已),将重合的元素放入缓存,再重新插入this中。
  • 当this为大位图时,直接调用CRoaring自带的roaring_bitmap_and_inplace()方法做与运算。注意如果r1为小位图,需要先调用getNewRbFromSmall()方法生成新的RBM。

位图操作函数的定义与实现都位于FunctionsBitmap.h内,例如刚才说过的bitmapAnd函数:

using FunctionBitmapAnd = FunctionBitmap<BitmapAndImpl, NameBitmapAnd>;template <typename T>
struct BitmapAndImpl
{static void apply(AggregateFunctionGroupBitmapData<T> & bitmap_data_1, const AggregateFunctionGroupBitmapData<T> & bitmap_data_2){bitmap_data_1.rbs.rb_and(bitmap_data_2.rbs);}
};

位图部分的源码在整个ClickHouse体系中算是相当友好的,看官也可自行查看,不再赘述。

CH位图的应用

我们知道,位图在需要精确统计基数及快速求交集、并集的场景非常有用。以用户行为(点击流)数据为例,创建以下的表:

CREATE TABLE tmp.analytics_access_log_bmp (ts_date Date,event_type LowCardinality(String),user_bmp AggregateFunction(groupBitmap, UInt64)
)
ENGINE = AggregatingMergeTree()
PARTITION BY ts_date
ORDER BY event_type
SETTINGS index_granularity = 16;

这里是以日期和事件类型作为key,将符合条件的用户ID以位图存储。注意为了配合AggregateFunction,引擎应使用AggregatingMergeTree,并且此表的行数肯定偏少,所以索引粒度可适当降低。

取一些数据灌入表中:

INSERT INTO tmp.analytics_access_log_bmp
SELECT ts_date,event_type,groupBitmapState(toUInt64(user_id))
FROM ods.analytics_access_log_local
WHERE ts_date >= '2020-08-15' AND ts_date <= '2020-08-20'
GROUP BY ts_date,event_type;

这样,我们就可以非常快速地统计每天查看过商品详情页的用户数:

SELECT ts_date,bitmapCardinality(user_bmp) AS user_cnt
FROM tmp.analytics_access_log_bmp
WHERE event_type = 'OpenGoodsDetail';

以及统计前一日打开过App,后一日点击过“立即购买”的用户转化率:

SELECT c1 / c0
FROM (SELECT bitmapCardinality((SELECT user_bmp FROM tmp.analytics_access_log_bmpWHERE ts_date = '2020-08-17' AND event_type = 'AppStart')) AS c0,bitmapCardinality(bitmapAnd((SELECT user_bmp FROM tmp.analytics_access_log_bmpWHERE ts_date = '2020-08-17' AND event_type = 'AppStart'),(SELECT user_bmp FROM tmp.analytics_access_log_bmpWHERE ts_date = '2020-08-18' AND event_type = 'BuyNow'))) AS c1
);

毫无疑问,由于位图操作消灭了GROUP BY、JOIN等复杂的关系代数操作,效率有极为明显的提升。

The End

Happy Friday night.

民那晚安晚安。


http://www.taodudu.cc/news/show-4052196.html

相关文章:

  • SparkSQL ClickHouse RoaringBitmap使用实践
  • Roaring Bitmap 更好的位图压缩算法
  • RoaringBitmap数据结构以及精确去重UDAF实现
  • RoaringBitMap学习和实践
  • Roaring BitMap(高效压缩位图)
  • Roaring64Bitmap实践
  • 一文了解RoaringBitmap
  • roaringbitmap java,BitMap与RoaringBitmap、JavaEWAH
  • roaringbitmap java,数据结构-RoaringBitmap概要
  • Roaring位图具有更好的位图性能
  • Go 每日一库之 roaring
  • vue中使用图片裁切器
  • vue图片裁切cropperjs的使用
  • Cropper使用(图片裁切)
  • layui框架实战案例(8):web图片裁切插件croppers.js组件实现上传图片的自定义截取(含php后端)
  • [WPF]图片裁切功能(鼠标绘制)
  • gif图片裁切、压缩导出无水印图片(保姆级教程,亲测可用)
  • iOS开发中有关图片裁切的问题
  • img元素实现图片裁切放大
  • Android 图片裁切框架 uCrop 的用法
  • css焦点图片裁切技术
  • git 裁切_Croppic图片裁切插件中文API帮助文档
  • Mathematica图片裁切
  • php 对上传图片尺寸裁切,PHP图片自动裁切应付不同尺寸的显示
  • 使用react-cropper-pro实现图片裁切压缩上传
  • Vue 裁切图片
  • Javascript图片裁切
  • 图片裁切器Cropper.js的使用
  • git 裁切_图片裁切.html
  • Jcrop+ajaxFileUpload 图片裁切上传 oss(java web)

ClickHouse遇见RoaringBitmap相关推荐

  1. RoaringBitMap在ClickHouse和Spark之间的实践-解决数据仓库预计算多维分析问题

    ​ 前面在Spark多维分析去重计数场景优化案例中说了一下Spark计算在多维分析场景中的弊端,多维度分析会导致数据量指数级膨胀,搭配上去重计算字段越多,膨胀倍数也是线性增长,通过BitMap这个案例 ...

  2. 一文搞定ClickHouse在苏宁用户画像场景的实践(建议收藏)

    关注公众号,获取更多一线大厂最新资讯! 摘要:今天分享的主要内容是ClickHouse在苏宁用户画像场景的实践 分享时间:2021年5月26日 内容分享:杨兆辉 摘要整理:皮卡丘 主要内容: 苏宁如何 ...

  3. 苏宁6亿会员是如何做到精确快速分析的?

    " 随着苏宁业务的高速发展,大数据平台对海量的业务数据分析越来越具有挑战,尤其是在精确去重.复杂 JOIN 场景下,如用户画像.UV.新老买家.留存.流失用户等. 图片来自 Pexels 随 ...

  4. 漫谈 ClickHouse 在实时分析系统中的定位与作用

    ClickHouse 是一款由俄罗斯Yandex公司开源的OLAP数据库,拥有着卓越的性能表现,在官方公布的基准测试中,ClickHouse的平均响应速度是Vertica的2.63倍.InfiniDB ...

  5. ClickHouse留存分析工具十亿数据秒级查询方案

    作者:陈璐,腾讯 CSIG 高级数据分析师 本文实践了对于千万级别的用户,操作总数达万级别,每日几十亿操作流水的留存分析工具秒级别查询的数据构建方案.同时,除了留存分析,对于用户群分析,事件分析等也可 ...

  6. 【java】高效压缩位图RoaringBitmap的原理与应用

    文章目录 1.概述 2.位图法简述 3.RoaringBitmap的思路 4.Container原理 4.1 ArrayContainer 4.2 BitmapContainer 4.3 RunCon ...

  7. Clickhouse 在大数据分析平台 - 留存分析

    背景 你可能听说过Growingio.神策等数据分析平台,本文主要介绍实现留存分析工具相关的内容.留存分析是一种用来分析用户参与情况/活跃程度的分析模型,可考查进行初始行为后的用户中,有多少人会进行后 ...

  8. Clickhouse 专栏---数据模型之留存分析

    什么是留存,比如在20200701这天操作了"点击banner"的用户有100个,这部分用户在20200702这天操作了"点击app签到"的有20个,那么对于分 ...

  9. 唯品会翻牌ClickHouse后,实现百亿级数据自助分析

    本文根据王玉老师在[deeplus直播第266期]线上分享演讲内容整理而成.(文末有获取本期PPT&回放的方式,不要错过) 王玉 唯品会实时平台OLAP团队负责人 负责唯品会Presto.Cl ...

  10. ClickHouse 在唯品会 OLAP 系统的实践

    供稿:王新春.王玉.王康.徐其民 01 OLAP在唯品会演进迭代 1.1 Presto/Kylin在唯品会的使用 Presto作为当前唯品会OLAP主力军,经历了数次架构和使用方式演进.当前阶段,我们 ...

最新文章

  1. Django项目配合sentry实现浅析
  2. JavaScript 特有奇葩问题“字符串类型与数字类型混乱”的分析与解决,与类型转换
  3. 深入mysql ON DUPLICATE KEY UPDATE 语法的分析
  4. Android之放大镜实现的两种方式
  5. P1197-星球大战【并查集,图论】
  6. 链表中删除选定结点的优雅操作!
  7. 用tf-faster-rcnn训练自己制作的车牌号数据集(VOC2007格式)
  8. pacman吃豆人_通过Tensorflow和强化学习实现自动化吃豆人PacMan
  9. python字典类型写入文件_python 字典写入文件
  10. 数据库维护计划中出现错误,数据库无法自动备份。 错误提示:作业失败。所有者(XXX\administrator用户拥有DB维护计划“数据库备份”作业)没有服务器访问权限。
  11. 台式电脑出厂编号怎么查_出厂编号的查询方法
  12. 猫九先森教你如何优雅的玩
  13. mysql admin php_apache+php+mysql+phpadmin 服务环境搭建
  14. mysql limt取指定数据条数 top取指定数据条数
  15. 微信小程序遍历二维数组
  16. 史上最简单的rar压缩包文档解密方法,rar压缩包权限密码如何解开?
  17. 致远项目管理SPM系统案例:道道全粮油股份有限公司人力资源管理
  18. 台湾屏东大学校徽设计被指抄袭 校方:征选过程严谨
  19. cs230 deeplearning.ai 1: Standard NN
  20. VEGAS Pro 17安装汉化教程

热门文章

  1. CINTA拉格朗日定理
  2. 【历史上的今天】1 月 6 日:“互联网之子”的陨落;微软云服务先驱出生;世界上第一台 5G 笔记本
  3. 06-4. How Long Does It Take (25)拓扑排序 求关键路径的最长的长度
  4. linux tpp模式,tpp 'exec'命令任意代码执行漏洞
  5. 李智慧 - 架构师训练营 第三周
  6. 【115】StrokeIt相关操作
  7. 在命令窗中查询当前电脑IP
  8. 【转载】高光谱图像处理与信息提取综述
  9. xinput1_3.dll丢失怎么修复win10_有什么好的修复方法推荐?
  10. 清除计算机用户缓存,如何清除电脑的内存缓存?