1. 主页
  2. 大数据技术
  3. 十五、ClickHouse
  4. 6. ClickHouse 系列表引擎

6. ClickHouse 系列表引擎

一、Log 系列引擎

Log 家族具有最小功能的轻量级引擎。当您需要快速写入许多小表(最多约 100w 行)并在以后整体读取它们时,该类型的引擎是最有效的。

1. TinyLog 引擎

  • 将数据存储在磁盘上,没有索引,没有标记块
  • 每列都存储在单独的压缩文件中
  • 数据写入时追加写到文件末尾
  • 该引擎没有并发控制,不允许同时读写

2. StrpeLog 引擎(数据分块列在一起)

3. Log 引擎(数据分块记录偏移量)

  • *.bin 存储每个字段的数据
  • mark.mrk 数据块标记
  • 支持多线程处理
  • 并发读写

二、MergeTree 系列表引擎

MergeTree 系列的表引擎支持主键索引、数据分区、数据副本和数据采样这些特性,同时也只有此系列的表引擎支持 ALTER 相关操作

特点:

  • 存储按主键排序的数据
  • 如果指定了分区键,则可以使用分区
  • 数据复制支持:ReplacedMergeTree 表族提供数据复制。
  • 数据采样支持

1. MergeTree

CREATE TABLE tb_merge_tree(
    id Int8 ,
    name String ,
    ctime Date
)ENGINE=MergeTree()
PARTITION BY name  --选填,如果不声明分区键,则 ClickHouse 会生成一个名为 all 的分区。
ORDER BY id --必填,默认情况下主键(PRIMARY KEY)与排序键相
PRIMARY id --选填,主键字段生成一级索引,主键允许存在重复数据
SAMPLE BY intHash32(id) --选填,用于声明数据以何种标准进行采样
SETTINGS index_granularity = 8192,  --选填,索引的粒度
index_granularity_bytes  = 0, --自适应间隔大小,根据每一批次写入数据的体量大小,动态划分间隔大小。0表示不启动自适应功能。
enable_mixed_granularity_parts = true, --选填,是否开启自适应索引间隔的功能,默认开启
merge_with_ttl_timeout = 10, --选填,数据TTL功能
storage_policy = 1; --选填,多路径存储策略

clickhouse-partiton-table-merge
分区表-相同分区的表被合并到一起,过段时间以后 CK 内部自动的会删除合并前的多余的文件夹

MergeTree 存储结构

MergeTree 表引擎中的数据是拥有物理存储的,数据会按照分区目录的形式保存到磁盘上。
clickhouse-mergetree-storage-structure

一张数据表的完整物理结构分为 3 个层级,依次是数据表目录、分区目录及各分区下具体的数据文件。

  • checksums.txt:校验文件,使用二进制格式存储。用于快速校验文件的完整性和正确性。
  • columns.txt:列信息文件,使用明文格式存储。用于保存次数据分区下的列字段信息。
  • count.txt:计数文件,使用明文格式存储。用于记录当前数据分区目录下的总行数。
  • primary.idx:一级索引文件,使用二进制格式存储,用于存放稀疏索引,一张 MergeTree 表只能声明一次稀疏索引(通过 order by 或 primary key)
  • [column].bin:数据文件,使用压缩格式存储,默认为 LZ4 压缩格式,用于存储某一列的数据,每一个列字段都拥有独立的 .bin 数据文件,并以列字段名称命名(如 CounterID.bin)
  • [column].mrk:列字段标记文件,使用二进制格式存储,标记文件中保存了 .bin 文件中数据的偏移量信息。标记文件与稀疏索引对齐,又与 .bin 文件一一对应,所以 MergeTree 通过标记文件建立了 primary.idx 稀疏索引与.bin数据文件之间的映射关系
  • [column].mrk2:如果使用了自适应大小的索引间隔,则标记文件会以 .mrk2 命名。它的工作原理和作用与 .mrk 标记文件相同。
  • partition.dat 与 minmax_[Column].idx:如果使用了分区键,则会额外生成 partition.dat 与 minmax 索引文件,它们均使用二进制格式存储。partition.dat 用于保存当前分区下分区表达式最终生成的值;而 minmax 索引用于记录当前分区下分区字段对应原始数据的最小和最大值。

