Log引擎是为了需要写入许多小数据量(少于一百万行)的表的场景而开发的。面对的数据查询场景也比较简单,并且往往是一次写入多次查询,则日志家族系列的表引擎将会是一种不错的选择。
共同点
数据存储在磁盘上,如果是linux系统使用的是直接IO。
写入时将数据追加在文件末尾。
不支持突变操作也就是不支持update和delete操作。
不支持索引。
这意味着 SELECT
在范围查询时效率不高。
非原子地写入数据。
如果某些事情破坏了写操作,例如服务器的异常关闭,你将会得到一张包含了损坏数据的表。
差异化
Log 和 StripeLog 引擎支持
并发访问数据的锁。
INSERT
请求执行过程中表会被锁定,并且其他的读写数据的请求都会等待直到锁定被解除。如果没有写数据的请求,任意数量的读请求都可以并发执行。
并行读取数据。
在读取数据时,ClickHouse 使用多线程。每个线程处理不同的数据块。
性能由低到高:TinyLog-- >StripeLog --> Log
总结
TinyLog:不支持并发读取数据文件,查询性能较差;格式简单,适合用来暂存中间数据。
StripLog:支持并发读取数据文件,查询性能比TinyLog好;将所有列存储在同一个大文件中,减少了文件个数。
Log:支持并发读取数据文件,查询性能比TinyLog好;每个列会单独存储在一个独立文件中。
Log 引擎
#创建测试库、表
CREATE DATABASE test;
use test;
create table tb_test_Log(`id` Int64,`vipId` Int64,`brandId` Int32,`shopId` Int32, `saleDate` Datetime64,saleMoney Float32) engine = Log;
#查看表目录,但表目录是空的
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/
total 0
drwxr-x---. 2 clickhouse clickhouse 6 Mar 18 15:52 tb_test_Log
drwxr-x---. 2 clickhouse clickhouse 57 Mar 18 15:47 tb_test_StripeLog
drwxr-x---. 2 clickhouse clickhouse 133 Mar 18 15:38 tb_test_TinyLog
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_Log/
total 0
#插入数据
insert into tb_test_Log values (10001,8001,429,6001,'2020-10-01 14:15:23',200.50);
SELECT *
FROM tb_test_Log
┌────id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 10001 │ 8001 │ 429 │ 6001 │ 2020-10-01 14:15:23.000 │ 200.5 │
└───────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_Log/
total 32
-rw-r-----. 1 clickhouse clickhouse 30 Mar 18 15:54 brandId.bin
-rw-r-----. 1 clickhouse clickhouse 34 Mar 18 15:54 id.bin
-rw-r-----. 1 clickhouse clickhouse 96 Mar 18 15:54 __marks.mrk
-rw-r-----. 1 clickhouse clickhouse 34 Mar 18 15:54 saleDate.bin
-rw-r-----. 1 clickhouse clickhouse 30 Mar 18 15:54 saleMoney.bin
-rw-r-----. 1 clickhouse clickhouse 30 Mar 18 15:54 shopId.bin
-rw-r-----. 1 clickhouse clickhouse 217 Mar 18 15:54 sizes.json
-rw-r-----. 1 clickhouse clickhouse 34 Mar 18 15:54 vipId.bin
Log表引擎是日志家族系列中性能最高的表引擎。
Log表引擎的存储结构由三部分组成:
[Columns].bin数据文件,数据文件按照列独立存储,每个列字段都拥有一个与之对应的bin文件。
_marks.mrk :数据标记文件,统一保存了数据在各个[column].bin文件中的位置信息,利用数据标记能使用多个线程,以并行的方式读取bin文件内的压缩数据块,从而提高数据查询的性能。
size.json:元数据文件,记录了[column].bin和_marks.mrk大小的信息。
Log拥有了数据标记和各个列数据独立存储的功能,则可以支持并行查询和按照列读取数据,但是也需要更多的文件描述符,相对于StripeLog。
insert into tb_test_Log values (10002,8002,429,6001,'2020-10-02 14:15:23',300.50),(10003,8001,429,6001,'2020-10-02 14:15:23',100.50);
select * from tb_test_Log;
┌────id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 10002 │ 8002 │ 429 │ 6001 │ 2020-10-02 14:15:23.000 │ 300.5 │
│ 10003 │ 8001 │ 429 │ 6001 │ 2020-10-02 14:15:23.000 │ 100.5 │
└───────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
┌────id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 10001 │ 8001 │ 429 │ 6001 │ 2020-10-01 14:15:23.000 │ 200.5 │
└───────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
```sql
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_Log/
total 32
-rw-r-----. 1 clickhouse clickhouse 64 Mar 18 15:58 brandId.bin
-rw-r-----. 1 clickhouse clickhouse 74 Mar 18 15:58 id.bin
-rw-r-----. 1 clickhouse clickhouse 192 Mar 18 15:58 __marks.mrk
-rw-r-----. 1 clickhouse clickhouse 77 Mar 18 15:58 saleDate.bin
-rw-r-----. 1 clickhouse clickhouse 64 Mar 18 15:58 saleMoney.bin
-rw-r-----. 1 clickhouse clickhouse 64 Mar 18 15:58 shopId.bin
-rw-r-----. 1 clickhouse clickhouse 218 Mar 18 15:58 sizes.json
-rw-r-----. 1 clickhouse clickhouse 74 Mar 18 15:58 vipId.bin
可见,后面插入的数据是在每个字段文件的后面追加。不会新增新的文件。
TinyLog引擎
# 建表
CREATE TABLE tb_test_TinyLog
(
`id` Int64,
`vipId` Int64,
`brandId` Int32,
`shopId` Int32,
`saleDate` Datetime64,
`saleMoney` Float32
)
ENGINE = TinyLog
#查看表目录,但表目录是空的
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/
total 0
drwxr-x---. 2 clickhouse clickhouse 6 Mar 18 15:28 tb_test_TinyLog
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_TinyLog/
total 0
#插入数据
insert into tb_test_TinyLog values (10001,8001,429,6001,'2021-03-18 14:15:23',200.50);
SELECT * FROM tb_test_TinyLog
┌────id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 10001 │ 8001 │ 429 │ 6001 │ 2021-03-18 14:15:23.000 │ 200.5 │
└───────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_TinyLog/
total 28
-rw-r-----. 1 clickhouse clickhouse 30 Mar 18 15:31 brandId.bin
-rw-r-----. 1 clickhouse clickhouse 34 Mar 18 15:31 id.bin
-rw-r-----. 1 clickhouse clickhouse 34 Mar 18 15:31 saleDate.bin
-rw-r-----. 1 clickhouse clickhouse 30 Mar 18 15:31 saleMoney.bin
-rw-r-----. 1 clickhouse clickhouse 30 Mar 18 15:31 shopId.bin
-rw-r-----. 1 clickhouse clickhouse 187 Mar 18 15:31 sizes.json
-rw-r-----. 1 clickhouse clickhouse 34 Mar 18 15:31 vipId.bin
[clickhouse@worker1 ~]$ cat /var/lib/clickhouse/data/test/tb_test_TinyLog/sizes.json
{
"yandex":{
"brandId%2Ebin":{
"size":"30"},"id%2Ebin":{
"size":"34"},"saleDate%2Ebin":{
"size":"34"},"saleMoney%2Ebin":{
"size":"30"},"shopId%2Ebin":{
"size":"30"},"vipId%2Ebin":{
"size":"34"}}}
可见每个字段一个压缩的.bin文件,启动sizes.json是元文件,记录着每个字段对应的.bin文件的大小
```sql
#继续插入数据
insert into tb_test_TinyLog values (10002,8002,429,6001,'2021-03-18 14:18:23',300.50),(10003,8003,429,6001,'2021-03-18 14:18:23',400.50);
select * from tb_test_TinyLog;
┌────id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 10001 │ 8001 │ 429 │ 6001 │ 2021-03-18 14:15:23.000 │ 200.5 │
│ 10002 │ 8002 │ 429 │ 6001 │ 2021-03-18 14:18:23.000 │ 300.5 │
│ 10003 │ 8003 │ 429 │ 6001 │ 2021-03-18 14:18:23.000 │ 400.5 │
└───────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
```sql
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_TinyLog/
total 28
-rw-r-----. 1 clickhouse clickhouse 64 Mar 18 15:38 brandId.bin
-rw-r-----. 1 clickhouse clickhouse 74 Mar 18 15:38 id.bin
-rw-r-----. 1 clickhouse clickhouse 77 Mar 18 15:38 saleDate.bin
-rw-r-----. 1 clickhouse clickhouse 64 Mar 18 15:38 saleMoney.bin
-rw-r-----. 1 clickhouse clickhouse 64 Mar 18 15:38 shopId.bin
-rw-r-----. 1 clickhouse clickhouse 187 Mar 18 15:38 sizes.json
-rw-r-----. 1 clickhouse clickhouse 74 Mar 18 15:38 vipId.bin
[clickhouse@worker1 ~]$ cat /var/lib/clickhouse/data/test/tb_test_TinyLog/sizes.json
{"yandex":{"brandId%2Ebin":{"size":"64"},"id%2Ebin":{"size":"74"},"saleDate%2Ebin":{"size":"77"},"saleMoney%2Ebin":{"size":"64"},"shopId%2Ebin":{"size":"64"},"vipId%2Ebin":{"size":"74"}}}
可见,后面插入的数据是在每个字段文件的后面追加。不会新增新的文件。
TinyLog是日志家族系列中性能最低的表引擎,存储结构由数据文件和元数据两部分组成。其中数据文件按照列独立存储,即每个列字段都拥有一个与之对应的bin文件。TinyLog不支持分区,没有mrk文件,不支持bin文件的并行读取操作,只适合在非常简单的场景下使用。
StripLog引擎
#创建表
CREATE TABLE tb_test_StripeLog
(
`id` Int64,
`vipId` Int64,
`brandId` Int32,
`shopId` Int32,
`saleDate` Datetime64,
`saleMoney` Float32
)
ENGINE = StripeLog
# 查看建表目录
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/
total 0
drwxr-x---. 2 clickhouse clickhouse 6 Mar 18 15:42 tb_test_StripeLog
drwxr-x---. 2 clickhouse clickhouse 133 Mar 18 15:38 tb_test_TinyLog
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_StripeLog/
total 0
# 插入数据
insert into tb_test_TinyLog values (10001,8001,429,6001,'2021-03-18 14:15:23',200.50);
SELECT * FROM tb_test_StripeLog
┌─id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 1 │ 8001 │ 429 │ 6001 │ 2021-03-18 14:15:23.000 │ 200.5 │
└────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_StripeLog/
total 12
-rw-r-----. 1 clickhouse clickhouse 314 Mar 18 15:44 data.bin
-rw-r-----. 1 clickhouse clickhouse 137 Mar 18 15:44 index.mrk
-rw-r-----. 1 clickhouse clickhouse 69 Mar 18 15:44 sizes.json
[clickhouse@worker1 ~]$ cat /var/lib/clickhouse/data/test/tb_test_StripeLog/sizes.json
{
"yandex":{
"data%2Ebin":{
"size":"314"},"index%2Emrk":{
"size":"137"}}}
① data.bin 数据文件,所有的列字段使用一个文件保存,他们的数据都会被写入data.bin.
② index.mrk:数据标记文件,保存了数据在data.bin文件中的位置信息。利用数据标记能使用多线程,以并行的方式读取data.bin内的压缩数据块,从而提升数据查询的性能。
③ size.json:元数据文件,记录data.bin和index.mrk 大小的信息。
# 继续插入数据
insert into tb_test_StripeLog values (0002,8001,429,6001,'2021-03-18 14:15:23',200.50),(0003,8001,429,6001,'2021-03-18 14:15:23',400.50);
select * from tb_test_StripeLog;
┌─id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 1 │ 8001 │ 429 │ 6001 │ 2021-03-18 14:15:23.000 │ 200.5 │
└────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
┌─id─┬─vipId─┬─brandId─┬─shopId─┬────────────────saleDate─┬─saleMoney─┐
│ 2 │ 8001 │ 429 │ 6001 │ 2021-03-18 14:15:23.000 │ 200.5 │
│ 3 │ 8001 │ 429 │ 6001 │ 2021-03-18 14:15:23.000 │ 400.5 │
└────┴───────┴─────────┴────────┴─────────────────────────┴───────────┘
[clickhouse@worker1 ~]$ ll /var/lib/clickhouse/data/test/tb_test_StripeLog/
total 12
-rw-r-----. 1 clickhouse clickhouse 658 Mar 18 15:47 data.bin
-rw-r-----. 1 clickhouse clickhouse 274 Mar 18 15:47 index.mrk
-rw-r-----. 1 clickhouse clickhouse 69 Mar 18 15:47 sizes.json`
可见再插入数据就会在数据文件data.bin 后面追加上去。
好,以上就是Log引擎的基本情况,后续关于其他表引擎将在下节介绍。
更多精彩内容,欢迎关注微信公众号