ery routing in Streaming Replication cluster

本章節將結合Pgpool-II,達成使用者端read write query的自動rounting。換句話說,read query(SELECT)自動在cluster中load balance; write query(INSERT, UPDATE...)自動指向master,架構如下圖所示:

此架構所帶來好處如下列:

  • read query負載平衡
  • connection pool
  • 使用者端不需要因為master, standby角色互換,而需要更改指向master的IP或主機位置
  • 可稱的上某種程度獨寫分離操作,且不需要實作在AP端
  • 無單點故障問題,任一節點掛掉皆可獨立運作

缺點:

  • 發生單點故障時,除非前端Loadbalance有自動偵測機制,否則仍需手動修改...

架構說明:

由於是由pgpool在前端實際面對使用者,建議使其listen postgres default post, 5432;讓後端postgres10listen其他port,本文讓postgres listen在5431上,對於使用者、管理者來說使用者也會比較友善。

[on master、slave]

安裝Pgpool-II

~$ sudo apt-get install pgpool2

設定pgpool.conf

先備份pgpool.conf設定檔

~$ sudo mv /etc/pgpool2/pgpool.conf /etc/pgpool2/pgpool.conf_old

由於Pgpool-II設定項目眾多,且不同模式間也有許多設定項目互斥的情況,請到/usr/share/doc/pgpool2/examples目錄下複製streaming replication設定範例

~$ sudo cp /usr/share/doc/pgpool2/examples/pgpool.conf.sample-stream.gz /etc/pgpool2/ && sudo gzip -d /etc/pgpool2/pgpool.conf.sample-stream.gz
~$ sudo mv /etc/pgpool2/pgpool.conf.sample-stream /etc/pgpool2/pgpool.conf

編輯pgpool.conf並確認下列設定項目是否設定正確

~$ sudo vim /etc/pgpool2/pgpool.conf
# Connection
listen_addresses = '*'
port = 5432

# Backends
backend_hostname0 = 'node1'  # hostname or IP
backend_port0 = 5431
backend_weight0 = 1
backend_data_directory0 = '/var/lib/postgresql/10/main'
backend_flag0 = 'DISALLOW_TO_FAILOVER'

# Authentication
enable_pool_hba = off

# pgpool mode
load_balance_mode = on
master_slave_mode = on
master_slave_sub_mode = 'stream'

# Do not use pgpool to do failover
fail_over_on_backend_error = off

# Log setting
log_destination = 'syslog'
log_connections = on
log_per_node_statement = on

# Health check
sr_check_user = 'postgres'
health_check_user = 'postgres'

Note : fail_over_on_backend_error若不設為off,只要任一節點有問題就會因為failover失敗導致pgpool停擺

將pgpool加入syslog facility

~$ sudo vim  /etc/rsyslog.conf
#pgpool
local0.* /var/log/pgpool.log

設定pgpool logrotate

~$ sudo vim /etc/logrotate.d/pgpool
/var/log/pgpool.log {
       daily
       rotate 10
       copytruncate
       delaycompress
       compress
       notifempt
       missingok
       su root root
}

pool_hba.conf連線管理

若希望在前端pgpool管理驗證連線,除了透過pgpool的pool_hba.conf必須搭配後端的pg_hba.conf來完成,設定對照如下表:

pool_hba.conf pool_passwd pg_hba.conf result
md5 md5 yes md5 auth
md5 tust yes no auth
trust trust yes/no no auth

整理自:https://www.pgpool.net/mediawiki/index.php/FAQ

一般實務情況下,前後端都應該開啟md5驗證模式,以避免資料庫匿名存取;但上列表格不適用於replication mode以及master/slave mode,若是使用以上模式,僅支援trust, clear text passwordu以及pam方法管理連線。但明文密碼可能會造成管理上的漏洞,故比較推薦透過來源IP、使用者以及存取資料庫來嚴格限制DB存取。

啟動與測試pgpool

於master, slave上啟動pgpool服務

~$ sudo service pgpool2 start

