美文网首页计算机语言工具文
MergeTree分区合并原理初探

MergeTree分区合并原理初探

作者: 淡淡的小番茄 | 来源:发表于2021-04-14 10:44 被阅读0次

    MergeTree引擎在我们项目中使用很多,但是对于其原理知之甚少。今天把最近搜集到的信息,结合我们的项目情况,整理归纳如下,以证明过我也思考过。

    MergeTree的创建 

    CREATE TABLE dmp_log.buffer_device_sty

    (

        `id` Int64,

        `product_key` String,

        `device_name` String,

        `device_key` String,

        `org_id` Int64,

        `status` Int8,

        `version` UInt64,

        `enabled` Int8,

        `sign` Int8,

        `insert_time` DateTime DEFAULT now()

    )

    ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/{layer}-{shard}/buffer_device_sty','{replica}',version)

    ORDER BY (id,product_key,device_key)

    SETTINGS index_granularity = 8192;

    相应的会在ClickHouse数据文件夹下创建buffer_device_sty文件夹,如下图所示:

    MergeTree数据块

    执行两个批量insert语句:

    INSERT INTO dmp_log.buffer_device_sty (id,product_key,device_name,device_key,org_id,status,version,enabled,sign) SELECT id,product_key,device_name,device_key,org_id,status,version,enabled,sign FROM buffer_device_all_0;

    INSERT INTO dmp_log.buffer_device_sty (id,product_key,device_name,device_key,org_id,status,version,enabled,sign) SELECT id,product_key,device_name,device_key,org_id,status,version,enabled,sign FROM buffer_device_all_1;

    相应的buffer_device_sty下会增加两个数据块文件夹:

    两个insert sql执行后直接生成两个数据块(Block):all_0_0_0和all_1_1_0。

    分区目录的命名规则

    数据片段文件夹命名规则如下:PartitionID_MinBlockNum_MaxBlockNum_Level。

    • PartitionID

    分区ID。如果不使用分区键,既不使用PARTITION BY声明任何分区表达式,则分区ID默认取名为all,所有的数据都会被写入到这个all分区。buffer_device_sty表就是如此。

    • MinBlockNum和MaxBlockNum

    顾名思义,最小数据块编号与最大数据块编号。这里的BlockNum是一个整型的自增长编号。如果将其设为n的话,那么计数n在单张MergeTree数据表内全局累加,n从1开始,每当新创建一个分区目录时,计数n就会累积加1。对于一个新的分区目录而言,MinBlockNum与MaxBlockNum取值一样,同等于n。

    • Level

    合并的层级,可以理解为某个分区被合并过的次数。Level计数与BlockNum有所不同,它并不是全局累加的。对于每一个新创建的分区目录而言,其初始值均为0。之后,以分区为单位,如果相同分区发生合并动作,则在相应分区内计数累积加1。

    ClickHouse会定期对统一个分区下面的数据block进行合并,默认超过3个block后,会将新增的block作为一组进行合并。合并后不会立即删除涉及到的block,下次合并会触发删除。

    分区合并

    1)在 08:13生成两个block,观察10分钟左右未触发分区合并。 08:27分再生成1个block。

    =====================================================

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:10 all_0_31_6

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:13 all_32_32_0

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:13 all_33_33_0

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:27 all_34_34_0

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:31 all_35_35_0

    2)08:27分再生成第4个block,超过3个block,触发分区合并,这个过程在我们的环境触发得比较快,1分钟左右:

    ======================================================

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:10 all_0_31_6

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:32 all_0_35_7

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:13 all_32_32_0

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:13 all_33_33_0

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:27 all_34_34_0

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:31 all_35_35_0

    3)10分钟左右,再次触发一次合并,会将之前的冗余block进行删除。最后只剩下一个合并后的block:all_0_35_7。

    ========================================================

    drwxr-x--- 2 clickhouse clickhouse 4096 Apr 14 08:32 all_0_35_7

    可以通过`system`.parts表查看详细信息,sql如下:select * from `system`.parts p where p.name ='all_0_35_7';

    相关文章

      网友评论

        本文标题:MergeTree分区合并原理初探

        本文链接:https://www.haomeiwen.com/subject/fodklltx.html