欢迎踏入 PostgreSQL 高可用性(HA)的精彩世界!在业务场景中,数据库的持续可用性是至关重要的,任何中断都可能引发严重后果。今天,我们将聚焦 Patroni,一个强大的开源工具,帮助您构建一个自动故障转移、自我修复的 PostgreSQL 高可用性集群。本文将以通俗易懂、循序渐进的教学风格,带您了解 Patroni 如何实现高可用性,核心配置步骤,以及如何在实践中确保数据库“永不宕机”。无论您是数据库新手还是经验丰富的 DBA,这篇文章都将为您提供清晰的指引!
类比讲解:Patroni 就像一支训练有素的消防队。PostgreSQL 节点是消防员,分布式配置存储(DCS)是指挥中心,HAProxy 是报警电话,而 Patroni 确保当火灾(主节点故障)发生时,备用消防员(从节点)迅速接管,扑灭火焰(服务中断),让城市(业务)安全无忧!
1. Patroni 如何实现高可用性?
1.1 Patroni 的核心机制
Patroni 是一个基于 Python 的工具,结合 PostgreSQL 的**流复制(Streaming Replication)**和分布式配置存储(DCS),实现高可用性。它的核心机制包括:
- 自动故障转移:当主节点(Primary)故障时,Patroni 使用分布式共识算法(通过 DCS,如 etcd)选举一个从节点(Replica)为主节点,确保服务不中断。
- 节点健康监控:Patroni 在每个节点运行,定期检查 PostgreSQL 的状态(如复制延迟、运行状态),并通过 REST API 报告。
- 动态配置管理:通过 DCS(如 etcd、Consul、ZooKeeper)存储集群状态(如主节点信息、配置),确保所有节点保持一致。
- 负载均衡:结合 HAProxy 或 PgBouncer,Patroni 提供统一的访问入口,写请求路由到主节点,读请求分发到从节点。
- 自我修复:故障节点恢复后,Patroni 自动重新初始化并加入集群,使用
pg_rewind
修复数据不一致。
类比讲解:Patroni 是集群的“心脏起搏器”。当心脏(主节点)停跳,起搏器迅速激活备用电源(从节点),并通过电线(DCS)协调节奏,确保心脏(服务)继续跳动!
1.2 为什么 Patroni 适合高可用性?
相比 PostgreSQL 原生流复制,Patroni 解决了以下痛点:
- 无自动故障转移:原生复制需要手动切换主节点。
- 节点恢复复杂:故障节点需手动重新配置。
- 缺乏统一管理:原生工具无法监控集群状态。
Patroni 的优势:
- 自动化:故障转移和恢复全自动,减少人工干预。
- 灵活性:支持多种 DCS(etcd、Consul、ZooKeeper、Kubernetes)。
- 可扩展性:轻松添加从节点,提升读性能。
- 健壮性:集成备份工具(如 pgBackRest),确保数据安全。
教学小贴士:Patroni 就像自动驾驶系统。您只需设定目的地(高可用性),它会自动导航(故障转移)、避障(节点恢复),让旅程(数据库服务)安全顺畅!
2. Patroni 高可用性架构
一个典型的 Patroni 高可用性集群包括:
- PostgreSQL 节点:一个主节点(写)和多个从节点(读),通过流复制同步。
- Patroni 代理:运行在每个节点,管理 PostgreSQL 生命周期(启动、停止、故障转移)。
- 分布式配置存储(DCS):如 etcd,存储集群状态和锁机制。
- 负载均衡器:HAProxy 路由写请求到主节点,读请求到从节点。
- 备份工具(可选):pgBackRest 提供备份和点对恢复(PITR)。
架构示意图:
客户端 <-> HAProxy <-> [主节点 + Patroni] <-> [从节点 + Patroni]
| |
+-------> etcd <----------+
(分布式配置存储)
类比讲解:Patroni 集群像一个智能厨房。PostgreSQL 节点是厨师,Patroni 是主厨,etcd 是食谱,HAProxy 是服务员,引导客人(请求)到正确的厨师(节点)。
3. 配置 Patroni 高可用性集群
以下是搭建一个简单 Patroni 集群的步骤,基于 Ubuntu 20.04,包含 2 个 PostgreSQL 节点(node1: 192.168.1.101, node2: 192.168.1.102)和 1 个 etcd/HAProxy 节点(192.168.1.103)。
3.1 准备工作
- 操作系统:Ubuntu 20.04。
- 节点:3 台服务器,IP 如上。
- 端口:开放 5432(PostgreSQL)、8008(Patroni API)、2379/2380(etcd)、5000/5001(HAProxy)。
- 软件:PostgreSQL 14、Patroni、etcd、HAProxy。
教学小贴士:准备工作像布置教室。确保每个学生(节点)有课本(软件)和座位(网络配置),才能开始上课(集群搭建)!
3.2 安装软件
在所有节点上执行:
-
安装 PostgreSQL:
1 2 3 4
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo apt update sudo apt install -y postgresql-14
-
安装 Patroni 和依赖:
1 2
sudo apt install -y python3 python3-pip sudo pip3 install patroni python-etcd psycopg2-binary
-
停止默认 PostgreSQL:
1 2
sudo systemctl stop postgresql sudo systemctl disable postgresql
在 etcd/HAProxy 节点(192.168.1.103): 4. 安装 etcd 和 HAProxy:
|
|
3.3 配置 etcd
In 192.168.1.103 上:
-
编辑 etcd 配置文件(/etc/default/etcd):
1
sudo vi /etc/default/etcd
配置单节点 etcd:
ETCD_LISTEN_PEER_URLS="http://192.168.1.103:2380" ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://192.168.1.103:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.103:2380" ETCD_INITIAL_CLUSTER="etcd0=http://192.168.1.103:2380" ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.103:2379" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"
-
启动 etcd:
1 2
sudo systemctl restart etcd sudo systemctl enable etcd
-
验证:
1
etcdctl member list
类比讲解:etcd 是集群的“指挥塔”,记录谁是队长(主节点)。配置 etcd 就像调试对讲机,确保指令清晰传达!
3.4 配置 Patroni
在 node1 和 node2 上:
-
创建数据目录:
1 2 3
sudo mkdir -p /data/pgsql sudo chown postgres:postgres /data/pgsql sudo chmod 700 /data/pgsql
-
创建 Patroni 配置文件(/etc/patroni.yml): 在 node1 (192.168.1.101):
1 2
sudo mkdir /etc/patroni sudo vi /etc/patroni/patroni.yml
添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
scope: postgres name: node1 restapi: listen: 192.168.1.101:8008 connect_address: 192.168.1.101:8008 etcd: host: 192.168.1.103:2379 bootstrap: dcs: ttl: 30 loop_wait: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true initdb: - encoding: UTF8 - data-checksums pg_hba: - host replication replicator 192.168.1.0/24 md5 - host all all 0.0.0.0/0 md5 postgresql: listen: 192.168.1.101:5432 connect_address: 192.168.1.101:5432 data_dir: /data/pgsql authentication: replication: username: replicator password: replicator superuser: username: postgres password: supersecret
在 node2 (192.168.1.102),复制并修改:
name: node2
restapi.listen
和connect_address
:改为192.168.1.102:8008
postgresql.listen
和connect_address
:改为192.168.1.102:5432
-
设置权限:
1 2
sudo chown postgres:postgres /etc/patroni/patroni.yml sudo chmod 600 /etc/patroni/patroni.yml
-
创建 Patroni 服务:
1
sudo vi /etc/systemd/system/patroni.service
添加:
[Unit] Description=Patroni PostgreSQL Cluster After=network.target [Service] User=postgres Group=postgres ExecStart=/usr/local/bin/patroni /etc/patroni.yml Restart=on-failure [Install] WantedBy=multi-user.target
-
启动 Patroni:
1 2 3
sudo systemctl daemon-reload sudo systemctl enable patroni sudo systemctl start patroni
3.5 配置 HAProxy
在 192.168.1.103 上:
-
编辑 HAProxy 配置文件(/etc/haproxy/haproxy.cfg):
1
sudo vi /etc/haproxy/haproxy.cfg
添加:
global maxconn 1000 user haproxy group haproxy defaults mode tcp timeout connect 5000ms timeout client 50000ms timeout server 50000ms frontend postgres_write bind *:5000 mode tcp option httpchk GET /master default_backend postgres_write_backend backend postgres_write_backend mode tcp option httpchk GET /master server node1 192.168.1.101:5432 check port 8008 server node2 192.168.1.102:5432 check port 8008 frontend postgres_read bind *:5001 mode tcp default_backend postgres_read_backend backend postgres_read_backend mode tcp balance roundrobin server node1 192.168.1.101:5432 server node2 192.168.1.102:5432
-
重启 HAProxy:
1 2
sudo systemctl restart haproxy sudo systemctl enable haproxy
3.6 验证集群
-
检查状态:
1
sudo -u postgres patronictl -c /etc/patroni.yml list
输出示例:
+ Cluster: postgres ---+----+-----------+ | Member | Host | Role | State | TL | Lag | +--------+-----------------+--------+---------+----+-----+ | node1 | 192.168.1.101 | Leader | running | 1 | | | node2 | 192.168.1.102 | Replica| running | 1 | 0 | +--------+-----------------+--------+---------+----+-----+
-
测试连接:
1
psql -h 192.168.1.103 -p 5000 -U postgres
-
模拟故障转移: 停止 node1 的 Patroni:
1
sudo systemctl stop patroni
再次检查状态,node2 应成为 Leader。
教学小贴士:配置 Patroni 像组装模型飞机。每个零件(etcd、Patroni、HAProxy)必须精确对接,试飞(验证)确保飞机(集群)平稳起飞!
4. 优化与注意事项
4.1 优化建议
- 多节点 DCS:部署 3 或 5 个 etcd 节点,避免单点故障:
1 2
etcd: hosts: 192.168.1.103:2379,192.168.1.104:2379,192.168.1.105:2379
- 备份:集成 pgBackRest:
1 2
sudo apt install pgbackrest sudo pgbackrest --stanza=pg_cluster backup
- 监控:使用 Prometheus 或 PMM 监控复制延迟和节点状态。
- 复制延迟:调整
maximum_lag_on_failover
和 WAL 参数:1 2 3 4
postgresql: parameters: wal_buffers: 16MB max_wal_senders: 10
4.2 注意事项
- 防火墙:限制公网访问,仅开放必要端口。
- 日志检查:故障时查看 Patroni 日志:
1
journalctl -u patroni
- 统计信息:定期运行
ANALYZE
优化查询计划。 - 权限:确保 pg_hba.conf 允许复制:
1
host replication replicator 192.168.1.0/24 md5
类比讲解:优化 Patroni 像调校赛车。调整引擎(etcd)、加装导航(监控)、检查轮胎(备份),让赛车(集群)跑得更快、更稳!
5. 总结与进阶建议
通过本文,您学会了如何使用 Patroni 实现 PostgreSQL 高可用性,包括核心机制、配置步骤和优化技巧。Patroni 通过自动故障转移、分布式共识和负载均衡,确保数据库服务持续可用。
进阶建议:
- 阅读 Patroni 文档:patroni.readthedocs.io.
- 实践多节点 etcd 和 pgBackRest 配置。
- 使用 REST API 开发监控脚本:
1
curl http://192.168.1.101:8008/health
- 探索 Kubernetes 集成,简化 Patroni 部署。
希望这篇文章为您的 PostgreSQL 高可用性之旅提供实用指导!欢迎在博客评论区分享您的 Patroni 经验!
评论 0