分布式Citus集群与Patroni

分布式Citus集群与Patroni

1. 环境介绍

2. 安装部署

2.1 安装Docker

2.1.1 检查是否安装

运行以下命令来检查 Docker 是否已安装:

docker --version

如果没有返回版本号,则 Docker 可能未安装。

2.1.2 安装

# 更新包索引
sudo yum update

# 安装必要的包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# 设置 Docker 仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装 Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io

# 启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
sudo systemctl status docker

2.1.3 添加用户到 Docker 组

为了避免每次运行 Docker 命令时都需要使用 sudo,您可以将当前用户添加到 Docker 组:

sudo usermod -aG docker root

然后注销并重新登录,或者使用 newgrp docker 使更改生效。

2.2 克隆Patroni repo并构建patroni-citus docker镜像

git clone https://github.com/zalando/patroni.git
cd patroni
docker build -t patroni-citus -f Dockerfile.citus .


Sending build context to Docker daemon  573.6MB
Step 1/36 : ARG PG_MAJOR=15
… skip intermediate logs
Step 36/36 : ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
---> Running in 1933967fcb58
Removing intermediate container 1933967fcb58
---> 0eea66f3c4c7
Successfully built 0eea66f3c4c7
Successfully tagged patroni-citus:latest

镜像准备就绪后,我们将使用以下命令部署堆栈:

docker-compose -f docker-compose-citus.yml up -d

现在我们可以验证容器是否已启动并运行:

docker ps

总共有11个镜像:

  • 具有ETCD的三个容器(形成三节点ETCD集群),
  • 七个容器,Patroni+PostgreSQL+Citus(三个协调器节点和两个工作集群,每个工作集群有两个节点),以及
  • 一个装有HAProxy的容器。

HAProxy监听端口5000(连接到Citus协调器主节点)和5001(在工作者主节点之间进行负载平衡):

几秒钟后,我们的Citus集群将启动并运行。我们可以使用patronictl容器中的demo-haproxy工具来验证它:

docker exec -ti demo-haproxy bash


patronictl list

现在,让我们通过HAProxy连接到协调器主节点,并验证Citus扩展是否已创建,工作节点是否已在协调器元数据中注册:

psql -h localhost -p 5000 -U postgres -d citus

到目前为止,一切顺利。😃

在这个特定的设置中,Patroni被配置为使用客户端证书以及节点之间超级用户连接的密码。由于Citus主动使用超级用户连接在节点之间进行通信,Patroni还通过pg_dist_authinfo来配置身份验证参数:

citus=# select * from pg_dist_authinfo;
nodeid | rolename |                                                   authinfo
-------+----------+--------------------------------------------------------------------------------------------------------------
     0 | postgres | password=postgres sslcert=/etc/ssl/certs/ssl-cert-snakeoil.pem sslkey=/etc/ssl/private/ssl-cert-snakeoil.key
(1 row)

不要被您在authinfo字段中看到的密码吓到。为什么?为什么?因为首先,对pg_dist_authinfo的访问仅限于超级用户。其次,可以只使用客户端证书来设置身份验证,这实际上是推荐的方式。

3. 使用HA

在Postgres HA术语和Patroni术语中,“故障”是故意的故障转移。这是当您有计划的维护并且出于某种原因需要自己触发故障转移时所做的事情。

在使用Patroni进行配置之前,让我们首先创建一个Citus分布式表,并开始使用\watchpsql命令向其中写入一些数据:

citus=# create table my_distributed_table(id bigint not null generated always as identity, value double precision);
CREATE TABLE
citus=# select create_distributed_table('my_distributed_table', 'id');
 create_distributed_table
--------------------------

(1 row)

citus=# with inserted as (
    insert into my_distributed_table(value)
     values(random()) RETURNING id
) SELECT now(), id from inserted\watch 0.01

\watch 0.01将每10 ms执行一次给定的查询,查询将返回插入的id加上微秒进动的当前时间,以便我们可以看到时钟对它的影响。

