Clickhouse 原理

Clickhouse 原理

分区目录的合并过程

当前 CK 版本

select version();-- 21.8.5.7

创建新表

CREATE TABLE dpaas_db.test_gc_part on cluster my_cluster(
    `tableName` String COMMENT '表名称',
    `traceId` String COMMENT 'UUID',
    `type` String COMMENT '消息类型',
    `scene` String COMMENT '场景',
    `createTime` datetime default toDateTime(now()) COMMENT '创建时间'
) ENGINE = ReplicatedMergeTree('/clickhouse/my_cluster/dpaas_db/tables/{shard}/test_gc_part/0','{replica}')
PARTITION BY toDate(createTime)
ORDER BY tableName
SETTINGS index_granularity = 8192;

CREATE TABLE dpaas_db.test_gc on cluster my_cluster(
    `tableName` String COMMENT '表名称',
    `traceId` String COMMENT 'UUID',
    `type` String COMMENT '消息类型',
    `scene` String COMMENT '场景',
    `createTime` datetime default toDateTime(now()) COMMENT '创建时间'
) ENGINE = Distributed('my_cluster','dpaas_db','test_gc_part',rand());

查看存储目录

[root@hadoop1 test_gc_part]# pwd
/var/lib/clickhouse/data/dpaas_db/test_gc_part
[root@hadoop1 test_gc_part]# ll
total 8
drwxr-x--- 2 clickhouse clickhouse 4096 Apr 21 19:45 detached
-rw-r----- 1 clickhouse clickhouse    1 Apr 21 19:45 format_version.txt
[root@hadoop1 test_gc_part]# 

插入数据

  • 插入一条当天分区的数据
insert into dpaas_db.test_gc_part values('tableName','uuid','type','dataset',now());

发现此时会有一个20220421_0_0_0的分区

  • 插入两条明天和后天分区的数据
insert into dpaas_db.test_gc_part values('tableName','uuid','type','dataset',addDays(now(),1));
insert into dpaas_db.test_gc_part values('tableName','uuid','type','dataset',addDays(now(),2));

发现此时会多两个目录 20220422_0_0_020220423_0_0_0

  • 再插入一条当天分区的数据
insert into dpaas_db.test_gc_part values('tableName','uuid','type','dataset',now());

在这里插入图片描述

  • 在同时插入10条数据到当天分区里

在这里插入图片描述

此时十条数据插入后又新增了一个目录 20220421_2_2_0

不过可以看到此时数据没有被合并

  • 手动触发合并分区

在这里插入图片描述

  • 系统后台会定时异步删除合并后的分区(默认8分钟)

在这里插入图片描述

  • 从表中看效果

在这里插入图片描述

  • 最终的效果

在这里插入图片描述

  • 在插入两条数据,一条是20220423,一条是20220420
insert into dpaas_db.test_gc_part values('tableName','uuid','type','dataset',addDays(now(),2));
insert into dpaas_db.test_gc_part values('tableName','uuid','type','dataset',addDays(now(),-1));

在这里插入图片描述

目录规则 20220421_0_2_1

  • 20220421 是当前分区
  • 0 MinBlockNum 最小数据块编号
  • 2 MaxBlockNum 最大数据块编号
  • 0 Level 分区合并的次数

同一分区,MinBlockNum 是递增的,不同分区不递增。默认从0开始

当同一分区目录比较多时,会怎么样?什么时候会出现这种问题?

当插入大批量数据时,如果单批量的条数比较少,会导致合并分区的速度小于插入分区的速度时会报错。

clickhouse,DB::Exception: Too many parts (300). Merges are processing significantly slower than inserts.

分区目录下的文件结构

在这里插入图片描述

  • 真实的结构

