暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ClickHouse集群(1)INSERT、MERGE执行流程

ClickHouse周边 2021-06-15
1255
        CH集群架构 (metrika.xml)基本由 副本+分片 组成。副本:源数据的冗余,防止数据丢失;分片:数据的水平拆分,提升查询性能。对于ClickHouse而言,集群架构由简单到复杂如下:

来自《ClickHouse原理解析与应用实践》一书

准备环境

  1. 集群架构是2分片,1副本

    create database testdb;
    use testdb;
    复制
    2.分布式DDL的建表语句
            2.1 本地表
      create table test_local ON CLUSTER my_cluster (ID Int8, Name String, BirthDate Date) \
                  ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_local','{replica}'PARTITION BY toYYYYMMDD(BirthDate) ORDER BY (Name, BirthDate) SETTINGS index_granularity = 8192;
              ReplicatedMergeTree的定义方式
      ENGINE =ReplicatedMergeTree('zk_path','replica_name')

              ClickHouse提供的配置模板

        <default_replica_path>/clickhouse/tables/{shard}/{table}</default_replica_path>
        <default_replica_name>{replica}</default_replica_name>

                对于zk_path,同一张数据表的同一个分片的不同副本,定义相同的路径;而对于replica_name,同一张数据表的同一个分片的不同副本,定义不同的名称。

        详情查看 Creating Replicated Tables

        https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/
                2.2 分布表
        复制
          create table test_all ON CLUSTER my_cluster (ID Int8, Name String, BirthDate Date) \
          ENGINE = Distributed(my_cluster,testdb,test_local, rand());

          3.插入测试数据

            insert into test_all values(1,'zhangsan',now()),(2,'lisi',now()),(3,'wangwu',now()),(4,'maliu',now());

            来自《ClickHouse原理解析与应用实践》一书
                    在MergeTree中,一个数据分区由开始创建到全部完成,会历经两类存储区域。
                    (1)内存:数据首先会被写入内存缓冲区。

                    (2)本地磁盘:数据接着会被写入tmp临时目录分区,待全部完成后再将临时目录重命名为正式分区,然后向/block节点写入该数据分区的block_id(用于去重)。ReplicatedMergeTree在上述基础之上增加了ZooKeeper的部分,它会进一步在ZooKeeper内创建一系列的监听节点,并以此实现多个实例之间的通信。

                    shard:/01/        192.168.6.129 选择拉取远端副本:192.168.6.128


                    其中可以看到shard:/01/ 的192.168.6.129 选择拉取远端副本:192.168.6.128 的时候第一次下载请求失败。ClickHouse默认配置可以共请求5次。
                    shard:/02/        192.168.6.84 选择拉取远端副本:192.168.6.130

                    追踪日志信息可以看出,基于DataPartsExchange的响应后,先将数据写入了tmp_fetch_20210611_0_0_0,待全部数据接收完成之后,重命名该目录:Renaming temporary part tmp_fetch_20210611_0_0_0 to 20210611_0_0_0。
            4.查询

            建表语句中分区键是:BirthDate ,主键是 Name, BirthDate
                    根据追踪的信息,解读SQL执行计划:
             该SQL没有使用主键索引:

            Key conditi

            on: unknown
            该SQL没有使用分区索引:

            MinMax index condition: unknown

            该SQL查询,共扫描了所有的1个分区目录,共计1个MarkRange:


            Selected 1 parts by date, 1 parts by key, 1 marks to read from 1 ranges

            5.合并
              insert into test_all values(11,'zhangsan',now()-259200),(22,'lisi',now()-259200),(33,'wangwu',now()-259200),(44,'maliu',now()-259200);
                insert into test_all values(5,'sunqi',now()),(6,'zhouba',now()),(7,'wujiu',now()),(8,'zhengshi',now());

                  optimize table test_local;

                          根据追踪的信息,操作类型为Merge合并,需要合并的分区目录是20210611_68_68_0 和 20210611_69_69_0。同时,主副本还锁住执行线程,对日志的接收情况进行监听:


                  Waiting for 192.168.6.128 to pull log-0000000089 to queue

                          各个副本实例将分别监听/log/log-0000000089日志的推送,它们也会分别拉取日志到本地,并推送到各自的/queue任务队列:

                  Pulling 1 entries to queue: log-0000000089 - log-0000000089

                          各个副本基于队列分别在本地执行MERGE

                  Executing log entry to merge parts 20210611_68_68_0, 20210611_69_69_0 to 20210611_68_69_1

                  Merging 2 parts: from 20210611_68_68_0 to 20210611_69_69_0 into Wide

                          合并完成查询:



                  近期文章推荐:
                  ClickHouse 之 FORMAT 应用
                  ClickHouse数据目录完全解析
                  Distributed表引擎Insert和Select流程

                  更多精彩内容欢迎关注微信公众号

                  复制
                  文章转载自ClickHouse周边,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论