Pgpool-II实现高可用+读写分离+负载均衡(二)---- 配置篇

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: Pgpool-II是一款工作在PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件。提供了连接池、复制、负载均衡、限制过多连接、看门狗、查询缓存等功能。本篇介绍详细配置。


一、Pgpool-II配置

1.1 PostgreSQL相关配置

本例Postgresql安装在/usr/local/pgsql16目录,Pgpool-II安装在/home/postgres/pgpool目录。

1.在PostgreSQL主节点(db01)上设置流复制

# 根据规划,创建归档日志目录su- postgres
mkdir /data/pgsql16/archive
# 在主节点初始化数据库(如果你已经初始化了数据库,可跳过此步骤)# 以postgres用户身份执行/usr/local/pgsql16/bin/initdb -D /home/pgsql16/data -E utf8 -W# 修改/home/pgsql16/data/postgresql.conf文件listen_addresses ='*'archive_mode = on
archive_command ='cp "%p" "/home/pgsql16/archive/%f"'max_wal_senders =10max_replication_slots =10wal_level = replica
hot_standby = on
wal_log_hints = on

在主节点启动后,我们将使用Pgpool-II的在线恢复(Online Recovery)功能设置从节点。

2.创建相关用户

基于安全考虑,创建repl用户用于流复制,pgpool用户用于流复制延迟检查及Pgpool健康检查。

用户名

密码

描述

repl repl PostgreSQL复制用户
pgpool pgpool Pgpool-II健康检查 (health_check_use)及复制延迟检查 (sr_check_user) 用户
postgres postgres

运行在线恢复的用户

[db01]# psql -U postgres -p 5432postgres=# SET password_encryption = 'scram-sha-256';postgres=# CREATE ROLE pgpool WITH LOGIN;postgres=# CREATE ROLE repl WITH REPLICATION LOGIN;postgres=# \password pgpoolpostgres=# \password repl

如果想在show pool_nodes的结果里显示"replication_state"和"replication_sync_state"列,pgpool用户需要有数据库的超级用户权限或者添加到pg_monitor组(>=Pgpool-II 4.1):

GRANT pg_monitor TO pgpool;

修改/data/pgsql16/data/pg_hba.conf,允许子网内其它节点访问主节点并开启scram-sha-256认证

host    all             all             192.168.0.0/24                 scram-sha-256
host    replication     all             192.168.0.0/24                 scram-sha-256

3.设置主从节点postgres用户ssh免密登录

如果要使用自动故障转移和在线恢复功能,需要设置主从节点间postgres用户免密登录,为方便配置时在各节点间复制文件,可先给postgres用户设置一个密码,配置完成后再删除密码。

# 在root用户下执行# passwd postgres

在每个节点上执行如下命令创建ssh密钥,并将公钥分发到各个节点,这里假设创建的密钥名为id_rsa_pgpool。

[all servers]# mkdir ~/.ssh[all servers]# chmod 700 ~/.ssh[all servers]# cd ~/.ssh[all servers]# ssh-keygen -t rsa -f id_rsa_pgpool[all servers]# ssh-copy-id -i id_rsa_pgpool.pub postgres@server1[all servers]# ssh-copy-id -i id_rsa_pgpool.pub postgres@server2[all servers]# ssh-copy-id -i id_rsa_pgpool.pub postgres@server3[all servers]# su - postgres[all servers]$ mkdir ~/.ssh
[all servers]$ chmod700 ~/.ssh
[all servers]$ cd ~/.ssh
[all servers]$ ssh-keygen-t rsa -f id_rsa_pgpool
[all servers]$ ssh-copy-id-i id_rsa_pgpool.pub postgres@server1
[all servers]$ ssh-copy-id-i id_rsa_pgpool.pub postgres@server2
[all servers]$ ssh-copy-id-i id_rsa_pgpool.pub postgres@server3
                             ......

密钥创建分发完成后,执行ssh postgres@db0x -i ~/.ssh/id_rsa_pgpool,检查是否不需要输入密码就可以登录成功。如果无法使用公钥登录,需要检查相关配置:

  • 检查/etc/ssh/sshd_config文件PubkeyAuthentication选项是否为 yes
  • 如果运行ssh-copy-id时无法通过密码登录其他节点,可在/etc/ssh/sshd_config文件中临时设置PasswordAuthentication yes
  • 如果启用了selinux,ssh免密登录也可能会失败,可做如下操作:
