跳到主要内容PostgreSQL 高可用集群部署指南 | 极客日志SQL
PostgreSQL 高可用集群部署指南
综述由AI生成档详细介绍了基于 Patroni、etcd、HAProxy 和 Keepalived 构建 PostgreSQL 高可用集群的完整部署流程。内容涵盖环境准备、组件安装配置、读写分离、故障转移测试及监控维护。方案支持自动故障切换、负载均衡和虚拟 IP 漂移,旨在为生产环境提供稳定可靠的数据库高可用架构解决方案。
随缘29 浏览 PostgreSQL 高可用集群部署指南
概述
本指南基于 Patroni + etcd 方案,提供完整的 PostgreSQL 高可用集群部署流程。该方案支持自动故障转移、读写分离、负载均衡等功能,确保数据库的高可用性和可扩展性。
架构组件
- PostgreSQL 12.17: 核心数据库
- Patroni: 集群管理和自动故障转移
- etcd: 分布式键值存储,作为集群状态存储
- HAProxy: 负载均衡器和读写分离
- Keepalived: 虚拟 IP 漂移和高可用
集群规划
本部署使用 3 节点架构:
- node1: 192.168.95.139
- node2: 192.168.95.140
- node3: 192.168.95.141
环境准备
1. 系统要求
- CentOS 7.x
- Python 3.6+
- 3 台物理机或虚拟机
- 网络互通,防火墙开放必要端口
2. 升级 Python 环境
yum install -y python3 python3-pip
alternatives --install /usr/bin/python python /usr/bin/python3 60
3. 创建必要目录
mkdir -p /u1/pgsql/data
mkdir -p /etc/patroni/
mkdir -p /tmp/patroni02
组件安装和配置
1. 安装和配置 etcd 集群
1.1 安装 etcd
yum install etcd -y
1.2 配置 etcd 集群
节点 1 配置 (/etc/etcd/etcd.conf):
ETCD_DATA_DIR="/var/lib/etcd/codis.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_NAME=
ETCD_INITIAL_ADVERTISE_PEER_URLS=
ETCD_ADVERTISE_CLIENT_URLS=
ETCD_INITIAL_CLUSTER=
ETCD_INITIAL_CLUSTER_TOKEN=
ETCD_INITIAL_CLUSTER_STATE=
"node1"
"http://192.168.95.139:2380"
"http://192.168.95.139:2379"
"node1=http://192.168.95.139:2380,node2=http://192.168.95.140:2380,node3=http://192.168.95.141:2380"
"etcd-cluster"
"new"
节点 2 配置 (/etc/etcd/etcd.conf):
ETCD_DATA_DIR="/var/lib/etcd/codis.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_NAME="node2"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.95.140:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.95.140:2379"
ETCD_INITIAL_CLUSTER="node1=http://192.168.95.139:2380,node2=http://192.168.95.140:2380,node3=http://192.168.95.141:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
节点 3 配置 (/etc/etcd/etcd.conf):
ETCD_DATA_DIR="/var/lib/etcd/codis.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_NAME="node3"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.95.141:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.95.141:2379"
ETCD_INITIAL_CLUSTER="node1=http://192.168.95.139:2380,node2=http://192.168.95.140:2380,node3=http://192.168.95.141:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
1.3 启动 etcd 服务
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
etcdctl member list
etcdctl --endpoints http://192.168.95.141:2379 cluster-health
1.4 安装 etcd-viewer(可选)
docker pull dontpanic57/etcd-viewer
docker run -d -p 8080:8080 dontpanic57/etcd-viewer
2. 安装 PostgreSQL 12.17
2.1 离线安装 PostgreSQL
- postgresql12-libs-12.17-1PGDG.rhel7.x86_64.rpm
- postgresql12-12.17-1PGDG.rhel7.x86_64.rpm
- postgresql12-server-12.17-1PGDG.rhel7.x86_64.rpm
- postgresql12-contrib-12.17-1PGDG.rhel7.x86_64.rpm
rpm -ivh postgresql12-libs-12.17-1PGDG.rhel7.x86_64.rpm
rpm -ivh postgresql12-12.17-1PGDG.rhel7.x86_64.rpm
rpm -ivh postgresql12-server-12.17-1PGDG.rhel7.x86_64.rpm
rpm -ivh postgresql12-contrib-12.17-1PGDG.rhel7.x86_64.rpm
yum install --downloadonly --downloaddir=/pg12_rpm libicu
yum install -y libicu-50.2-4.el7_7.x86_64.rpm
2.2 配置 PostgreSQL 数据目录
chown postgres:postgres /u1/pgsql
chmod -R 700 /u1/pgsql
3. 安装和配置 Patroni
3.1 安装 Patroni
pip install psycopg2-binary -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com
pip3 install patroni[etcd] -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com
which patroni
yum remove python-pip
ln -sf /usr/local/python3/bin/pip /usr/bin/pip
yum install python3-pip python3 python2 python2-pip
3.2 创建 .pgpass 文件
su - postgres
echo "192.168.95.139:5432:postgres:postgres:postgres123"> ~/.pgpass
echo "192.168.95.140:5432:postgres:postgres:postgres123">> ~/.pgpass
echo "192.168.95.141:5432:postgres:postgres:postgres123">> ~/.pgpass
chmod 600 ~/.pgpass
exit
3.3 创建 Patroni 配置文件
节点 1 配置 (/etc/patroni/patroni_postgresql.yml):
scope: postgresql12
namespace: /postgresql/
name: node1
log:
level: INFO
traceback_level: ERROR
dir: /tmp/patroni02
file_num: 10
file_size: 104857600
restapi:
listen: 192.168.95.139:8008
connect_address: 192.168.95.139:8008
etcd:
hosts:
- 192.168.95.139:2379
- 192.168.95.140:2379
- 192.168.95.141:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
master_start_timeout: 300
synchronous_mode: false
postgresql:
use_pg_rewind: true
use_slots: true
parameters:
listen_addresses: "*"
wal_level: logical
hot_standby: "on"
wal_keep_segments: 10
max_wal_senders: 10
max_replication_slots: 10
wal_log_hints: "on"
initdb:
- encoding: UTF8
- locale: C
- lc-ctype: zh_CN.UTF-8
- data-checksums
pg_hba:
- host replication postgres 0.0.0.0/0 md5
- host all all 0.0.0.0/0 md5
postgresql:
listen: 0.0.0.0:5432
connect_address: 192.168.95.139:5432
data_dir: /u1/pgsql/data
bin_dir: /usr/pgsql-12/bin
config_dir: /u1/pgsql/data
pgpass: /var/lib/pgsql/.pgpass
authentication:
replication:
username: postgres
password: postgres123
superuser:
username: postgres
password: postgres123
rewind:
username: postgres
password: postgres123
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
节点 2 配置(修改对应 IP 为 192.168.95.140)和节点 3 配置(修改对应 IP 为 192.168.95.141)同理,只需更改 name、listen、connect_address 和 pgpass 配置。
3.4 设置权限和目录
chown -R postgres.postgres /etc/patroni/
chmod 600 /etc/patroni/patroni_postgresql.yml
chown -R postgres.postgres /tmp/patroni02
3.5 创建 Patroni 系统服务
创建服务文件 (/usr/lib/systemd/system/patroni.service):
[Unit]
Description=High availability PostgreSQL Cluster
After=syslog.target network.target
[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/local/bin/patroni /etc/patroni/patroni_postgresql.yml
KillMode=process
TimeoutSec=30
Restart=no
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable patroni
systemctl start patroni
3.6 验证集群状态
patronictl -c /etc/patroni/patroni_postgresql.yml list
yum install python3-psycopg2
+ Cluster: postgresql12 (6965741508141313244) ---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | +-----------+------------------+---------+---------+----+-----------+ | node1 | 192.168.95.139 | Leader | running | 1 | | | node2 | 192.168.95.140 | Replica | running | 1 | 0.0 | | node3 | 192.168.95.141 | Replica | running | 1 | 0.0 | +-----------+------------------+---------+---------+----+-----------+
3.7 手动故障转移测试
patronictl -c /etc/patroni/patroni_postgresql.yml switchover
高可用组件配置
1. 安装和配置 HAProxy
1.1 安装 HAProxy
1.2 配置 HAProxy
配置文件 (/etc/haproxy/haproxy.cfg):
global
maxconn 100
log 127.0.0.1 local2
defaults
log global
mode tcp
retries 2
timeout client 30m
timeout connect 4s
timeout server 30m
timeout check 5s
listen stats
mode http
bind *:7000
stats enable
stats uri /
listen pgsql
mode tcp
bind *:5000
option httpchk http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server postgresql_192.168.95.139_5432 192.168.95.139:5432 maxconn 100 check port 8008
server postgresql_192.168.95.140_5432 192.168.95.140:5432 maxconn 100 check port 8008
server postgresql_192.168.95.141_5432 192.168.95.141:5432 maxconn 100 check port 8008
listen pgsql_read
mode tcp
bind *:6000
option httpchk GET /replica
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server postgresql_192.168.95.139_5432 192.168.95.139:5432 maxconn 100 check port 8008
server postgresql_192.168.95.140_5432 192.168.95.140:5432 maxconn 100 check port 8008
server postgresql_192.168.95.141_5432 192.168.95.141:5432 maxconn 100 check port 8008
1.3 启动 HAProxy
systemctl enable haproxy
systemctl start haproxy
setsebool -P haproxy_connect_any=1
2. 安装和配置 Keepalived
2.1 安装 Keepalived
yum install -y keepalived
2.2 配置 Keepalived
node1 配置 (/etc/keepalived/keepalived.conf):
global_defs {
router_id LVS_DEVEL
}
vrrp_script check_haproxy {
script "pgrep -x haproxy"
interval 2
weight 10
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 210
priority 90
advert_int 1
track_script {
check_haproxy
}
virtual_ipaddress {
192.168.95.142
}
}
node2 配置(将 priority 改为 80,其他相同)
2.3 启动 Keepalived
systemctl enable keepalived
systemctl start keepalived
ip addr show dev ens33
数据库连接配置
1. 应用数据库配置
根据您的项目 application-dev.yml,当前使用 Oracle 数据库。要切换到 PostgreSQL 高可用集群,需要修改配置:
spring:
datasource:
url: jdbc:postgresql://192.168.95.142:5000/postgres
username: postgres
password: postgres123
2. 连接字符串配置选项
2.1 JDBC 多主机 URL
jdbc:postgresql://192.168.95.139:5432,192.168.95.140:5432,192.168.95.141:5432/postgres?targetServerType=primary
jdbc:postgresql://192.168.95.139:5432,192.168.95.140:5432,192.168.95.141:5432/postgres?targetServerType=preferSecondary&loadBalanceHosts=true
jdbc:postgresql://192.168.95.139:5432,192.168.95.140:5432,192.168.95.141:5432/postgres?targetServerType=any&loadBalanceHosts=true
2.2 HAProxy 代理配置
- 写操作:
192.168.95.142:5000
- 读操作:
192.168.95.142:6000
- 状态监控:
http://192.168.95.142:7000
高级配置
1. 级联复制配置
1.1 集群内部级联复制
tags:
replicatefrom: node2
1.2 集群间级联复制
bootstrap:
dcs:
standby_cluster:
host: 192.168.234.210
port: 5432
primary_slot_name: slot1
create_replica_methods:
- basebackup
2. 复制槽配置
bootstrap:
dcs:
slots:
slot1:
type: physical
监控和维护
1. 集群状态监控
1.1 Patroni 状态查询
patronictl -c /etc/patroni/patroni_postgresql.yml list
patronictl -c /etc/patroni/patroni_postgresql.yml query
patronictl -c /etc/patroni/patroni_postgresql.yml show
1.2 PostgreSQL 状态监控
psql -h 192.168.95.139 -U postgres -c "SELECT * FROM pg_stat_replication;"
2. 日志查看
tail -f /tmp/patroni02/patroni.log
tail -f /u1/pgsql/data/log/postgresql-*.log
journalctl -u etcd -f
3. 性能优化配置
在 Patroni 配置的 parameters 部分添加优化参数:
postgresql:
parameters:
shared_buffers: 256MB
effective_cache_size: 1GB
work_mem: 4MB
maintenance_work_mem: 64MB
max_connections: 100
wal_buffers: 16MB
checkpoint_completion_target: 0.9
random_page_cost: 1.1
effective_io_concurrency: 200
故障处理
1. 常见问题解决
1.1 Patroni 启动失败
pgpass: /var/lib/pgsql/.pgpass
1.2 集群初始化失败
rm -rf /u1/pgsql/data/*
systemctl restart patroni
1.3 HAProxy 启动失败
setsebool -P haproxy_connect_any=1
setenforce 0
1.4 Keepalived 虚拟 IP 不生效
ip addr show dev ens33
firewall-cmd --add-rich-rule='rule family="ipv4" destination address="192.168.95.142" accept'
2. 应急处理流程
2.1 主库故障处理
patronictl -c /etc/patroni/patroni_postgresql.yml switchover
patronictl -c /etc/patroni/patroni_postgresql.yml list
2.2 节点恢复流程
- 修复节点: 解决硬件或系统问题
- 验证同步状态: 确认数据同步完成
systemctl restart patroni
2.3 数据恢复流程
sudo -u postgres pg_ctl -D /u1/pgsql/data stop
rm -rf /u1/pgsql/data/*
systemctl start patroni
备份和恢复
1. 自动备份配置
创建备份脚本 (/usr/local/bin/pg_backup.sh):
#!/bin/bash
BACKUP_DIR="/backup/pg"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
mkdir -p $BACKUP_DIR
psql -h 192.168.95.139 -U postgres -c "SELECT pg_start_backup('backup_$DATE');"
tar -czf $BACKUP_DIR/pg_data_$DATE.tar.gz -C /u1/pgsql/data .
psql -h 192.168.95.139 -U postgres -c "SELECT pg_stop_backup();"
find $BACKUP_DIR -name "pg_data_*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: pg_data_$DATE.tar.gz"
chmod +x /usr/local/bin/pg_backup.sh
echo "0 2 * * * /usr/local/bin/pg_backup.sh" | crontab -
2. 恢复操作
systemctl stop patroni
mv /u1/pgsql/data /u1/pgsql/data.backup
mkdir -p /u1/pgsql/data
tar -xzf /backup/pg/pg_data_YYYYMMDD_HHMMSS.tar.gz -C /u1/pgsql/data
chown -R postgres:postgres /u1/pgsql/data
chmod 700 /u1/pgsql/data
systemctl start patroni
总结
本部署指南提供了完整的 PostgreSQL 高可用集群部署方案,包含以下核心功能:
- ✅ 高可用性: 基于 Patroni 的自动故障转移
- ✅ 读写分离: HAProxy 代理的读写流量分离
- ✅ 负载均衡: 多节点负载分发
- ✅ 虚拟 IP: Keepalived 提供的透明高可用
- ✅ 监控界面: HAProxy 统计页面
- ✅ 扩展性: 支持动态添加节点
生产环境注意事项
- 安全配置:
- 启用 SSL/TLS 加密
- 配置防火墙规则
- 设置强密码策略
- 性能优化:
- 根据硬件配置调整参数
- 监控系统性能指标
- 定期进行性能评估
- 容灾备份:
- 维护计划:
- 定期更新系统补丁
- 监控磁盘空间使用
- 检查系统日志异常
通过以上配置,您可以获得一个稳定、高可用的 PostgreSQL 集群环境。
相关免费在线工具
- SQL 美化和格式化
在线格式化和美化您的 SQL 查询(它支持各种 SQL 方言)。 在线工具,SQL 美化和格式化在线工具,online
- SQL转CSV/JSON/XML
解析 INSERT 等受限 SQL,导出为 CSV、JSON、XML、YAML、HTML 表格(见页内语法说明)。 在线工具,SQL转CSV/JSON/XML在线工具,online
- CSV 工具包
CSV 与 JSON/XML/HTML/TSV/SQL 等互转,单页多 Tab。 在线工具,CSV 工具包在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online