如何配置Patroni+Citus集群实现数据按需复制避免全量同步?
解决Patroni+Citus集群全量数据复制问题
你的问题核心是错误地将所有Citus节点纳入了同一个Patroni集群,或者Citus角色配置混乱,导致Patroni在整个集群内同步全量数据,加上Citus的分片分发,最终造成存储资源浪费。要实现你预期的架构,需要从以下几个关键步骤调整:
1. 拆分独立的Patroni集群
为Coordinator和每个Worker组创建完全独立的Patroni集群,每个集群有自己的scope和DCS(如etcd)路径,确保Patroni只同步集群内部的主备节点数据,不会跨集群复制。
配置示例(Patroni的patroni.yml)
- Coordinator集群的配置:
scope: citus-coordinator dcs: ttl: 30 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true prefix: /patroni/citus-coordinator # 独立的DCS路径 postgresql: listen: '0.0.0.0:5432' connect_address: 'citus-coord-main:5432' data_dir: /var/lib/postgresql/data parameters: citus.node_type: 'coordinator' # 指定Citus角色
- Worker1集群的配置(Worker2集群同理,修改scope和prefix):
scope: citus-worker-1 dcs: ttl: 30 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true prefix: /patroni/citus-worker-1 postgresql: listen: '0.0.0.0:5432' connect_address: 'citus-worker1-main:5432' data_dir: /var/lib/postgresql/data parameters: citus.node_type: 'worker' # 指定Citus角色
2. 严格配置Citus节点角色
- Coordinator节点:仅启用Coordinator角色,只存储分片元数据,不存储业务数据分片。确保
postgresql.conf中citus.node_type = 'coordinator',且不要将Coordinator节点加入Citus的Worker列表。 - Worker节点:每个Worker集群的主节点作为Citus的Worker节点,负责存储分配的分片;备节点仅作为Patroni的副本,不需要被Coordinator识别(Patroni负责主备切换)。Worker节点的
postgresql.conf中设置citus.node_type = 'worker'。
3. Docker Compose服务拆分
在docker-compose.yml中将6个节点拆分为3组独立服务,每组对应一个Patroni集群:
services: # Coordinator高可用集群 citus-coord-main: image: citusdata/citus:12.1 volumes: - ./patroni-coord.yml:/etc/patroni.yml - coord-main-data:/var/lib/postgresql/data command: patroni /etc/patroni.yml citus-coord-replica: image: citusdata/citus:12.1 volumes: - ./patroni-coord.yml:/etc/patroni.yml - coord-replica-data:/var/lib/postgresql/data command: patroni /etc/patroni.yml # Worker1高可用集群 citus-worker1-main: image: citusdata/citus:12.1 volumes: - ./patroni-worker1.yml:/etc/patroni.yml - worker1-main-data:/var/lib/postgresql/data command: patroni /etc/patroni.yml citus-worker1-replica: image: citusdata/citus:12.1 volumes: - ./patroni-worker1.yml:/etc/patroni.yml - worker1-replica-data:/var/lib/postgresql/data command: patroni /etc/patroni.yml # Worker2高可用集群 citus-worker2-main: image: citusdata/citus:12.1 volumes: - ./patroni-worker2.yml:/etc/patroni.yml - worker2-main-data:/var/lib/postgresql/data command: patroni /etc/patroni.yml citus-worker2-replica: image: citusdata/citus:12.1 volumes: - ./patroni-worker2.yml:/etc/patroni.yml - worker2-replica-data:/var/lib/postgresql/data command: patroni /etc/patroni.yml # DCS服务(如etcd) etcd: image: quay.io/coreos/etcd:v3.5.5 command: etcd -listen-client-urls=http://0.0.0.0:2379 -advertise-client-urls=http://etcd:2379
4. 正确配置Citus分片分配
在Coordinator节点上,仅将每个Worker集群的主节点加入Citus Worker列表:
-- 添加Worker主节点 SELECT citus_add_node('citus-worker1-main', 5432); SELECT citus_add_node('citus-worker2-main', 5432); -- 设置分片复制因子为1(由Patroni负责节点级高可用,无需Citus再做分片副本) SELECT citus_set_shard_replication_factor(1);
5. 主备切换后的自动更新
当Worker主节点故障,Patroni切换到备节点后,需要在Coordinator上更新Worker节点信息,可通过Patroni的on_switchover回调脚本自动执行:
# 示例回调脚本(在Patroni配置中指定) #!/bin/bash COORDINATOR_HOST="citus-coord-main" OLD_NODE=$1 NEW_NODE=$2 psql -h $COORDINATOR_HOST -U postgres -c "SELECT citus_update_node('$OLD_NODE', '$NEW_NODE', 5432);"
关键注意事项
- 禁止将所有节点配置为同一个Patroni集群的成员,否则Patroni会同步全量数据。
- 不要将Coordinator节点标记为Worker,否则业务分片会被存储到Coordinator节点。
- Worker备节点不需要被Coordinator识别,避免分片被重复分配。
内容的提问来源于stack exchange,提问作者Sulas
相关产品推荐
相关产品推荐