[all servers]# su - postgres[all servers]$ restorecon-Rv ~/.ssh

确保几个节点相互之间均可以通过ssh免密码登录后,继续配置。

4.建立PostgreSQL密码文件

在流复制跟在线recovery时需要repl用户密码,执行pg_rewind时需要postgres超级用户的密码,因此需要在postgres的家目录下创建.pgpass密码文件(重要!!!):

[all servers]# su - postgres[all servers]$ vi$HOME/.pgpass
server1:5432:replication:repl:<repl user password>
server2:5432:replication:repl:<repl user password>
server3:5432:replication:repl:<repl user password>
server1:5432:postgres:postgres:<postgres user password>
server2:5432:postgres:postgres:<postgres user password>
server3:5432:postgres:postgres:<postgres user password>
[all servers]$ chmod600$HOME/.pgpass

创建完成后用scp复制到其他节点的postgres家目录下。

5.防火墙设置

如果启用了防火墙,需要设置防火墙允许相应端口:

[all servers]# firewall-cmd --permanent --zone=public --add-service=postgresql[all servers]# firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp --add-port=9000/tcp  --add-port=9694/udp[all servers]# firewall-cmd --reload

6.创建节点文件pgpool_node_id

需要在每个节点机的/home/postgresql/pgpool/etc目录下创建一个节点文件pgpool_node_id用于标识节点ID,以便看门狗识别每个节点,每个节点ID不能相同。

[server1]# cat /etc/pgpool-II/pgpool_node_id0[sever2]# cat /etc/pgpool-II/pgpool_node_id1[server3]# cat /etc/pgpool-II/pgpool_node_id2

1.2 Pgpool-II配置

源码安装,配置文件在/home/postgres/pgpool/etc目录下,复制pgpool.conf.sample文件为pgpool.conf,然后修改相应选项。

1.集群模式

Pgpool-II支持多种集群模式,这里推荐使用PostgreSQL的流复制模式

backend_clustering_mode ='streaming_replication'

2.侦听地址、端口号

listen_addresses ='*'port =9999

3.流复制检查

sr_check_user ='pgpool'#密码置空,使用pool_passwd文件sr_check_password =''

4.健康检查

启用运行状况检查,以便Pgpool-II执行故障切换。此外,如果网络不稳定,即使后端运行正常,健康检查也会失败,可能会发生故障切换或退化操作。为了防止此类错误检测运行状况检查,我们将Health_check_max_reries设置为3。

health_check_period =5health_check_timeout =30health_check_user ='pgpool'#密码置空,使用pool_passwd文件health_check_password =''health_check_max_retries =3

5.PostgreSQL服务端设置

本例添加了三个节点

backend_hostname0 ='server1'#主机名或IP地址backend_port0 =5432backend_weight0 =1backend_data_directory0 ='/data/pgsql16/data'backend_flag0 ='ALLOW_TO_FAILOVER'backend_hostname1 ='server2'backend_port1 =5432backend_weight1 =1backend_data_directory1 ='/data/pgsql16/data'backend_flag1 ='ALLOW_TO_FAILOVER'backend_hostname2 ='server3'backend_port2 =5432backend_weight2 =1backend_data_directory2 ='/data/pgsql16/data'backend_flag2 ='ALLOW_TO_FAILOVER'

如果想在show pool_nodes的结果里显示"replication_state" and "replication_sync_state"列,需要设置backend_application_name参数。这里我们设置成后端主机名。(>=Pgpool-II 4.1)

...
backend_application_name0 ='server1'...
backend_application_name1 ='server2'...
backend_application_name2 ='server3'

6.故障转移配置

在failover_command参数中指定故障转移后要执行的failover.sh脚本。如果我们使用3台PostgreSQL服务器,则需要指定flow_primary_command用于在主节点故障转移后进行后续处理。如果有两台PostgreSQL服务器,则不需要设置flow_primary_command

