一、为什么需要自动故障转移
数据库高可用是生产环境中的刚需。想象一下,半夜三点数据库主节点突然宕机,运维人员睡眼惺忪地爬起来手动切换——这种场景谁都不想遇到。PostgreSQL虽然自带流复制,但故障转移需要人工干预,这时候就需要像Patroni这样的工具来帮我们实现自动化。
Patroni是一个用于管理PostgreSQL高可用集群的Python工具,它通过分布式共识系统(比如etcd)来协调故障转移。etcd则是一个可靠的键值存储,常用于服务发现和配置共享。这俩搭档起来,能让PostgreSQL集群在主节点挂掉时,自动选举新的主节点,业务几乎无感知。
二、环境准备与组件安装
1. 基础环境
假设我们有三台服务器(192.168.1.10、192.168.1.11、192.168.1.12),操作系统是CentOS 7。
# 在所有节点上安装依赖
yum install -y python3 python3-devel gcc postgresql12 postgresql12-server postgresql12-contrib
2. 安装etcd集群
etcd需要部署在奇数个节点上以实现高可用。以下是在192.168.1.10上的配置示例:
# 下载etcd
wget https://github.com/etcd-io/etcd/releases/download/v3.4.16/etcd-v3.4.16-linux-amd64.tar.gz
tar -xvf etcd-v3.4.16-linux-amd64.tar.gz
cd etcd-v3.4.16-linux-amd64
# 启动etcd(实际生产环境建议用systemd管理)
nohup ./etcd --name etcd1 \
--data-dir /var/lib/etcd \
--initial-advertise-peer-urls http://192.168.1.10:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://192.168.1.10:2379 \
--initial-cluster "etcd1=http://192.168.1.10:2380,etcd2=http://192.168.1.11:2380,etcd3=http://192.168.1.12:2380" \
--initial-cluster-state new &
其他节点只需修改--name和IP地址即可。用etcdctl cluster-health验证集群状态。
3. 安装Patroni
Patroni可以通过pip安装:
pip3 install patroni[etcd]
三、配置Patroni管理PostgreSQL
1. 创建Patroni配置文件
以下是一个最小化的/etc/patroni.yml配置:
scope: pgcluster # 集群名称
namespace: /service/ # etcd中的路径
restapi:
listen: 0.0.0.0:8008 # Patroni管理API
connect_address: 192.168.1.10:8008
etcd:
hosts: "192.168.1.10:2379,192.168.1.11:2379,192.168.1.12:2379" # etcd集群地址
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
parameters:
max_connections: 100
shared_buffers: 1GB
postgresql:
listen: 0.0.0.0:5432
connect_address: 192.168.1.10:5432
data_dir: /var/lib/pgsql/12/data
bin_dir: /usr/pgsql-12/bin
pgpass: /tmp/pgpass
authentication:
replication:
username: replicator
password: "123456"
superuser:
username: postgres
password: "postgres"
2. 启动Patroni
patroni /etc/patroni.yml
其他节点启动前,记得修改restapi.connect_address和postgresql.connect_address。
四、测试故障转移
1. 查看集群状态
# 通过Patroni API检查
curl http://192.168.1.10:8008/cluster
输出会显示哪个节点是主库(role为master)。
2. 模拟主节点宕机
直接kill主节点的Patroni进程:
pkill -f patroni
等待10-30秒后,再次检查集群状态,会发现新的主节点被选举出来。
3. 验证数据同步
在原主节点恢复后,它会自动变成从库并同步新主库的数据:
# 在新主库上创建测试表
psql -h 192.168.1.11 -U postgres -c "CREATE TABLE test_failover(id int);"
# 在原主库上查询该表
psql -h 192.168.1.10 -U postgres -c "\d"
# 应该能看到test_failover表
五、技术细节与注意事项
1. 为什么选择etcd?
etcd比ZooKeeper更轻量,比Consul更适合与Patroni集成。它的watch机制可以实时监控节点状态变化。
2. 网络分区问题
如果etcd集群出现网络分区,可能导致脑裂。建议部署至少3个节点,并配置合理的ttl和loop_wait。
3. Patroni的监控
可以通过Prometheus抓取Patroni的/metrics端点,监控集群健康状态。
六、总结
Patroni+etcd的组合让PostgreSQL高可用变得非常简单。整个过程自动化,减少了人为操作的风险。当然,生产环境还需要考虑备份、监控等配套措施。如果你正在寻找一个开箱即用的PostgreSQL高可用方案,不妨试试这个组合。
评论