Clickhouse表引擎介绍
- 表引擎作用
- 数据如何存储,从哪写入,从哪读取
- 支持哪些查询,以及如何支持。
- 并发数据访问
- 如果存在,使用索引
- 是否支持多线程
- 数据复制
表引擎类型
- MergeTree
- 适用于高负载,最强大的表引擎
- 同构后续的后台数据处理,快速插入数据,然后应用规则在后台合并这些部分
- 支持数据复制、分区、辅助数据跳过索引以及其他引擎不支持的其他功能
- 种类
- MergeTree
- ReplacingMergeTree
- SummingMergeTree
- AggregatingMergeTree
- CollapsingMergeTree
- VersionedCollapsingMergeTree
- GraphiteMergeTree
- Log
- 轻量级引擎,功能最少。当您需要快速编写许多小表(最多约100万行)并在以后作为一个整体读取它们时,它们是最有效的。
- 种类
- TinyLog
- StripeLog
- Log
- Integration Engines
- 与其他数据存储和处理系统通信的引擎。
- 种类
- Kafka
- MySQL
- ODBC
- JDBC
- HDFS
- S3
- Special Engines(特殊引擎,不知道如何分类,ClickHouse特有的)
- Distributed
- MaterializedView
- Dictionary
- Merge
- File
- Null
- Set
- Join
- URL
- View
- Memory
- Buffer
MergeTree系列
MergeTree家族的表引擎是ClickHouse数据存储功能的核心。它们为恢复能力和高性能数据检索提供了大多数功能:列式存储、自定义分区、稀疏主索引、辅助数据跳过索引等。
基本MergeTree表引擎可以被认为是单节点ClickHouse实例的默认表引擎,因为它对于广泛的用例来说是通用和实用的。
对于生产使用来说,ReplicatedMergeTree是一个不错的选择,因为它为常规MergeTree引擎的所有特性增加了高可用性。另一个好处是在数据摄取时自动执行重复数据消除,因此如果插入过程中出现网络问题,软件可以安全地重试。
MergeTree系列的所有其他引擎都为某些特定的用例添加了额外的功能。通常,它在后台实现为额外的数据操作。
MergeTree引擎的主要缺点是它们的重量相当重。因此,典型的模式是没有这么多。如果需要许多小表,例如临时数据,请考虑日志引擎系列。
MergeTree引擎
就相当于一个父类有最基本的那些功能,有特殊需求,可以使用它的子类:XXXMergeTree
-
支持功能
- 按照主键排序
- 如果指定了分区键,则可以使用分区
- 支持数据复制
- 支持数据采样
- 并发/索引/分区/crud
-
建表语句
INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2) ENGINE = MergeTree()ORDER BY expr[PARTITION BY expr][PRIMARY KEY expr][SAMPLE BY expr][TTL expr
[DELETE|TO DISK 'xxx'|TO VOLUME 'xxx' [, ...] ]
[WHERE conditions]
[GROUP BY key_expr [SET v1 = aggr_func(v1) [, v2 = aggr_func(v2) ...]] ] ]
[SETTINGS name=value, ...]
-
ENGINE:引擎的名称和参数.
-
ORDER BY:排序键
-
PARTITION BY:分区键
-
PRIMARY KEY—主键(如果它不同于排序键)
-
SAMPLE BY — 用于抽样的表达式。
-
TTL 指定行存储的持续时间并定义数据片段在硬盘和卷上的移动逻辑的规则列表。 DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'指定了当满足条件(到达指定时间)时所要执行的动作:移除过期的行,还是将数据片段(如果数据片段中的所有行都满足表达式的话)移动到指定的磁盘(TO DISK 'xxx') 或 卷(TO VOLUME 'xxx')
-
SETTINGS — 控制 MergeTree 行为的额外参数
- index_granularity — 索引粒度。
- index_granularity_bytes — 索引粒度,以字节为单位,默认值: 10Mb。
- enable_mixed_granularity_parts — 是否启用通过 index_granularity_bytes 控制索引粒度的大小
- use_minimalistic_part_header_in_zookeeper — 是否在 ZooKeeper 中启用最小的数据片段头
- min_merge_bytes_to_use_direct_io — 使用直接 I/O 来操作磁盘的合并操作时要求的最小数据量。
- merge_with_ttl_timeout — TTL合并频率的最小间隔时间,单位:秒。默认值: 86400 (1 天)。
- write_final_mark — 是否启用在数据片段尾部写入最终索引标记。默认值: 1(不建议更改)
- merge_max_block_size — 在块中进行合并操作时的最大行数限制。默认值:8192
- storage_policy — 存储策略。 参见 使用具有多个块的设备进行数据存储.
- min_bytes_for_wide_part,min_rows_for_wide_part 在数据片段中可以使用Wide格式进行存储的最小字节数/行数。你可以不设置、只设置一个,或全都设置。
-
例子
CREATE TABLE test.tables(
`order_id` UInt32,
`order_sn` String,
`date_added` UInt64
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(toDate(date_added))
ORDER BY order_sn
INSERT INTO test.tables
(order_id, order_sn, date_added)
VALUES(1, '11', 1608963927769);
//强制合并
optimize table test final;
//查看表的相关信息
SELECT
partition,
name,
active FROM system.parts WHERE table = 'test'
- 对应磁盘分区目录
- *.bin 各个字段二进制压缩数据
- .MRK 对应的*。bin中数据块的偏移量
- primary.idx 逐渐索引(稀疏索引:)
- checksums.txt 校验和,保证数据正确性和完整性
- cloumns.txt当前表的所有字段
- count.txt当前分区中所有数据的行数
- partition.dat 分区信息
- minmax_birthday.idx 分区最小最大数据
ReplacingMergeTree
MergeTree 的不同之处在于它会删除排序键值相同的重复项。数据的去重只会在数据合并期间进行。合并前还是可以被查到。
CollapsingMergeTree
该引擎要求在建表语句中指定一个标记列Sign,按照Sign的值将行分为两类:Sign=1的行称之为状态行,Sign=-1的行称之为取消行。再主键相同的情况下,每次需要新增状态时,写入一行状态行;需要删除状态时,则写入一行取消行。没有成对的行会被保留。 多线程情况下-1和1可能存在乱序,导致无法被删除
VersionedCollapsingMergeTree
为了解决CollapsingMergeTree乱序写入情况下无法正常折叠问题,VersionedCollapsingMergeTree表引擎在建表语句中新增了一列Version,用于在乱序情况下记录状态行与取消行的对应关系。主键相同,且Version相同、Sign相反的行,在Compaction时会被删除。
SummingMergeTree
当合并 SummingMergeTree 表的数据片段时,ClickHouse 会把所有具有相同主键的行合并为一行,并根据指定的字段进行累加。
AggregatingMergeTree
SummingMergeTree只能累加,这个能进行各种聚合,需要指定聚合函数
CREATE TABLE agg_table
( CounterID UInt8,
StartDate Date,
UserID AggregateFunction(uniq, UInt64)
) ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(StartDate)
ORDER BY (CounterID, StartDate);
Log系类
这些引擎是为了需要写入许多小数据量(少于一百万行)的表的场景而开发的。
几种Log表引擎的共性是:
- 数据被顺序append写到磁盘上;
- 不支持delete、update;
- 不支持index;
- 不支持原子性写;
- insert会阻塞select操作。
TinyLog,引擎是该系列中最简单的引擎并且提供了最少的功能和最低的性能。TinyLog 引擎不支持并行读取和并发数据访问,并将每一列存储在不同的文件中。
Log和StripLog支持并发读取。每个线程处理一个单独的数据块。Log引擎每一列使用一个单独文件,Stripe Log保存在一个文件。Log引擎相对来说更加高效
StripeLog
写入许多小数据量(小于一百万行)的表的场景下使用这个引擎。 StripeLog 引擎不支持 ALTER UPDATE 和 ALTER DELETE 操作。 select的返回顺序不可预测
Log
这些标记写在每个数据块上,并且包含偏移量,这些偏移量指示从哪里开始读取文件以便跳过指定的行数。写入操作会阻塞读取和其他写入。,不支持索引。 同样,如果写入表失败,则该表将被破坏,并且从该表读取将返回错误。Log引擎适用于临时数据,write-once 表以及测试或演示目的。
TinyLog
最简单的表引擎,用于将数据存储在磁盘上。每列都存储在单独的压缩文件中。写入时,数据将附加到文件末尾。
Integration系列
该系统表引擎主要用于将外部数据导入到ClickHouse中,或者在ClickHouse中直接操作外部数据源。
- Kafka:将Kafka Topic中的数据直接导入到ClickHouse;
- MySQL:将Mysql作为存储引擎,直接在ClickHouse中对MySQL表进行select等操作;
- JDBC/ODBC:通过指定jdbc、odbc连接串读取数据源;
- HDFS:直接读取HDFS上的特定格式的数据文件。
Special系列
Distributed Table Engine
- 分布式引擎本身不存储数据, 但可以在多个服务器上进行分布式查询。读是自动并行的
- 读取时,远程服务器表的索引(如果有的话)会被使用。
- 分布式引擎参数:服务器配置文件中的集群名,远程数据库名,远程表名,数据分片键(可选)。ENGINE =Distributed(cluster, db, table[, sharding_key])
Merge
Merge 引擎 (不要跟 MergeTree 引擎混淆) 本身不存储数据,但可用于同时从任意多个其他的表中读取数据。读是自动并行的,不支持写入。
Merge(hits, '^WatchLog')
数据会从 hits 数据库中表名匹配正则 ‘^WatchLog’ 的表中读取。
File table Engine
File表引擎以一种受支持的文件格式(TabSeparated,Native等)将数据保存在文件中。读取其他系统生成的数据文件
Null Table Engine
写入Nulltable 数据被忽略,返回值也是空
Set Table Engine
数据集永远存在RAM中,不能重复
URL Table Engine
保存http/https上面的数据,很想FIle Engine
View Table Engine
用于构建视图(有关更多信息,请参阅 CREATE VIEW 查询)。 它不存储数据,仅存储指定的 SELECT 查询。
Memory Table Engine
Memory 引擎以未压缩的形式将数据存储在 RAM 中。数据完全以读取时获得的形式存储。读写操作不会相互阻塞。不支持索引。查询是并行化的。在简单查询上达到最大速率(超过10 GB /秒),因为没有磁盘读取,不需要解压缩或反序列化数据。重新启动服务器时,表中的数据消失,表将变为空。
Buffer Table Engine
缓冲数据写入 RAM 中,周期性地将数据刷新到另一个表。在读取操作时,同时从缓冲区和另一个表读取数据。
Clickhouse数据库引擎
默认使用Atomic数据库引擎
- MySQL
- MaterializeMySQL
- Lazy
- Atomic
- PostgreSQL
MySQL
MySQL引擎用于将远程的MySQL服务器中的表映射到ClickHouse中,并允许您对表进行INSERT和SELECT查询,以方便您在ClickHouse与MySQL之间进行数据交换。
无法做的
- RENAME
- CREATE TABLE
- ALTER
MaterializeMySQL
将MySQL服务器中的表映射到ClickHouse中,将ClickHouse服务看作MySQL副本,它读取Binlog并执行DDL和DML请求。实现了基于MySQL Binlog机制的业务数据库实时同步功能。
CREATE DATABASE mysql ENGINE = MaterializeMySQL('localhost:3306', 'db', 'user', '***');
SHOW TABLES FROM mysql;
Lazy
最后一次访问的多少秒内,将数据保存在内存中,只能和Log表一起使用
CREATE DATABASE testlazy ENGINE = Lazy(expiration_time_in_seconds);
Atomic
它支持非阻塞DROP和RENAME TABLE查询以及原子交换表t1和t2查询。 默认情况下使用原子数据库引擎。
CREATE DATABASE test ENGINE = Atomic;
PostgreSQL
支持连接远程PostgreSQL数据库,并提供读写操作
CREATE DATABASE test_database
ENGINE = PostgreSQL('postgres1:5432', 'test_database', 'postgres', 'mysecretpassword', 1);
参考资料 官网