觀察是否能正常接受查詢

~$ psql -h pgdbnode1 -U postgres -c "show pool_nodes;"
 node_id | hostname  | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay 
---------+-----------+------+--------+-----------+---------+------------+-------------------+-------------------
 0       | pgdbnode1 | 5431 | up     | 0.500000  | primary | 2          | true              | 0
 1       | pgdbnode2 | 5431 | unused | 0.500000  | standby | 0          | false             | 0
(2 筆資料列)

~$ psql -h pgdbnode2 -U postgres -c "show pool_nodes;"
 node_id | hostname  | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay 
---------+-----------+------+--------+-----------+---------+------------+-------------------+-------------------
 0       | pgdbnode1 | 5431 | up     | 0.500000  | primary | 0          | true              | 0
 1       | pgdbnode2 | 5431 | unused | 0.500000  | standby | 0          | false             | 0
(2 筆資料列)

Note: psql指令預設會使用5432 port來連線,我們的設定是將postgresql service listen在5431port上,pgpool listen在5432 port上

在show pool_nodes返回結果中,standby node會處於unused狀態,且pgpool.log中也可以觀察到,select query只會被送到node0(master),並沒有送到node1(slave),Load balance功能實際上是失效的。

~$ tail -f /var/log/pgpool.log
Nov  8 14:02:28 pgdbnode1 pgpool[48322]: [106-1] 2017-11-08 14:02:28: pid 48322: LOG:  pool_send_and_wait: Error or notice message from backend: : DB node id: 0...
Nov  8 14:02:28 pgdbnode1 pgpool[48322]: [106-1] 2017-11-08 14:02:28: pid 48322: LOG:  pool_send_and_wait: Error or notice message from backend: : DB node id: 0...
Nov  8 14:02:28 pgdbnode1 pgpool[48322]: [106-1] 2017-11-08 14:02:28: pid 48322: LOG:  pool_send_and_wait: Error or notice message from backend: : DB node id: 0...

這是因為pgpool雖然在設定檔中知道standby的存在,但在管理pgpool的meta中並不知道它的存在,此時會需要透過PCP-pgpool Communication Manager工具來節點加入到pgpool中來管理。

使用pcp_attach_node加入standby node

使用pg_md5產生密碼

~$ pg_md5 <password>
81dc9bdb52d04dc20036dbd8313ed055

將hash後密碼加到pcp.conf中,並讓admin使用者可以透過該組密碼進行驗證

~$ sudo vim /etc/pgpool2/pcp.conf
admin:81dc9bdb52d04dc20036dbd8313ed055

預設PCP服務listen 9898 port上,確認該服務有正確listen後,使用pcp_node_info並帶上驗證資訊測試

~$ pcp_node_info -U admin -h pgdbnode1 -n 0
Password:(輸入剛剛用pg_md5來hash的密碼)
pgdbnode1 5431 2 0.500000 up

~$ pcp_node_info -U admin -h pgdbnode1 -n 1
Password:
pgdbnode2 5431 0 0.500000 unused

確認PCP運作正常後,請透過將node1(standby)加入pgpool管理

~$ pcp_attach_node -h pgdbnode1 -U admin -n 1
Password: 
pcp_attach_node -- Command Successful

~$ pcp_node_info -h pgdbnode2 -U admin -n 1
pgdbnode2 5431 2 0.500000 up

此時show pool_nodes standby的狀態就會被更新成up了,也可以觀察到/var/log/pgpool.log會有分配到slave的select語法

 ~$ psql -h pgdbnode1 -U postgres -c "show pool_nodes;"
 node_id | hostname  | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay 
---------+-----------+------+--------+-----------+---------+------------+-------------------+-------------------
 0       | pgdbnode1 | 5431 | up     | 0.500000  | primary | 2          | true              | 0
 1       | pgdbnode2 | 5431 | up     | 0.500000  | standby | 0          | false             | 0
(2 筆資料列)

results matching ""

    No results matching ""