You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:36:01