Clickhouse 正本节点之间通过Zookeeper 的log数据和其余管制信息,实现了正本间数据的异步同步。本文中简略介绍插入数据后正本之间同步流程。

正本表Zookeeper目录构造

创立正本表,并插入数据,在Zookeeper上能够看到表目录下次要蕴含下列目录信息,
ReplicatedMergeTree(’/clickhouse/tables/{shard}/tbl_replicated’, ‘{replica}’)

tbl_replicated:| —— block_numbers    |all| —— blocks| —— columns 列信息| —— leader_election    | —— leader_election-0000000000 主信息,正本节点(multiple leaders ok)| —— log    | —— log-0000000000 part名称以及相干的块信息,创立工夫,source replica, part_type| —— metadata 元数据信息 (未变动)| —— mutations 空 (未变动)合并场景,alter table的场景| —— nonincrement_block_numbers 空 (未变动)| —— quorum    ----> 默认状况下,INSERT 语句仅期待一个正本写入胜利后返回。             如果数据只胜利写入一个正本后该正本所在的服务器不再存在,             则存储的数据会失落。             要启用数据写入多个正本才确认返回,应用 insert_quorum 选项。    | —— failed_parts    | —— last_part    | —— parallel| —— replicas    | —— 1 、2        | —— columns 列信息        | —— flags        | —— host 以后正本的主机信息,端口号        | —— is_active 正本节点ClickHouseServer过程PID        | —— is_lost        | —— log_pointer ===》 1        | —— max_processed_insert_time        | —— metadata 元数据信息        | —— metadata_version        | —— min_unprocessed_insert_time        | —— mutation_pointer        | —— parts 正本蕴含的part 信息        | —— queue 正本节执行操作的队列

同步流程

数据插入,流程如下:

  1. 在其中2正本节点插入数据时,如果数据只存在1个partition的数据,则在该正本节点产生1个part。
  2. ClickHouse Server从tbl_replicated/block_numbers/all(all是分区名,没有分区的状况下是all) 获取新产生part的下标,该下标是递增的。应用获取的part 下标产生对应的part 名。比方,首次插入数据从tbl_replicated/block_numbers/all获取到的下标是0, 则产生all_0_0_0 的part名。下次插入时,从tbl_replicated/block_numbers/all获取到的下标是1,产生的part 名是all_1_1_0;
  3. 用这个part 名生成写入磁盘后,在zookeeper正本表目录下产生part 信息node
    tbl_replicated/replicas/2/parts/all_0_0_0

在tbl_replicated/replicas/2/part/all_0_0_0在tbl_replicated/log目录产生log-0000000000 日志信息:

[zk: 8.5.131.220:24002(CONNECTED) 11] get /clickhouse/tables/17/tbl_replicated/log/log-0000000000format version: 4create_time: 2021-11-20 14:27:00source replica: 2block_id: all_3218416765532976388_2128470793510818708getall_0_0_0part_type: Compactsource replica: 2 表明该part 是从正本2产生的

正本同步流程

  1. 正本节点1 定时读取tbl_replicated/log 目录,读取到新的log后,将log同步到本正本节点的tbl_replicated/replicas/1/queue/queue-00000000000, 而后更本节点的tbl_replicated/replicas/1/log_pointer 值为0,表明本正本曾经执行到log-0000000000,后续执行log-0000000001(蕴含)之后的log
  2. 内核中正本表的定时工作从tbl_replicated/replicas/1/queue生产节点,读取到log-0000000000的内容时,须要从source replica: 2 拉取part ,正本2对应的主机节点host 从znode 节点/clickhouse/tables/17/tbl_replicated/replicas/2/host获取:

    host: 8-5-131-220port: 21429tcp_port: 9000database: db_testtable: tbl_replicatedscheme: https

    拉取到part后,正本1也写入tbl_replicated/replicas/1/parts/all_0_0_0的znode ,表明本正本节点有这个part数据。
    在正本生产queue的过程中,并不是严格先入先出的程序。如果看到log 的类型是merge 而不是get ,则思考优先去拉取merge后的part 数据,而不是间接拉取原始的part

  3. log 革除逻辑。当log_xxxxxxx下标曾经小于所有有正本的log_pointer ,且log 目录下的数量曾经大于指定阈值,则会革除该log节点。

    本文由华为云公布