failover_command ='/home/postgres/pgpool/etc/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'follow_primary_command ='/home/postgres/pgpool/etc/follow_primary.sh %d %h %p %D %m %H %M %P %r %R'

/home/postgres/pgpool/etc目录下有相关脚本的的示例文件,需要根据自身情况做相应的修改。修改完成后scp到其他节点相同目录下。

[all servers]# cd /home/postgres/pgpool/etc[all servers]# cp -p failover.sh.sample failover.sh[all servers]# cp -p follow_primary.sh.sample follow_primary.sh[all servers]# chown postgres:postgres failover.sh follow_primary.sh# 这两个脚本文件主要修改PG_HOME这一项,改为自己的PostgreSQL安装目录

follow_primary_command所设置的脚本follow_primary.sh脚本还需要执行pcp命令,还需要做pcp密码验证,因些还要修改follow_primary.sh的PCP_USER参数,这里我们使用pgpool用户。

# cat /home/postgres/pgpool/etc/follow_primary.sh...
PCP_USER=pgpool
...

使用pg_md5程序加密pgpol密码并保存到/home/postgres/pgpool/etc/pcp.conf文件中:

[all servers]# echo 'pgpool:'`pg_md5 pgpool密码` >> /etc/pgpool-II/pcp.conf

为了让follow_primary.sh脚本执行pcp命令时无需输入密码,需要在postgres用户的家目录下生成.pcppass文件。

[all servers]# su - postgres[all servers]$ echo'localhost:9898:pgpool:<pgpool用户密码>' > ~/.pcppass
[all servers]$ chmod600 ~/.pcppass

7.在线recovery配置

在线recovery需要超级用户权限,因此需要以postgres用户的身份运行,需要执行recovery_1st_stage_command和recovery_2nd_stage_command参数指定的脚本,配置如下:

recovery_user ='postgres'recovery_password =''recovery_1st_stage_command ='recovery_1st_stage'recovery_2nd_stage_command ='pgpool_remote_start'

这两个脚本在/home/postgres/pgpool/etc目录下也有相应的用例,根据自己的场景修改相关参数,主要修改PG_HOME参数。并将修改好的脚本文件复制到PG_HOME目录,赋予可执行权限。

[server1]# cp -p /home/postgres/pgpool/etc/recovery_1st_stage.sample /data/pgsql16/data/recovery_1st_stage[server1]# cp -p /home/postgres/pgpool/etc/pgpool_remote_start.sample /data/pgsql16/data/pgpool_remote_start[server1]# chown postgres:postgres /home/pgsql16/data/{recovery_1st_stage,pgpool_remote_start}[server1]# chmod +x /home/pgsql16/data/{recovery_1st_stage,pgpool_remote_start}

在线recovery需要用到pgpool_recovery扩展提供的pgpool_recovery, pgpool_remote_start, pgpool_switch_xlog函数,因此需要在主节点的template1数据库模板上创建pgpool_recovery扩展

[server1]# su - postgres[server1]$ psql template1 -c"CREATE EXTENSION pgpool_recovery"

8.客户端认证配置

出于安全原因,客户端访问pgpool里也需要密码认证,因些需要配置pgpool的密码认证,类似于PostgreSQL的pg_hba.conf,pgpool的配置文件保存在/home/postgres/pgpool/etc目录下,文件名为pool_hba.conf,我们使用scram-sha-256算法。

enable_pool_hba = on
pool_passwd ='pool_passwd'

pool_hba.conf

host    all         pgpool           192.168.0.0/24          scram-sha-256
host    all         postgres         192.168.0.0/24          scram-sha-256

此外还需要为所有需要通过Pgpool访问PostgreSQL数据库的用户创建Pgpool的密码文件,密码文件位于/home/postgres/pgpool/etc目录下,缺省文件名为:pool_passwd。密码使用AES算法加密,需要先生成.pgpoolkey文件,文件中保存加密用的密钥。

[all servers]# su - postgres[all servers]$ echo'some string' > ~/.pgpoolkey
[all servers]$ chmod600 ~/.pgpoolkey

生成key文件后,执行pg_enc -m -k /path/to/.pgpoolkey -u username -p生成用户的密码。

