写点什么

Kylin、Druid、ClickHouse 核心技术对比

  • 2020-08-28
  • 本文字数:2411 字

    阅读完需:约 8 分钟

Kylin、Druid、ClickHouse核心技术对比

导读: Kylin、Druid、ClickHouse 是目前主流的 OLAP 引擎,本文尝试从数据模型和索引结构两个角度,分析这几个引擎的核心技术,并做简单对比。在阅读本文之前希望能对 Kylin、Druid、ClickHouse 有所理解。

01 Kylin 数据模型

Kylin 的数据模型本质上是将二维表(Hive 表)转换为 Cube,然后将 Cube 存储到 HBase 表中,也就是两次转换。


第一次转换,其实就是传统数据库的 Cube 化,Cube 由 CuboId 组成,下图每个节点都被称为一个 CuboId,CuboId 表示固定列的数据数据集合,比如“ AB” 两个维度组成的 CuboId 的数据集合等价于以下 SQL 的数据集合:


select A, B, sum(M), sum(N) from table group by A, B
复制代码



第二次转换,是将 Cube 中的数据存储到 HBase 中,转换的时候 CuboId 和维度信息序列化到 rowkey,度量列组成列簇。在转换的时候数据进行了预聚合。下图展示了 Cube 数据在 HBase 中的存储方式。


02 Kylin 索引结构

因为 Kylin 将数据存储到 HBase 中,所以 kylin 的数据索引就是 HBase 的索引。HBase 的索引是简化版本的 B+树,相比于 B+树,HFile 没有对数据文件的更新操作。


HFile 的索引是按照 rowkey 排序的聚簇索引,索引树一般为二层或者三层,索引节点比 MySQL 的 B+树大,默认是 64KB。数据查找的时候通过树形结构定位到节点,节点内部数据是按照 rowkey 有序的,可以通过二分查找快速定位到目标。



Kylin 小结:适用于聚合查询场景;因为数据预聚合,Kylin 可以说是最快的查询引擎(group-by 查询这样的复杂查询,可能只需要扫描 1 条数据);kylin 查询效率取决于是否命中 CuboId,查询波动较大;HBase 索引有点类似 MySQL 中的联合索引,维度在 rowkey 中的排序和查询维度组合对查询效率影响巨大;所以 Kylin 建表需要业务专家参与。

03 Druid 数据模型

Druid 数据模型比较简单,它将数据进行预聚合,只不过预聚合的方式与 Kylin 不同,kylin 是 Cube 化,Druid 的预聚合方式是将所有维度进行 Group-by,可以参考下图:


04 Druid 索引结构

Druid 索引结构使用自定义的数据结构,整体上它是一种列式存储结构,每个列独立一个逻辑文件(实际上是一个物理文件,在物理文件内部标记了每个列的 start 和 offset)。对于维度列设计了索引,它的索引以 Bitmap 为核心。下图为“city”列的索引结构:



首先将该列所有的唯一值排序,并生成一个字典,然后对于每个唯一值生成一个 Bitmap,Bitmap 的长度为数据集的总行数,每个 bit 代表对应的行的数据是否是该值。Bitmap 的下标位置和行号是一一对应的,所以可以定位到度量列,Bitmap 可以说是反向索引。同时数据结构中保留了字典编码后的所有列值,其为正向的索引。


那么查询如何使用索引呢?以以下查询为例:


select site, sum(pv) from xx where date=2020-01-01 and city='bj' group by site
复制代码


  1. city 列中二分查找 dictionary 并找到’bj’对应的 bitmap

  2. 遍历 city 列,对于每一个字典值对应的 bitmap 与’bj’的 bitmap 做与操作

  3. 每个相与后的 bitmap 即为 city='bj’查询条件下的 site 的一个 group 的 pv 的索引

  4. 通过索引在 pv 列中查找到相应的行,并做 agg

  5. 后续计算


Druid 小结:Druid 适用于聚合查询场景但是不适合有超高基维度的场景;存储全维度 group-by 后的数据,相当于只存储了 KYLIN Cube 的 Base-CuboID;每个维度都有创建索引,所以每个查询都很快,并且没有类似 KYLIN 的巨大的查询效率波动。

05 ClickHouse 索引结构 (只讨论 MergeTree 引擎)

因为 Clickhouse 数据模型就是普通二维表,这里不做介绍,只讨论索引结构。整体上 Clickhouse 的索引也是列式索引结构,每个列一个文件。Clickhouse 索引的大致思路是:首先选取部分列作为索引列,整个数据文件的数据按照索引列有序,这点类似 MySQL 的联合索引;其次将排序后的数据每隔 8192 行选取出一行,记录其索引值和序号,注意这里的序号不是行号,序号是从零开始并递增的,Clickhouse 中序号被称作 Mark’s number;然后对于每个列(索引列和非索引列),记录 Mark’s number 与对应行的数据的 offset。


下图中以一个二维表(date, city, action)为例介绍了整个索引结构,其中(date,city)是索引列。



那么查询如何使用索引呢?以以下查询为例:


select count(distinct action) where date=toDate(2020-01-01) and city=’bj’
复制代码


  1. 二分查找 primary.idx 并找到对应的 mark’s number 集合(即数据 block 集合)

  2. 在上一步骤中的 block 中,在 date 和 city 列中查找对应的值的行号集合,并做交集,确认行号集合

  3. 将行号转换为 mark’s number 和 offset in block(注意这里的 offset 以行为单位而不是 byte)

  4. 在 action 列中,根据 mark’s number 和.mark 文件确认数据 block 在 bin 文件中的 offset,然后根据 offset in block 定位到具体的列值。

  5. 后续计算


