Clickhouse 入门

一、OLTP 与 OLAP

概念

联机事务处理 OLTP(On-line Transaction Processing) 是传统关系型数据库的主要应用,用来执行一些基本的、日常的事务处理。比如数据库记录的增、删、改、查等。

联机分析处理 OLAP(On-line Analytical Processing) 是在基于数据仓库多维模型的基础上实现的面向分析的各类操作的集合。

对比

数据处理类型 OLTP OLAP
面向对象   业务开发人员   分析决策人员 
 功能实现   日常事务处理   面向分析决策 
 数据模型   关系模型   多维模型 
 DB 设计   面向应用   面向主题 
 数据量   几条或几十、几百条记录   千万上亿条记录 

OLTP 与 OLAP 操作对比

OLTP 操作:增加、删除、修改、查看

OLAP 操作:钻取(Drill-down)、上卷(Roll-up)、切片(Slice)、切块(Dice)以及旋转(Pivot)

OLAP 操作图解

原始数据立方

8bfcd583dde24294bb0d075671d4c9a7_41706f6577ed42de89a1ce7e68f4c1dc.png

操作图解

d817840813f443afa9a0fb5905ba9430_47b21bde41e1422cab51f3e9eebff4e8.png

说明

  钻取(Drill-down) :在维的不同层次间的变化,从上层降到下一层,或者说是将汇总数据拆分到更细节的数据,比如通过对 2010 年第二季度的总销售数据进行钻取来查看 2010 年第二季度 4、5、6 每个月的消费数据,如上图;当然也可以钻取浙江省来查看杭州市、宁波市、温州市……这些城市的销售数据。

  上卷(Roll-up):钻取的逆操作,即从细粒度数据向高层的聚合,如将江苏省、上海市和浙江省的销售数据进行汇总来查看江浙沪地区的销售数据,如上图。

  切片(Slice):选择维中特定的值进行分析,比如只选择电子产品的销售数据,或者 2010 年第二季度的数据。

  切块(Dice):选择维中特定区间的数据或者某批特定值进行分析,比如选择 2010 年第一季度到 2010 年第二季度的销售数据,或者是电子产品和日用品的销售数据。

  旋转(Pivot):即维的位置的互换,就像是二维表的行列转换,如图中通过旋转实现产品维和地域维的互换。

二、列式数据库

概念

列式存储 (Column-based) 是相对于行式存储来说的,新兴的 Hbase、HP Vertica、EMC Greenplum 等分布式数据库均采用列式存储。在基于列式存储的数据库中, 数据是按照列为基础逻辑存储单元进行存储的,一列中的数据在存储介质中以连续存储形式存在。

列式数据库与行式数据库

cfbc5ce6d3d24809b93a60c485849f5d_931c3a33d9484942a12b21fbdfe3da79.png

列式数据库更适合 OLAP 场景的原因

OLAP 场景的关键特征

  • 大多数是读请求
  • 数据总是以相当大的批 (> 1000 rows) 进行写入
  • 不修改已添加的数据
  • 每次查询都从数据库中读取大量的行,但是同时又仅需要少量的列
  • 宽表,即每个表包含着大量的列
  • 较少的查询 (通常每台服务器每秒数百个查询或更少)
  • 对于简单查询,允许延迟大约 50 毫秒
  • 列中的数据相对较小: 数字和短字符串 (例如,每个 URL 60 个字节)
  • 处理单个查询时需要高吞吐量(每个服务器每秒高达数十亿行)
  • 事务不是必须的
  • 对数据一致性要求低
  • 每一个查询除了一个大表外都很小
  • 查询结果明显小于源数据,换句话说,数据被过滤或聚合后能够被盛放在单台服务器的内存中

行式

2828f6fe4a5c436bb74d1f032c9bcdae_row_oriented.gif

列式

d4369d61a4fe45e8a912bf8557b8b16e_column_oriented.gif

Input/output

1. 针对分析类查询,通常只需要读取表的一小部分列。在列式数据库中你可以只读取你需要的数据。例如,如果只需要读取 100 列中的 5 列,这将帮助你最少减少 20 倍的 I/O 消耗。