[all servers]# su - postgres[all servers]$ pg_enc-m-k ~/.pgpoolkey -u pgpool -pdb password: [pgpool user's password][all servers]$ pg_enc -m -k ~/.pgpoolkey -u postgres -pdb password: [postgres user's password]
# cat /home/postgres/pgpool/etc/pool_passwdpgpool:AESheq2ZMZjynddMWk5sKP/Rw==postgres:AESHs/pWL5rtXy2IwuzroHfqg==

9.看门狗配置

# 看门狗相关use_watchdog = on
# 节点1hostname0 ='server1'wd_port0 =9000pgpool_port0 =9999# 节点2hostname1 ='server2'wd_port1 =9000pgpool_port1 =9999# 节点3hostname2 ='server3'wd_port2 =9000pgpool_port2 =9999delegate_ip ='192.168.0.5'#浮动IPif_cmd_path ='/usr/sbin'if_up_cmd ='/usr/bin/sudo /usr/sbin/ip addr add $_IP_$/32 dev eth0 label eth0:0'if_down_cmd ='/usr/bin/sudo /usr/sbin/ip addr del $_IP_$/32 dev eth0'arping_path ='/usr/sbin'arping_cmd ='/usr/bin/sudo /usr/bin/arping -U $_IP_$ -w 1 -I eth0'ping_path ='/usr/bin'wd_escalation_command ='/home/postgres/pgpool/etc/escalation.sh'heartbeat_hostname0 ='server1'heartbeat_port0 =9694heartbeat_device0 =''heartbeat_hostname1 ='server2'heartbeat_port1 =9694heartbeat_device1 =''heartbeat_hostname2 ='server3'heartbeat_port2 =9694heartbeat_device2 =''wd_heartbeat_keepalive =2wd_heartbeat_deadtime =30

看门狗在做浮动IP切换、执行arping检查其他节点是否存活时需要以root权限执行,需要为postgres用户设置相应的权限,使用visudo编辑权限,加上如下内容:

postgres ALL=NOPASSWD: /usr/sbin/ip
postgres ALL=NOPASSWD: /usr/bin/arping

wd_escalation_command指定浮动IP切换脚本,/home/postgres/pgpool/etc目录下有相应用例escalation.sh.sample,根据自身情况修改:

[all servers]# cd /home/postgres/pgpool/etc[all servers]# cp -p escalation.sh.sample escalation.sh[all servers]# chown postgres:postgres escalation.sh[all servers]# chmod +x escalation.sh[all servers]# vi escalation.sh...
PGPOOLS=(server1 server2 server3)
VIP=192.168.137.5
# 需要绑定的网卡名可通过ifconfig -a查看DEVICE=eth0

10.日志配置

logging_collector = on
log_directory ='/home/postgres/pgpool/logs'log_filename ='pgpool-%Y-%m-%d_%H%M%S.log'log_truncate_on_rotation = on
log_rotation_size = 100MB
pid_file_name ='/home/postgres/pgpool/logs/pgpool.pid'logdir ='/tmp'


附:一个完整的配置文件例子

