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 正本节执行操作的队列
同步流程
数据插入,流程如下:
- 在其中 2 正本节点插入数据时,如果数据只存在 1 个 partition 的数据,则在该正本节点产生 1 个 part。
- 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;
- 用这个 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-0000000000
format version: 4
create_time: 2021-11-20 14:27:00
source replica: 2
block_id: all_3218416765532976388_2128470793510818708
get
all_0_0_0
part_type: Compact
source replica: 2 表明该 part 是从正本 2 产生的
正本同步流程
- 正本节点 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
-
内核中正本表的定时工作从 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-220 port: 21429 tcp_port: 9000 database: db_test table: tbl_replicated scheme: https
拉取到 part 后,正本 1 也写入 tbl_replicated/replicas/1/parts/all_0_0_0 的 znode,表明本正本节点有这个 part 数据。
在正本生产 queue 的过程中,并不是严格先入先出的程序。如果看到 log 的类型是 merge 而不是 get,则思考优先去拉取 merge 后的 part 数据,而不是间接拉取原始的 part -
log 革除逻辑。当 log_xxxxxxx 下标曾经小于所有有正本的 log_pointer,且 log 目录下的数量曾经大于指定阈值,则会革除该 log 节点。
本文由华为云公布