在这里插入图片描述
在这里插入图片描述

  • checksums.txt :校验文件,使用二进制格式存储。它保存了primary.idxcount.txt 文件的size大小和size的hash值。用于快速校验文件的完整性和正确性

  • columns.txt : 列信息文件

  • count.txt:计数文件,当前分区下数据总量。

  • primary.idx:一级索引文件,使用二进制格式存储。用于存放稀疏索引,一张MergeTree表只能声明一次一级索引(通过ORDER BY或者PRIMARY KEY)

  • [Column].bindata.bin: 数据文件,用于存储某一列的数据。使用压缩格式存储。默认LZ4压缩格式

    • 当字段比较少的时候会将所有字段的.bin都合并到data.bin

    • 当字段多的时候会单独作为[Column].bin,例如:id.bin 。如果id是Nullable 可为空的字段,则还会多出来 [Column].null.bin

    • data.markdata.mark2 同理

  • [Column].mrkdata.mrk : 列字段标记文件,使用二进制格式存储。标记.bin文件中数据的偏移量。这里保存的是稀疏索引与.bin数据文件之间的映射关系。即首先通过稀疏索引(primary.idx)找到对应数据的偏移量信息(.mrk),再通过偏移量直接从.bin文件中读取数据

  • [Column].mrk2data.mrk2 : 如果使用了自适应大小的索引间隔,则标记文件会以 .mrk2命名。工作原理和作用与 .mrk 标记文件相同

  • partition.datminmax_[Column].idx :如果使用了 分区键,则会额外生成这两个文件。使用二进制格式存储

    • partition.dat 用于保存当前分区下分区表达式最终生成的值
    • minmax_[Column].idx 该索引文件用于记录当前分区下分区字段对应原始数据的最小和最大值。
    • 在这些分区索引的作用下,进行数据查询时能够快速跳过不必要的分区目录,从而减少需要扫描的数据范围
  • skp_idx_[Column].idx skp_idx_[Column].mrk:如果在建表语句中声明了二级索引,则会额外生成相应的二级索引与标记文件。它们同样也使用二进制存储。二级索引在ClickHouse中又称跳数索引,目前拥有minmax、set、ngrambf_v1和tokenbf_v1四种类型。最终目标与一级稀疏索引相同,都是为了进一步减少所需扫描的数据范围,以加速整个查询过程。

count.txt:计数文件,当前分区下数据总量。

  • primary.idx:一级索引文件,使用二进制格式存储。用于存放稀疏索引,一张MergeTree表只能声明一次一级索引(通过ORDER BY或者PRIMARY KEY)

  • [Column].bindata.bin: 数据文件,用于存储某一列的数据。使用压缩格式存储。默认LZ4压缩格式

    • 当字段比较少的时候会将所有字段的.bin都合并到data.bin

    • 当字段多的时候会单独作为[Column].bin,例如:id.bin 。如果id是Nullable 可为空的字段,则还会多出来 [Column].null.bin

    • data.markdata.mark2 同理

  • [Column].mrkdata.mrk : 列字段标记文件,使用二进制格式存储。标记.bin文件中数据的偏移量。这里保存的是稀疏索引与.bin数据文件之间的映射关系。即首先通过稀疏索引(primary.idx)找到对应数据的偏移量信息(.mrk),再通过偏移量直接从.bin文件中读取数据

  • [Column].mrk2data.mrk2 : 如果使用了自适应大小的索引间隔,则标记文件会以 .mrk2命名。工作原理和作用与 .mrk 标记文件相同

  • partition.datminmax_[Column].idx :如果使用了 分区键,则会额外生成这两个文件。使用二进制格式存储

    • partition.dat 用于保存当前分区下分区表达式最终生成的值
    • minmax_[Column].idx 该索引文件用于记录当前分区下分区字段对应原始数据的最小和最大值。
    • 在这些分区索引的作用下,进行数据查询时能够快速跳过不必要的分区目录,从而减少需要扫描的数据范围
  • skp_idx_[Column].idx skp_idx_[Column].mrk:如果在建表语句中声明了二级索引,则会额外生成相应的二级索引与标记文件。它们同样也使用二进制存储。二级索引在ClickHouse中又称跳数索引,目前拥有minmax、set、ngrambf_v1和tokenbf_v1四种类型。最终目标与一级稀疏索引相同,都是为了进一步减少所需扫描的数据范围,以加速整个查询过程。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值