2. 由于数据总是打包成批量读取的,所以压缩是非常容易的。同时数据按列分别存储这也更容易压缩。这进一步降低了 I/O 的体积。

3. 由于 I/O 的降低,这将帮助更多的数据被系统缓存。

CPU

由于执行一个查询需要处理大量的行,因此在整个向量上执行所有操作将比在每一行上执行所有操作更加高效。同时这将有助于实现一个几乎没有调用成本的查询引擎。如果你不这样做,使用任何一个机械硬盘,查询引擎都不可避免的停止 CPU 进行等待。所以,在数据按列存储并且按列执行是很有意义的。

有两种方法可以做到这一点:

1. 向量引擎:所有的操作都是为向量而不是为单个值编写的。这意味着多个操作之间的不再需要频繁的调用,并且调用的成本基本可以忽略不计。操作代码包含一个优化的内部循环。

2. 代码生成:生成一段代码,包含查询中的所有操作。

三、Clickhouse 演化过程

《Yandex.Metrica 中数据结构的演变》

《彪悍开源的分析数据库 -ClickHouse》

四、为什么 Clickhouse 在 OLAP 业务中性能出众

MergeTree

LSM-Tree(The Log-Structured Merge-Tree)

下边这个图是 LevelDB 的架构,首先,LSM-tree 被分成三种文件,第一种是内存中的两个 memtable,一个是正常的接收写入请求的 memtable,一个是不可修改的 immutable memtable。

0a5304c103354576b37ed52aac181554_64c470beca5042fdb1b588c28e8e2b17.png

MergeTree — 写

  • 类似 LSM Tree,但是没有内存表,不记录 log 

  • 直接落磁盘,按照主键排序,分块写入

  • 异步 merge,与写不冲突                                           

  • 不支持删除、修改                                         

  • primary.idx+.bin+.mrk2+checksums.txt+columns.txt 

MergeTree — 读  

  • 主键查询:每 8192 行,抽取一行数据形成稀疏索引(默认值为 8192)

  • 非主键查询:向量化操作

目录结构

示例表结构
2134868848964c64b0d3296c744b6fe5_7466523b02b6454e8751ecc3520dc9d2.png

某一分区目录结构
84cb327366474e2d91273b5e1f5ab9ce_361f2c18fc5946dabd76b80ad47fb1c9.png

clickhouse 针对每一列都进行了分别存储,并生成了.bin 以及.mrk 两个文件:

bin 文件存储了真正的列的值(内部又设计列的压缩);

mrk2 文件记录了 Mark numbers(block)对应这个列的 offset。

primary.idx 文件存储了主键。
f8a69f37d89d4f1e99593368ddda9ea9_1073c863610149b696e4dc88fa4ecf80.png

columns.txt 文件记录了该表的全部列名及其类型。

存储示例

主键为:CounterID,Date

bb6d713f79e04a28853368c10ba42c9a_ff75b80ac6fe4584b242e457299ce58b.png

稀疏索引

在 Clickhouse 中,按照主键对数据进行排序,这将帮助其在几十毫秒以内完成对数据特定值或范围的查找。借助稀疏索引,可以存储更多的索引在内存中。
c55603b2bfc944189dd5cc369b1f8883_be3d8eab5405488aac2a3d5e18a1160d.png

查询逻辑

1. 并非使用 BTree 点对点查找,稀疏索引,肯定存在大量无用数据过滤

2. 向量化操作

a69aae87e2744301bb51e0138b6116af_174b87b9cbf4428a9cf748fbec94d225.png

索引分析

61e281df7240459eb55509341fea3f04_d6833b3562bc4ae481834d5499144ce1.png

索引建议

9d98b62634e549428c8234f87b5ef189_a1e418b62c2f449e850bf82f409387d2.png

26e31dc74abb49e6aebe529a5b0650cd_7b0cb6fd609c419193a88d353d1082c8.png

数据压缩

在一些列式数据库管理系统中 (例如:InfiniDB CE 和 MonetDB) 并没有使用数据压缩。但是, 若想达到比较优异的性能,数据压缩确实起到了至关重要的作用。

