最簡單的Postgresql 高可用方式 與 kong 網關
- 2020 年 2 月 21 日
- 筆記

事情的起因是,一家比較大的公司,要使用kong網關,就職的朋友問我postgresql 最簡單的高可用方式有什麼, 所以才有了此文PostgreSQL 的複製默認是異步的方式,如果primary server crash了一些已經commited的事務在primary server 但還沒有傳送到 standby server 則主從就會不一致,數據就丟失了,所以這是異步複製的模式。
但Postgresql 提供了一種同步的模式,保證primary 和 standby 庫的數據是一致的,這樣的方式將所有的事務改變必須傳送到standby server wal_log 後在確認commit。這也就使得數據丟失的唯一可能性是主庫和從庫同時無法正常工作。
當然這樣操作的缺點也是顯而易見
1 性能一定是要大打折扣,因為明明在一個服務器上寫操作就可以繼續的事情,現在要兩台服務器之間要確認,自然性能要損失。
2 從庫如果因為某些原因無法寫入數據,或者網絡出現問題,則數據庫的對外服務就會出現問題。
所以這樣的高可用的搭建,基本上在現實中很少見。但今天為什麼要提他。
任何架構的使用都與他所處的使用的環境和應用的邏輯有關,在某些情況這樣的高可用是可以被接受的。
舉個例子,現在熱門的微服務網關 kong, 使用它就要使用數據庫,而這樣的情況下,有兩種選擇postgresql or cassandra 。 如果讓你選怎麼選,傳統的人士估計大概率還是選擇 postgresql, 不會選擇cassandra(其實cassandra很有意思)。其中的原因如果你知道cassandra 的原理就明白。
那擺在現在的問題就是,是要咱們搭建一個高可用的postgresql,在沒有專業人士的指導,patroni , repmgr , 想想還是算了。
那這個例子中有什麼特點
1 postgresql 承載的數據量不大
2 不會經常寫數據庫,基礎數據大概率一次寫入
3 讀多,寫少
4 數據庫沒有高可用,尤其是網關,並且還是微服務的,(有多少模塊在這上面),丟了數據,或者主庫失效,難道你要整個系統跟着統統down掉。
那怎麼高效的完成任務,還能簡簡單單,讓非DB的人士趕緊搞定這個事情,所以這個同步的方式,以及這樣方式下的高可用,就是最好的選擇。所以這期是最簡單的高可用,(我沒說是最好的,也沒說哪裡都能用,就上面那個例子用,再好不過)
那怎麼搭建這個高可用的方式,下面就來盤盤道。 postgresql.conf
1 安裝這裡就不說了,請參見之前的文字
2 配置文件, 這裡的關鍵就是配置文件
1 synchronous_commit
2 synchronous_standby_name
這兩個是必須的要進行設置必選項
synchronous_commit
下面是他的幾個選項
on
事務提交總是等待,直到將數據真正刷新到事務日誌(也稱為WAL或XLOG),以確保事務確實是持久的。在同步流複製模式下,副本也需要這樣做。
off
事務flush wal_log 前,就可以向用戶提交確認,當然付出的代價就是在服務器crash時會損失那些沒有提交單沒有flush 到wal_log 的數據
local
這個選擇僅僅保證你的事務commited 後不再主節點丟失數據,standby不保證數據不丟失。
remote_write
與on選項相比,這並不會不丟失數據,standby 僅僅等等操作系統返回數據寫入的磁盤的確認。
remote_apply
這個是我們需要的選項,提供了複製的強一致選項,主庫不會在沒有從庫提交返回數據已經安全寫入standby之前commit,這這個選項的意義在於,主和從在任何一個時間數據都是一直的,或者一起去dead。
列出一個從弱到強的對數據的一致性保護
off (async) > on (async) > remote_write (sync) > on|local (sync) > remote_apply (sync)
而
synchronous_standby_name 的與上面的意義不同的在於,他在選擇你要哪個從庫與你一致,因為可能有很多的從庫與你進行數據的同步。
最簡單粗暴的就是用 * 來代表,當然你也可以寫成mongodb 的方式 'ANY 2 (服務器1 ,服務器2 服務器3) ' 這就是MONGODB 的裏面的大多數的概念,POSTGRESQL 這裡也是至少2個 standby與我一致我才罷休,否則不可以。
或者也可以寫成固定的模式 'FIRST 2 (服務器1 ,服務器2 服務器3) ' 至少前邊兩個服務器必須與你的primary 數據一致(具體看上面那個參數的設置)
才能讓primary commit or no .
下面我們做一個例子
兩台機器,使用pg_basebackup 做了最基本的複製,相關複製怎麼做請參見之前的文字。

我們下面做一個實驗
1 我們在primary 服務器上開啟事務
2 我們在commit 前將從庫關閉
3 我們看看會怎麼樣
主庫

從庫

可以很清晰的看到,從庫不在線的情況下,主庫根本沒有辦法commit
我們可以看下面,明顯開啟從庫後,主庫自動就將事務commit了


也可以看一下primary 和 standby 的日誌
primary

standby

再次基礎上,配合keepalive 去驗證postgresql 服務,並且其中包含promote命令,就能完成一個最簡單的高可用的postgresql。
其實如果MYSQL 的複製能做到強一致性的話,可能也就沒有當初MHA什麼事情了。MYSQL + KEEPALIVE 也可能是一種可靠的選擇。
再次重申,怕有同學誤會,覺得我推薦這樣的高可用,請在回顧一下題目,最簡單的,另外還是那句話,看需求,在做,要不僅僅人家就要一個KONG 的簡單需求,並且人家公司也沒有POSTGRESQL DBA,要人家REPMGR PATRONI,PG 的 數據庫DBA It's too expensive and hard to find 。