同时,在不同的终端中,我们将在其中一个工作节点上发起一个TCP/IP:

$ docker exec -ti demo-haproxy bash

postgres@haproxy:~$ patronictl switchover
Current cluster topology
+ Citus cluster: demo ---------+--------------+---------+----+-----------+
| Group | Member  | Host       | Role         | State   | TL | Lag in MB |
+-------+---------+------------+--------------+---------+----+-----------+
|     0 | coord1  | 172.19.0.8 | Sync Standby | running |  1 |         0 |
|     0 | coord2  | 172.19.0.7 | Leader       | running |  1 |           |
|     0 | coord3  | 172.19.0.6 | Replica      | running |  1 |         0 |
|     1 | work1-1 | 172.19.0.5 | Sync Standby | running |  1 |           |
|     1 | work1-2 | 172.19.0.2 | Leader       | running |  1 |         0 |
|     2 | work2-1 | 172.19.0.9 | Sync Standby | running |  1 |         0 |
|     2 | work2-2 | 172.19.0.4 | Leader       | running |  1 |           |
+-------+---------+------------+--------------+---------+----+-----------+
Citus group: 2
Primary [work2-2]:
Candidate ['work2-1'] []:
When should the switchover take place (e.g. 2023-02-06T14:27 )  [now]:
Are you sure you want to switchover cluster demo, demoting current leader work2-2? [y/N]: y
2023-02-06 13:27:56.00644 Successfully switched over to "work2-1"
+ Citus cluster: demo (group: 2, 7197024670041272347) ------+
| Member  | Host       | Role    | State   | TL | Lag in MB |
+---------+------------+---------+---------+----+-----------+
| work2-1 | 172.19.0.9 | Leader  | running |  1 |           |
| work2-2 | 172.19.0.4 | Replica | stopped |    |   unknown |
+---------+------------+---------+---------+----+-----------+

最后,在安装完成后,让我们检查第一个终端中的日志:

Mon Feb  6 13:27:54 2023 (every 0.01s)

             now              |  id
------------------------------+------
2023-02-06 13:27:54.441635+00 | 1172
(1 row)

Mon Feb  6 13:27:54 2023 (every 0.01s)

            now              |  id
-----------------------------+------
2023-02-06 13:27:54.45187+00 | 1173
(1 row)

Mon Feb  6 13:27:57 2023 (every 0.01s)

             now              |  id
------------------------------+------
2023-02-06 13:27:57.345054+00 | 1174
(1 row)

Mon Feb  6 13:27:57 2023 (every 0.01s)

             now              |  id
------------------------------+------
2023-02-06 13:27:57.351412+00 | 1175
(1 row)

正如您可能看到的,在切换发生之前,查询每10 ms持续运行一次。在id 11731174之间,您可能会注意到一个短暂的延迟峰值,2893 ms(不到3秒)。这就是受控的服务器如何表现自己,不产生客户端错误!

在安装完成后,我们可以再次检查pg_dist_node

citus=# select nodeid, groupid, nodename, nodeport, noderole
from pg_dist_node order by groupid;
nodeid | groupid |  nodename  | nodeport | noderole
-------+---------+------------+----------+----------
     1 |       0 | 172.19.0.7 |     5432 | primary
     3 |       1 | 172.19.0.2 |     5432 | primary
     2 |       2 | 172.19.0.9 |     5432 | primary
(3 rows)

正如您所看到的,组2中主服务器的nodename已被Patroni自动从172.19.0.4更改为172.19.0.9

4. CN节点主从替换