ClickHouse 提出了两种压缩方法:LZ4 和 ZSTD,因此您可以选择适合您的情况,硬件设置和工作负载的压缩方法。

  • 在具有大范围扫描的查询的瓶颈是 I / O 时,最好使用 ZSTD(ZSTD 压缩比率高)。

  • 当 I / O 足够快时,可以选择 LZ4,此时解压缩速度成为瓶颈(LZ4 解压速度快)。

  • 对于超快磁盘子系统(例如 SSD NVMe 阵列),即使 LZ4 也会变慢,因此 ClickHouse 可以选择指定“无”压缩。

扩展

列式数据库主要的压缩算法有三种:

1. 游程编码算法 (Run length Encoding)

2. 词典编码算法 (Dictionary Encoding)

3. 位向量算法 (Bit-Vector Encoding)

位向量应用扩展阅读:《快手 HBase 在千亿级用户特征数据分析中的应用与实践》

向量引擎(A vector engine)

向量化查询执行更容易利用 CPU 的 SIMD 功能。

SIMD:单指令多数据流,对于计算密集型程序来说,可能经常会需要对大量不同的数据进行同样的运算。SIMD 引入之前,执行流程为同样的指令重复执行,每次取一条数据进行运算。例如有 8 个 32 位整形数据都需要进行移位运行,则由一条对 32 位整形数据进行移位的指令重复执行 8 次完成。SIMD 引入了一组大容量的寄存器,一个寄存器包含 832 位,可以将这 8 个数据按次序同时放到一个寄存器。同时,CPU 新增了处理这种 832 位寄存器的指令,可以在一个指令周期内完成 8 个数据的位移运算。

牺牲事务

五、Clickhouse 的 UPDATE 与 DELETE

突变

ClickHouse 团队将 Clickhouse 的 UPDATE 与 DELETE 命名为“突变”,原因是:每次更新 / 删除后,数据都会发生显着变化(突变)。

突变(Mutations)是一种 ALTER 查询变体,它允许更改或删除表中的行。与用于点数据更改的标准查询 UPDATE 和 DELETE 查询相比,突变用于更改表中许多行的繁重操作。

ALTER TABLE <table_name> DELETE WHERE <filter>;

ALTER TABLE <table_name> UPDATE col1 = expr1, ... WHERE <filter>;

限制

更新索引列

索引列不可更新。

:) ALTER TABLE test_update UPDATE event_key = 41 WHERE event_key = 40;

Received exception from server (version 18.12.17):

Code: 420. DB::Exception: Received from localhost:9000, ::1. DB::Exception: Cannot UPDATE key column `event_key`.

分布式表更新

对分布式表的更新不起作用。如果您尝试更新分布式表,则可能会得到类似以下内容的信息:

Received exception from server (version 18.12.17):

Code: 48. DB::Exception: Received from localhost:9000, ::1. DB::Exception: Mutations are not supported by storage Distributed.

频繁的点数据更新

Clickhouse 删除修改的主要用例是罕见的批量操作,因为它需要大量资源消耗的后台工作。像在 OLTP 数据库中一样,将其用于点(单行)更新不是一个好主意。

六、Clickhouse 的“不足”

1. 没有完整的事务支持。

2. 缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合 GDPR(注:《通用数据保护条例》(General Data Protection Regulation,简称 GDPR))。

3. 稀疏索引使得 ClickHouse 不适合通过其键检索单行的点查询。

参考资料

1. OLTP

2. OLAP

3. 数据立方体与 OLAP

4. OLAP 技术应用——位运算原理及应用

5. Clickhouse 官方文档

6. “行式存储”和“列式存储”的区别

7. 列式数据库和向量化

8. 彪悍开源的分析数据库 -ClickHouse

9. [Yandex.Metrica 中数据结构的演变

10. Compression in ClickHouse

11. LSM-tree 基本原理及应用

12. ClickHouse 使用

13. ClickHouse Primary Keys

14. 数据分析领域的黑马 -ClickHouse

15. Updates and Deletes in ClickHouse

16. 快手 HBase 在千亿级用户特征数据分析中的应用与实践

17. 列式数据库压缩算法

18. 向量化与编译执行浅析