7.9 基於pgpool-Ⅱ高可用方案
pgpool-Ⅱ是一款介於數據庫服務器和客戶端之間的中間件。
7.9.1 pgpool-Ⅱ特性
- 連接池:pgpool 提供連接池功能,降低建立連接帶來的開銷,同時增加系統的吞吐量
- 負載均衡:當數據庫運行在復制模式或主備模式下,SELECT語句運行在集群中任何一個節點都能返回一致的結果,pgpool能將查詢語句分發到集群的各個數據庫中,從而提升系統的吞吐量,負載均衡適用於只讀場景。
- 高可用:當集群中的主庫不可用時,pgpool 能夠探測到並且激活備庫,實現故障轉移
- 復制:pgpool 可以管理多個 PostgreSQL 數據庫,這是 pgpool 內置的復制特性,也可以使用外部復制方式,例如 PostgreSQL 的流復制等
- 限制超過限度的連接:PostgreSQL支持限制當前最大的連接數,拒絕新連接。pgpool-Ⅱ也支持限制最大連接數,它將超過限制的連接放入隊列而不是立即返回一個錯誤。
- 並行查詢:使用並行查詢時,數據可以分割到多台服務器上同時執行,以減少總體的執行時間。但並行查詢功能不完善。通常使用Postgres-XC|PL/Proxy方案實現PG數據水平拆分
7.9.2 架構
pgpool-Ⅱ完全實現PostgreSQL的連接協議,客戶端連接到pgpool-Ⅱ上,就於連接到數據庫上完全一樣。pgpool-Ⅱ的復制是同步的,即如果客戶端發送一個DML語句,將並發地在后端所有數據庫上執行,保證所有數據庫的一致性。
pgpool-Ⅱ是一個多進程的架構
- pcp進程:pcp是一個管理工具,向pgpool-Ⅱ發送管理命令
- pgpool-Ⅱ父進程:負責檢查各個底層數據庫的健康狀態
- pgpool-Ⅱ子進程:負責接收用戶發送過來的SQL請求,然后根據規則發送到底層數據庫上
- worker進程:負責檢查底層數據庫之間的復制延遲
7.9.3 pgpool-Ⅱ 的運行模式
pgpool-Ⅱ有連接池、復制、負載均衡等功能,使用這些功能需要配置在不同的工作模式下。
-
原始模式:只實現故障切換功能,當配置多個后端數據庫情形,第一個后端數據庫故障時切換到第二個后端數據庫,依次類推。這種模式pgpool不負責后端數據庫數據同步,數據庫的數據同步由用戶負責,對應配置文件為$prefix/etc/pgpool.conf.sample,這種模式不支持負載均衡。
-
連接池模式:實現連接池的功能和原始模式的故障切換功能。
-
內置復制模式:這種模式下pgpool負責后端數據庫數據同步,pgpool節點上的寫操作需等待所有后端數據庫將數據寫入后才向客戶端返回成功,是強同步復制方式,配置文件為$prefix/etc/pgpoo1.conf.sampie-repIication,這種模式實現負載均衡的功能。
-
主備模式:使用第三方工具(如:Slony,流復制)完成pgpool的后端數據庫的數據同步復制,中間件層使用pgpool-Ⅱ,pgpool提供高可用和連接池的功能。配置文件為$prefix/etc/pgpool.conf.sample-master-slave,這種模式支持負載均衡。
- 配合流復制的主備模式:使用PostgreSQL流復制方式,PostgreSQL流復制負責pgpool后端數據庫數據同步,對應的配置文件為$prefix/etc/pgpool.conf.sample-stream,這種模式支持負載均衡。pgpool+pg復制實現高可用解決方案
- 配合Slony的主備模式:
-
並行模式:實現查詢的並行執行。並行模式不能與主備模式同時使用。
復制模式與主備模式對比優缺點
復制模式優點
- 數據是同步的,數據強一致性
- 自動Failover
- 讀可以負載均衡
- 可以在線恢復,不需要停止pgpool就可以在線修復或增加后端數據庫節點
- 容易配置
復制模式缺點
- 寫性能不會很好,有30%的寫性能下降
- 不支持部分查詢。一些隨機函數、序列號,直接在不同的后端數據庫上執行SQL將產生不同的結果集,在復制模式下,不能使用此類函數和序列號
主備模式優點
- 寫性能較好,只有10%~20%的性能下降
- 自動Failover
- 可以做讀的負載均衡
主備模式的缺點
- 復制是異步
- 配置復雜
pgpool-Ⅱ3.0之后,支持配合使用流復制+Standby的主備模式,它實現讀寫分離。這種方式的好處:
- 智能的讀寫查詢分發:pgpool可以區分只讀查詢和更新查詢,對於只讀查詢,會將請求負載均衡到各個節點上,寫查詢只發送到主庫上
- 智能的負載均衡:pgpool能檢測備庫和主庫的延遲。如果備庫延遲超過設定值,讀查詢將之發送到主庫上
- 增加Standby Server時不需要停止pgpool-Ⅱ
7.9.4 安裝部署pgpool
rpm包安裝方式
# yum 包安裝(https://www.pgpool.net/mediawiki/index.php/Yum_Repository)
yum -y install http://www.pgpool.net/yum/rpms/4.1/redhat/rhel-7-x86_64/pgpool-Ⅱ-release-4.1-1.noarch.rpm
# 安裝適配指定pg版本pgpool軟件
yum -y install pgpool-Ⅱ-pg11
# 移除pgpool
yum -y erase pgpool-Ⅱ-pg11
源碼包編譯安裝
# https://www.pgpool.net/mediawiki/index.php/Downloads
wget https://www.pgpool.net/mediawiki/images/pgpool-Ⅱ-3.6.20.tar.gz
su - root
mkdir -p /ups/app/postgresql/pgpool
chown postgres:postgres /ups/app/postgresql/pgpool
su - postgres
tar -xf pgpool-Ⅱ-4.1.0.tar.gz
cd pgpool-Ⅱ-4.1.0
./configure --prefix=/ups/app/postgresql/pgpool --with-pgsql=/ups/app/postgresql/pgsql-11
make && make install
#
配置自啟動服務
vi /usr/lib/systemd/system/pgpool.service
[Unit]
Description=pgpool-Ⅱ
After=syslog.target network.target
[Service]
User=postgres
Group=postgres
EnvironmentFile=-/etc/sysconfig/pgpool
ExecStart=/ups/app/postgresql/pgpool/bin/pgpool -f /ups/app/postgresql/pgpool/etc/pgpool.conf $OPTS
ExecStop=/ups/app/postgresql/pgpool/bin/pgpool -f /ups/app/postgresql/pgpool/etc/pgpool.conf $STOP_OPTS stop
ExecReload=/ups/app/pgpool/bin/pgpool -f /ups/app/postgresql/pgpool/etc/pgpool.conf reload
[Install]
WantedBy=multi-user.target
編輯/etc/sysconfig/pgpool
文件
cat >> /etc/sysconfig/pgpool <<EOF
# Options for pgpool
# -n: don't run in daemon mode. does not detatch control tty
# -d: debug mode. lots of debug information will be printed
#OPTS=" -d -n"
OPTS=" -n"
STOP_OPTS=" -m fast"
EOF
安裝擴展函數
# 安裝pgpool_adm函數
cd /ups/soft/pgpool-Ⅱ-4.1.0/src/sql/pgpool_adm/
make && make install
# 安裝C語言函數-pgpool_recovery
cd /ups/soft/pgpool-Ⅱ-4.1.0/src/sql/pgpool-recovery
make && make install
psql -f /ups/soft/pgpool-Ⅱ-4.1.0/src/sql/pgpool-recovery/pgpool-recovery.sql template1
# pgpool_regclass函數被pgpool-II內部使用,用於解決不同schema中處理同名非臨時表
cd /ups/soft/pgpool-Ⅱ-4.1.0/src/sql/pgpool-regclass
make && make install
# 加載到template1 模板庫
psql -f /ups/soft/pgpool-Ⅱ-4.1.0/src/sql/pgpool-regclass/pgpool-regclass.sql template1
# 或 使用統一命令安裝擴展函數
cd /ups/soft/pgpool-Ⅱ-4.1.0/src/sql
make && make install
# 建立pgpool_catalog.insert_lock表 (master),用於解決復制中互斥的問題。在復制模式中,pgpool-Ⅱ需要鎖定目標表,而表鎖與VACUUM沖突,插入操作可能會出現長時間等待
psql -f /ups/soft/pgpool-Ⅱ-4.1.0/src/sql/insert_lock.sql template1
安裝擴展插件
-- psql
-- 主節點安裝插件
create EXTENSION pgpool_regclass;
CREATE EXTENSION pgpool_recovery;
\df
通過PCP接口管理
pgpool 提供一個用於管理 pgpool 的系統層命令行工具。PCP 命令使用的用戶屬於 pgpool 層面,和 PostgreSQL 數據庫中的用戶沒有關系,但pcp 命令 的用戶名和 MD5 加密的密碼必須首先在 pcp .conf 文件中定義。
# 配置用戶加密密碼
pg_md5 pgpool
# 編輯pcp.conf文件
# 格式: USERID:MD5PASSWD
cp /ups/app/postgresql/pgpool/etc/pcp.conf.sample /ups/app/postgresql/pgpool/etc/pcp.conf
vi /ups/app/postgresql/pgpool/etc/pcp.conf
postgres:md53175bce1d3201d16594cebf9d7eb3f9d
sync:md52803003449203cdbe05c56deb21cfa86
pgpool:ba777e4c2f15c11ea8ac3be7e0440aa0
使用
# pcp_node_info 命令查看節點信息
pcp_node_info --verbose -h 192.168.10.199 -U pgpool 0
7.9.5 簡單示例環境搭建
復制和負載均衡環境
服務器信息
角色 | IP地址 | 軟件版本 |
---|---|---|
安裝pgpool | 192.168.10.200 | pgpool-4 |
后端數據節點 | 192.168.10.181 | postgresql-11 |
后端數據節點 | 192.168.10.182 | postgresql-11 |
配置文件
# 1.
export PGPOOL_HOME=/ups/app/postgresql/pgpool
cd ${PGPOOL_HOME}
cp ${PGPOOL_HOME}/etc/pgpool.conf.sample ${PGPOOL_HOME}/etc/pgpool.conf
cp etc/pcp.conf.sample etc/pcp.conf
# 2. 配置pcp.conf
# 2.1 計算密碼的md5值
${PGPOOL_HOME}/bin/pg_md5 --help
Usage:
/ups/app/postgresql/pgpool/bin/pg_md5 [OPTIONS]
/ups/app/postgresql/pgpool/bin/pg_md5 <PASSWORD>
--prompt, -p Prompt password using standard input.
--md5auth, -m Produce md5 authentication password.
--username, -u USER When producing a md5 authentication password,
create the pool_passwd entry for USER.
--config-file, -f CONFIG-FILE Specify pgpool.conf.
--help, -h This help menu.
vi etc/pcp.conf
postgres:md53175bce1d3201d16594cebf9d7eb3f9d
sync:md52803003449203cdbe05c56deb21cfa86
pgpool:ba777e4c2f15c11ea8ac3be7e0440aa0
# 3. 配置pgool.conf
listen_addresses = '*'
port = 9999
replication_mode = on
load_balance_mode = on
backend_hostname0 = '192.168.10.181'
backend_port0 = 1921
backend_weight0 = 1
backend_data_directory0 = '/ups/data/pgdata/11/pg_root'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_application_name0 = 's1'
backend_hostname1 = '192.168.10.182'
backend_port1 = 1921
backend_weight1 = 1
backend_data_directory1 = '/ups/data/pgdata/11/pg_root'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_application_name1 = 's1'
failover_on_backend_error = on
啟動pgpool
${PGPOOL_HOME}/bin/pgpool -f ${PGPOOL_HOME}/etc/pgpool.conf
驗證
-- 連接到pgpool操作數據
psql -p 9999 -h 192.168.10.200 -U dev devdb
CREATE TABLE test01(id int, note text);
INSERT INTO test01 VALUES(1,'1');
-- 連接到后端數據庫查看
psql -p 1521 -h 192.168.10.181 -U dev devdb
\d test01
SELECT id, note FROM test01;
psql -p 1521 -h 192.168.10.182 -U dev devdb
\d test01
SELECT id, note FROM test01;
流復制的主備模式
服務器信息
角色 | IP地址 | 軟件版本 |
---|---|---|
安裝pgpool | 192.168.10.200 | pgpool-4.1 |
主庫 | 192.168.10.181 | postgresql-11 |
從庫 | 192.168.10.182 | postgresql-11 |
主從數據庫間使用異步流復制
配置參數文件
# 1. pgpool.conf
vi etc/pgpool.conf
listen_addresses = '*'
port = 9999
replication_mode = off
load_balance_mode = on
master_slave_mode = on
master_slave_sub_mode = 'stream'
backend_hostname0 = '192.168.10.181'
backend_port0 = 1921
backend_weight0 = 1
backend_data_directory0 = '/ups/data/pgdata/11/pg_root'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_application_name0 = 's1'
backend_hostname1 = '192.168.10.182'
backend_port1 = 1921
backend_weight1 = 1
backend_data_directory1 = '/ups/data/pgdata/11/pg_root'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_application_name1 = 's1'
failover_on_backend_error = on
啟動pgpool
${PGPOOL_HOME}/bin/pgpool -f ${PGPOOL_HOME}/etc/pgpool.conf
檢查
使用show命令檢查pgpool信息
- pool_status: 查看配置信息
- pool_nodes: 查看后端數據庫節點信息
- pool_processes: 查看進程信息
- pool_pools: 顯示連接池的各個連接信息
- pool_version: 顯示版本
-- psql -p 9999 -h 192.168.10.200 -U dev devdb
show pool_status;
show pool_nodes;