基于Patroni+etcd的PostgreSQL高可用集群部署与故障演练

张开发
2026/5/4 22:17:35 15 分钟阅读
基于Patroni+etcd的PostgreSQL高可用集群部署与故障演练
1. 为什么选择Patronietcd搭建PostgreSQL高可用集群第一次接触PostgreSQL高可用方案时我被各种专业术语搞得晕头转向。直到实际在生产环境部署了Patronietcd方案后才发现这套组合简直是运维工程师的福音。想象一下当你的数据库主节点突然宕机系统能在30秒内自动切换到备用节点业务几乎无感知——这就是Patroni带来的魔力。Patroni本质上是一个Python开发的守护进程它把PostgreSQL和分布式一致性存储如etcd粘合在一起。我特别喜欢它的无单点故障设计理念集群中每个PostgreSQL节点都运行一个Patroni进程这些进程通过etcd来协调状态完全去中心化。去年我们有个电商大促凌晨3点主库所在服务器硬件故障正是这套系统在28秒内完成了自动切换避免了数百万损失。etcd在这个架构中扮演着真理之源的角色。它用Raft算法保证集群状态的一致性相当于整个系统的大脑。我做过测试即使同时宕掉两个etcd节点三节点集群只要最后一个节点存活集群仍然能正常工作。这种设计特别适合对数据一致性要求严格的金融类应用。2. 生产环境部署实战指南2.1 基础环境准备在开始前我们需要准备至少三台服务器物理机或VM均可。我习惯用CentOS 7.9作为基础系统以下是必须完成的准备工作# 所有节点执行 sudo timedatectl set-timezone Asia/Shanghai sudo systemctl stop firewalld sudo setenforce 0网络配置是第一个容易踩坑的地方。建议为数据库集群划分独立VLAN确保节点间延迟低于1ms。我曾遇到过一个奇葩故障某台机器的MTU设置与其他节点不同导致大事务频繁超时。解决方法很简单# 检查并统一MTU值 ip link show | grep mtu sudo ip link set dev eth0 mtu 15002.2 etcd集群部署etcd的安装看似简单但配置不当会导致整个集群不稳定。这是我的优化配置模板以node1为例# /etc/etcd/etcd.conf ETCD_NAMEetcd01 ETCD_DATA_DIR/var/lib/etcd/etcd01.etcd ETCD_LISTEN_PEER_URLShttp://10.0.0.131:2380 ETCD_LISTEN_CLIENT_URLShttp://10.0.0.131:2379 ETCD_INITIAL_CLUSTER_TOKENetcd-cluster ETCD_INITIAL_CLUSTERetcd01http://10.0.0.131:2380,etcd02http://10.0.0.132:2380,etcd03http://10.0.0.133:2380启动后务必验证集群健康状态etcdctl --endpointshttp://10.0.0.131:2379 endpoint health etcdctl member list2.3 PostgreSQL与Patroni安装PostgreSQL 15的安装要注意编译参数。我推荐使用官方仓库sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install -y postgresql15-server postgresql15-contribPatroni的安装需要Python 3.6环境。遇到过pip安装超时的问题可以改用国内镜像pip install patroni[etcd] -i https://mirrors.aliyun.com/pypi/simple/3. 集群配置的艺术3.1 Patroni配置文件详解Patroni的YAML配置是整套系统的核心。这是我优化过的生产配置片段scope: pg_production namespace: /service/ restapi: listen: 10.0.0.131:8008 etcd: hosts: 10.0.0.131:2379,10.0.0.132:2379,10.0.0.133:2379 bootstrap: dcs: ttl: 30 loop_wait: 10 retry_timeout: 10 postgresql: use_pg_rewind: true parameters: wal_level: logical hot_standby: on max_connections: 500特别注意use_pg_rewind参数它允许节点在脱离集群后自动恢复同步避免了重建从库的麻烦。上周我们一个从库因为网络分区落后主库20GB就是这个功能让它自动追上了数据。3.2 高可用VIP配置生产环境通常需要虚拟IPVIP来屏蔽后端切换细节。这个回调脚本会在角色变更时自动管理VIP#!/bin/bash VIP10.0.0.100 case $1 in on_role_change) if [ $2 master ]; then /sbin/ip addr add $VIP/24 dev eth0 else /sbin/ip addr del $VIP/24 dev eth0 fi ;; esac记得给postgres用户添加sudo权限echo postgres ALL(ALL) NOPASSWD: /sbin/ip /etc/sudoers4. 故障演练从理论到实践4.1 模拟主节点宕机真正的考验在于故障恢复能力。我常用的测试方法是直接kill主库PostgreSQL进程# 在主节点执行 sudo pkill -9 postgres然后用patronictl观察切换过程patronictl list pg_production正常情况下30秒内应该能看到新的leader被选举出来。如果切换超时检查etcd集群状态和网络延迟。4.2 手动切换Switchover有计划维护时需要手动切换主从。这个命令把主库从node1切换到node2patronictl switchover pg_production \ --master node1 \ --candidate node2 \ --force有个小技巧切换前先执行CHECKPOINT可以缩短切换时间。有次我们切换一个负载很重的主库没做检查点导致切换花了2分钟前端都报超时了。4.3 网络分区测试最复杂的故障场景是网络分区。我常用iptables模拟# 在主节点阻断etcd通信 sudo iptables -A INPUT -p tcp --dport 2379 -j DROP这时应该观察到原主库降级为从库新主库被选举出来网络恢复后原主库自动重新加入集群5. 日常运维关键技巧5.1 监控指标解读这些Prometheus指标最关键patroni_leader当前leader状态pg_replication_lag复制延迟MBetcd_server_has_leaderetcd健康状态我配置的告警规则是复制延迟超过100MB或etcd无leader持续30秒就触发PagerDuty告警。5.2 备份策略Patroni不负责备份需要配合WAL归档postgresql: parameters: archive_mode: on archive_command: test ! -f /backup/wal/%f cp %p /backup/wal/%f建议每天做一次基础备份pg_basebackup -D /backup/base/$(date %Y%m%d) -X stream5.3 版本升级步骤升级PostgreSQL小版本很安全在所有节点安装新版本RPM执行switchover将主库移到最空闲的节点逐个重启从库完成升级最后重启主库大版本升级则需要使用逻辑复制或pg_upgrade建议先在测试环境验证。

更多文章