backend_clustering_mode ='streaming_replication'listen_addresses ='*'port =9999unix_socket_directories ='/tmp'pcp_listen_addresses ='*'pcp_port =9898pcp_socket_dir ='/tmp'# masterbackend_hostname0 ='server1'#主机名或IP地址backend_port0 =5432backend_weight0 =1backend_data_directory0 ='/data/pgsql16/data'backend_flag0 ='ALLOW_TO_FAILOVER'backend_application_name0 ='server0'# standby-1backend_hostname1 ='server2'backend_port1 =5432backend_weight1 =1backend_data_directory1 ='/data/pgsql16/data'backend_flag1 ='ALLOW_TO_FAILOVER'backend_application_name1 ='server1'# standby-2backend_hostname2 ='server3'backend_port2 =5432backend_weight2 =1backend_data_directory2 ='/data/pgsql16/data'backend_flag2 ='ALLOW_TO_FAILOVER'backend_application_name2 ='server2'enable_pool_hba = on
pool_passwd ='pool_passwd'process_management_mode = dynamic
num_init_children =32min_spare_children =5max_spare_children =10max_pool =4# 日志相关logging_collector = on
log_directory ='/home/postgres/pgpool/logs'log_filename ='pgpool-%Y-%m-%d_%H%M%S.log'log_truncate_on_rotation = on
log_rotation_size = 100MB
pid_file_name ='/home/postgres/pgpool/logs/pgpool.pid'logdir ='/tmp'connection_cache = on #连接池开启load_balance_mode = on #负载均衡开启disable_load_balance_on_write ='transaction'#应用有事务时一定要设置# 健康检查相关sr_check_user ='pgpool'sr_check_password =''health_check_period =5health_check_timeout =30health_check_user ='pgpool'health_check_password =''health_check_max_retries =3# failover、recovery相关failover_command ='/home/postgres/pgpool/etc/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'follow_primary_command ='/home/postgres/pgpool/etc/follow_primary.sh %d %h %p %D %m %H %M %P %r %R'recovery_user ='postgres'recovery_password =''recovery_1st_stage_command ='recovery_1st_stage'recovery_2nd_stage_command ='pgpool_remote_start'# 看门狗相关use_watchdog = on
# 节点1hostname0 ='server1'wd_port0 =9000pgpool_port0 =9999# 节点2hostname1 ='server2'wd_port1 =9000pgpool_port1 =9999# 节点3hostname2 ='server3'wd_port2 =9000pgpool_port2 =9999delegate_ip ='192.168.0.5'#浮动IPif_cmd_path ='/usr/sbin'if_up_cmd ='/usr/bin/sudo /usr/sbin/ip addr add $_IP_$/32 dev eth0 label eth0:0'if_down_cmd ='/usr/bin/sudo /usr/sbin/ip addr del $_IP_$/32 dev eth0'arping_path ='/usr/sbin'arping_cmd ='/usr/bin/sudo /usr/bin/arping -U $_IP_$ -w 1 -I eth0'ping_path ='/usr/bin'wd_escalation_command ='/home/postgres/pgpool/etc/escalation.sh'heartbeat_hostname0 ='server1'heartbeat_port0 =9694heartbeat_device0 =''heartbeat_hostname1 ='server2'heartbeat_port1 =9694heartbeat_device1 =''heartbeat_hostname2 ='server3'heartbeat_port2 =9694heartbeat_device2 =''wd_heartbeat_keepalive =2wd_heartbeat_deadtime =30

配置完成后将pgpool.conf复制到其他节点(server2、server3)。各节点的pgpool.conf内容均相同,无需修改。

[server1]$ scp-p /home/postgres/pgpool/etc/pgpool.conf postgres@server2://home/postgres/pgpool/etc/.
[server1]$ scp-p /home/postgres/pgpool/etc/pgpool.conf postgres@server3://home/postgres/pgpool/etc/.



相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
25天前
|
负载均衡 网络协议 网络安全
SLB-Backend多实例部署配置健康检查
【10月更文挑战第22天】
49 3
|
6天前
|
负载均衡 应用服务中间件
slb何时需要配置健康检查域名
slb何时需要配置健康检查域名
19 3
|
20天前
|
弹性计算 负载均衡 算法
slb 配置不当
【11月更文挑战第2天】
32 10
|
21天前
|
负载均衡 监控 应用服务中间件
slb配置同步问题
【11月更文挑战第1天】
27 3
|
29天前
|
弹性计算 负载均衡 算法
slb配置监听器
【10月更文挑战第18天】
43 3
|
2月前
|
负载均衡 应用服务中间件 Apache
Tomcat负载均衡原理详解及配置Apache2.2.22+Tomcat7
Tomcat负载均衡原理详解及配置Apache2.2.22+Tomcat7
44 3
|
2月前
|
负载均衡 Java 应用服务中间件
Nginx负载均衡配置
Nginx负载均衡配置
|
2月前
|
负载均衡 算法 Java
java中nginx负载均衡配置
java中nginx负载均衡配置
45 0
|
2月前
|
负载均衡 算法 应用服务中间件
【nginx】配置Nginx实现负载均衡
【nginx】配置Nginx实现负载均衡
|
4月前
|
监控 Linux 应用服务中间件
在Linux中,如何配置负载均衡器?
在Linux中,如何配置负载均衡器?