在 Patroni 管理的 Citus 集群中,Coordinator Node (CN) 和 Worker Node (DN) 的主从切换类似于 PostgreSQL 的主从切换过程。以下是关于 CN 节点在 Patroni 中的主从替换过程:

  1. Coordinator Node (CN) 的主从切换
    当 Patroni 监控到当前主 CN 节点故障时,会自动将一个备用的 CN 节点提升为新的主节点。Patroni 通过 pg_promote 命令将同步的从节点(Replica)提升为主节点(Primary)。这种主从切换可以通过 Patroni API 手动触发,也可以通过 Patroni 自动健康检查来实现。

  2. Worker Node (DN) 的主从切换
    对于 Worker Node(即数据节点,DN),Patroni 也提供了类似的主从切换机制。Citus 的 Coordinator Node(CN)会在主从切换期间暂停来自应用的查询请求,以避免不一致的查询结果。切换完成后,CN 会继续将查询请求分发到新的主节点上。

  3. 代码实现
    在 Patroni 的源码中,patroni.postgresql.mpp.citus.PgDistGroup 类负责管理 Citus 中的节点。比如,sync_meta_dataupdate_node 等方法会帮助 CN 节点同步元数据,以保持分布式节点信息的一致性,从而确保在节点失效或添加新节点时可以平滑地进行故障切换和重新配置【38†source】。

更多详细信息可以参考 Patroni 的 GitHub 文档

5. DN节点主从替换

在 Patroni 中,Citus 的 Worker Node (DN) 主从切换过程也是自动化的,类似于 Coordinator Node (CN) 的主从切换,但会涉及一些 Citus 特有的处理逻辑,以确保分布式数据一致性和查询不中断。以下是 DN 节点主从切换的具体过程:

  1. 检测故障
    Patroni 通过健康检查持续监控每个 DN 的状态。一旦检测到当前主 DN 节点(Primary)失效,Patroni 会自动启动切换流程,将一个同步的从节点(Replica)提升为新的主节点。

  2. 分片迁移与查询暂停
    在 Citus 集群中,查询请求首先由 CN 协调。如果某个 DN 出现故障,CN 会暂停对该节点上的数据分片的查询操作,以防止在切换过程中出现不一致的问题。Citus 会暂时停止对相关分片的访问,直到新的主节点完全接管并能够处理读写请求为止【38†source】。

  3. 主从切换与元数据同步
    Patroni 使用 pg_promote 等方法将从节点提升为主节点,并确保新的主节点在同步完成后正式上线。此外,Citus 会更新 pg_dist_node 表中的元数据,确保 CN 能够正确识别当前活跃的 DN 主节点,从而正常路由查询请求【38†source】。

  4. 恢复与流量恢复
    当新的主 DN 节点完全就绪后,Patroni 会通知 CN 恢复对该节点的查询分发。这样,整个切换过程对于应用来说几乎是透明的,保持了数据和请求的高可用性。

通过这种机制,Citus 在 Patroni 的帮助下确保了 DN 节点的自动主从切换,最大限度地减少了对分布式查询的影响,实现了分布式 PostgreSQL 数据库的高可用性和容错能力。更多详细信息可以在 Patroni 的 GitHub 文档中查看。

6. 参考文献

关于Patroni中Citus的CN(协调器)和DN(数据节点)节点主从替换的相关博客文章,以下是一些推荐的资源:

  1. Citus与Patroni的高可用性集群部署
    这篇博文详细介绍了如何通过Patroni配置实现Citus的高可用性,涵盖了协调器和工作节点的故障处理和主从切换的过程。可以参考Citus Data Blog【51†source】。

  2. Patroni和Citus的文档
    官方文档提供了有关Citus在Patroni中的配置及节点角色的信息,包括主从替换的机制。这是理解具体实现的良好起点,可以访问Patroni GitHub Documentation【52†source】。

  3. Citus和PostgreSQL高可用性
    这篇文章介绍了如何利用PostgreSQL的流复制与Citus实现高可用性,以及节点的主从替换策略。更多内容可以在Citus Open Source找到【53†source】。

这些资源提供了丰富的信息,有助于深入理解Citus在Patroni中如何处理CN和DN节点的主从替换过程。希望这些能对你有所帮助!

posted @   零の守墓人  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示