新版本略有不同,如下:

clickhouse-mergetree-storage-structure-new-version

2. ReplacingMergeTree

CREATE TABLE test_replacingMergeTree_version
(
    id Int8 ,
    name String ,
    city String,
    version Int8
)ENGINE = ReplacingMergeTree(version)
ORDER BY name
PARTITION BY city;

使用场景:适用于在后台清除重复的数据行以节省空间,但是它不保证没有重复的数据出现。

  • (1)使用order by排序键作为判断重复数据的唯一依据
  • (2)只有在合并分区的时候才会触发删除重复数据的逻辑,分区合并在未知时间的后台进行。
  • (3)当分区合并时,同一分区内的重复数据会被删除;不同分区之间的重复数据不会被删除。
  • (4)在进行数据去重时,因为分区内的数据已经基于ORBER BY进行了排序,所以能够找到那些相邻的重复数据。
  • (5)数据去重策略有两种

如果没有设置 version 版本号,则保留同一组重复数据的最后一行
如果设置了 version 版本号,则保留同一组重复数据中版本取值最大的一行。

3. CollapsingMergeTree

CREATE TABLE tb_cps_merge_tree
(
    user_id UInt64,
    name String,
    age UInt8,
    sign Int8
)ENGINE = CollapsingMergeTree(sign)
ORDER BY user_id;

CollapsingMergeTree 是一种通过以增代删的思路,支持行级数据修改和删除的表引擎。

通过定义一个 sign 标记位字段,记录数据行的状态。如果 sign 标记为1,则表示这是一行有效的数据;如果 sign 标记为 -1,则表示这行数据需要被删除。当 CollapsingMergeTree 分区合并时,同一数据分区内,sign 标记为 1 和 -1 的一组数据会被抵消删除。

注意:CollapsingMergeTree 虽然解决了主键相同的数据即时删除的问题,但是状态持续变化且多线程并行写入情况下,状态行与取消行位置可能乱序,导致无法正常折叠。只有保证老的状态行在在取消行的上面, 新的状态行在取消行的下面! 但是多线程无法保证写的顺序!

4. VersionedCollapsingMergeTree

CREATE TABLE tb_vercps_merge_tree
(
    uid UInt64,
    name String,
    age UInt8,
    sign Int8,
    version UInt8
)ENGINE = VersionedCollapsingMergeTree(sign, version)
ORDER BY uid;

INSERT INTO tb_vercps_merge_tree VALUES (1001, 'ADA', 18, -1, 1);

INSERT INTO tb_vercps_merge_tree VALUES (1001, 'ADA', 18, 1, 1),
                                        (101, 'DAD', 19, 1, 2),
                                        (101, 'DAD', 11, 1, 3);

OPTIMIZE TABLE tb_vercps_merge_tree;
SELECT * FROM tb_vercps_merge_tree;

解决 CollapsingMergeTree 乱序写入情况下无法正常删除(折叠)问题,在建表语句中新增了一列 version,用于在乱序情况下记录状态行与取消行的对应关系

主键(排序)相同,且 version 相同,sign 相反的行,在合并时会被删除。

5. SummingMergeTree

只需要查询汇总结果,不关心明细数据。并且数据的汇总条件是预先明确的(group by 条件明确,不会随意改变)

6. AggregatingMergeTree

通过定义 AggregateFunction(聚合函数,数据类型)决定针对哪些列字段计算。

写入时需要使用 -state 语法,查询时使用 -merge 语法。

三、外部存储引擎

1. HDFS 引擎

clickhouse 可以直接从 HDFS 中指定的目录下加载数据,自己不存储数据,仅仅读取数据

engine=HDFS('hdfs://linux01:8020/ck/test/*','csv')
-clickhouse支持的文件格式有CSV、TSV、JSON等

2. MySQL 引擎

engine=MYSQL('localhost:3306','test','test','root','123456')

3. File 引擎

四、内部引擎

1. Memotry

2. Set

3. Buffer

参考