该实例中包含了对于列的正反两个方向的查找过程。反向:查找 date=toDate(2020-01-01) and city=’bj’数据的行号;正向:根据行号查找 action 列的值。对于反向查找,只有在查找条件匹配最左前缀的时候,才能剪枝掉大量数据,其它时候并不高效。


Clickhouse 小结:MergeTree Family 作为主要引擎系列,其中包含适合明细数据的场景和适合聚合数据的场景;Clickhouse 的索引有点类似 MySQL 的联合索引,当查询前缀元组能命中的时候效率最高,可是一旦不能命中,几乎会扫描整个表,效率波动巨大;所以建表需要业务专家,这一点跟 kylin 类似。

06 小结

  • Kylin、Druid 只适合聚合场景,ClickHouse 适合明细和聚合场景

  • 聚合场景,查询效率排序:Kylin > Druid > ClickHouse

  • Kylin、ClickHouse 建表都需要业务专家参与

  • Kylin、ClickHouse 查询效率都可能产生巨大差异

  • ClickHouse 在向量化方面做得的最好,Druid 少量算子支持向量化、Kylin 目前还不支持向量化计算。


今天的分享就到这里,谢谢大家。


作者介绍


吴建超,9 年程序员一枚,目前专注于大数据处理和数据库技术。


本文来自 DataFunTalk


原文链接


Kylin、Druid、ClickHouse核心技术对比


2020-08-28 14:068261

评论 3 条评论

发布
用户头像
"遍历 city 列,对于每一个字典值对应的 bitmap 与’bj’的 bitmap 做与操作 "
这里应该是
"遍历 site 列"吧
2021-01-25 20:00
回复
用户头像
2020-09-24 16:29
回复
用户头像
这个文章短小精悍,对于这三个OLAP引擎核心讲的很到位,赞一个
2020-09-04 18:39
回复
没有更多了
发现更多内容

新书上市 | Vue 3.0 核心源码解析,这本书给Vue学习提供新方法

图灵教育

前端 代码 VUE 3.0 源码

双活数据建设方案

阿泽🧸

双活 9月月更

【Meetup预告】OpenMLDB+37手游:一键查收实时特征计算场景案例及进阶使用攻略

第四范式开发者社区

机器学习 数据库 实时计算 特征平台 特征工程

网络入侵检测系统之Snort(三)--优劣势与性能指标

于顾而言

网络安全

2022-09-17:一个字符串s,表示仓库的墙 与 货物,其中‘|‘表示墙,‘*‘表示货物。 给定一个起始下标start和一个终止下标end, 找出子串中 被墙包裹的货物 数量。 比如: s = “

福大大架构师每日一题

算法 福大大

网络入侵检测系统之Suricata(六)--规则加载模块代码详解

于顾而言

网络安全 suricata

每日算法刷题Day12-跳台阶、排列、替换空格、求n累加

timerring

算法题 9月月更

网络入侵检测系统之Snort(二)--数据流图与环境搭建

于顾而言

网络安全 ips

网络入侵检测系统之Snort(一)--snort概览

于顾而言

网络安全 ips

【云原生 | 从零开始学Docker】六、如何写出自己的镜像——Docker file

泡泡

Docker 云计算 容器 云原生 9月月更

网络入侵检测系统之Suricata(一)--概览

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(二)--运行模式及数据流图

于顾而言

网络安全 suricata

jquery入门到实战

楠羽

笔记 JQuery框架 9月月更

计算机网络——奈式准则

StackOverflow

编程 计算机网络 9月月更

图库

武师叔

【指针内功修炼】深度剖析指针笔试题(三)

Albert Edison

C语言 9月月更 指针数组 数组指针

网络入侵检测系统之Suricata(五)--Worker Model线程调度详解详解

于顾而言

网络安全 suricata

二叉树的概念及三种遍历方法(C语言)

孤衫

后端 C语言 9月月更

DPDK源码分析之网络基础知识

于顾而言

网络协议 DPDK

网络入侵检测系统之Suricata(七)--DDOS流量检测模型

于顾而言

网络安全 suricata

资本“呼唤”:走产品化路线,找得到PMF的云安全创业项目

B Impact

To B业务

NFTScan 正式发布 PlatON 网络 NFT 浏览器

NFT Research

NFT platon

网络入侵检测系统之Suricata(四)--初始化模块代码详解

于顾而言

网络安全 suricata

[Maven进阶]多环境配置与应用

十八岁讨厌编程

maven 后端开发 9月月更

TO B的本质是“定制化”不变,“定制化”实现方式求变

B Impact

TO B

新书上市 | Vue 3.0 核心源码解析,这本书给 Vue 学习提供新方法

图灵社区

前端 代码 VUE 3.0 源码

企业容器云建设及推广的一点Tips

穿过生命散发芬芳

容器云 9月月更

网络入侵检测系统之Suricata(三)--日志代码详解

于顾而言

网络安全 suricata

流计算中的Windows计算

孤衫

大数据 流计算 9月月更

DPDK源码分析之l2fwd

于顾而言

DPDK

【云原生 | 从零开始学Docker】七丶实战提交自己的镜像以及docker网络

泡泡

Docker 云计算 容器 云原生 9月月更

  • 扫码加入 InfoQ 开发者交流群
Kylin、Druid、ClickHouse核心技术对比_大数据_DataFunTalk_InfoQ精选文章