副本表怎么工作
ReplicatedMergeTree 借助 ZooKeeper 或 ClickHouse Keeper 做多副本同步:建表时给出该表的协调路径与副本标识(或由 Replicated 数据库自动生成),副本之间通过复制日志拉取数据块,查询读任意可用副本即可。写入落到一个副本,其余副本异步追平。
基本信息
| 适用版本 | ClickHouse 22.x 及以上 |
|---|---|
| 引擎写法 | ReplicatedMergeTree('/clickhouse/tables/{shard}/tbl', '{replica}') |
| 路径宏 | {shard}、{replica} 来自 config.xml 的 macros |
| Replicated 库 | 库引擎为 Replicated 时可省略路径与副本名 |
| 依赖 | ZooKeeper 或 ClickHouse Keeper |
典型使用场景
- 生产环境做双副本容灾:单节点故障不影响查询与写入
- 跨机房部署:每个机房一份副本就近读取,靠复制日志同步
- 集群化建表:ON CLUSTER 一次在所有节点建出结构一致的表
- 副本延迟排查:用 system.replicas 看延迟与队列,确认副本是否追平
- 副本重建:某副本数据损坏时从其他副本恢复,而不是手工拷目录
示例
示例
CREATE TABLE events_local ON CLUSTER prod
(
ts DateTime,
id UInt64
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/events_local', '{replica}')
PARTITION BY toYYYYMM(ts)
ORDER BY (id, ts);
SYSTEM SYNC REPLICA events_local; -- 阻塞等待本副本追平,排查延迟时用
SELECT database, table, is_leader, is_readonly,
queue_size, absolute_delay
FROM system.replicas; -- 逐表查看副本状态与延迟
INSERT INTO events_local SELECT * FROM events_local_source
SETTINGS insert_quorum = 2; -- 等法定数量副本确认后再返回要素读法
| 要素 | 含义 | 注意点 |
|---|---|---|
| 路径参数 | 协调服务上的表路径 | 同一分片的各副本必须写完全相同的路径 |
| 副本名参数 | 本副本的唯一标识 | 通常用 {replica} 宏,各机器取值必须不同 |
| macros 配置 | 在 config.xml 里定义 {shard}、{replica} | 宏没配或两台机器相同会导致副本冲突 |
| Replicated 库 | 库引擎为 Replicated 时自动生成路径 | 省掉手写路径,集群内建表更省心 |
| SYSTEM SYNC REPLICA | 阻塞等待副本追平 | 积压多时会等很久,慎在高峰期执行 |
| insert_quorum | 写入等待指定数量副本确认 | 提升一致性,代价是写入延迟变高 |
写任意一个副本即可,其余副本通过复制日志拉取;相同的 INSERT 数据块按哈希去重,所以重试写入通常不会产生重复数据。
副本是异步的:写入返回不代表其他副本已经可见。对一致性有要求的场景用 insert_quorum 等法定数量副本确认,或写完用 SYSTEM SYNC REPLICA 等追平后再做校验。
Keeper 不可用时副本表会进入只读状态,写入报错并提示无法与协调服务通信;这类问题的根因在 Keeper 侧,重启 ClickHouse 没有用。