起搏器和半同步複製
在我工作的公司中,我們使用簡單的主次複製設置。如果主系統因任何原因發生故障,我們手動進行切換。這也意味著,MySQL 幾乎不會更新。我想讓它成為可能,在不停機的情況下更新伺服器。由於各種原因,我們不想要一個(過度)複雜的解決方案。所以我想知道,為了實現我的目標,是否可以像這樣簡單:
啟用 GTID 的主-主複製和半同步複製。Pacemaker 將虛擬 IP 從一台伺服器切換到另一台伺服器,因此我可以停止一台伺服器進行更新。然後切換回來並更新另一台伺服器。
對於 Primary-Primary 複製,我沒有以不同方式配置 auto-increment-increment。所有寫入程序都將使用起搏器的虛擬 IP,因此只會寫入一台主機。
我們在我的公司這樣做。我們執行了數千個使用這種方法的 MySQL 主-主對。我們開發了一項服務來執行您描述的切換。我們稱其為“成功轉移”,因為它比故障轉移具有更積極的含義。我們可以並且確實在一天中的任何時間執行它,甚至不需要通知應用程序團隊我們正在這樣做。
以下是一般步驟:
認為:
“Master1”是目前可寫的主 MySQL 實例,其中定義了 VIP。
“Master2”是一個副本,處於只讀模式。
- 將 Master1 設為只讀。
- 從 Master1 中刪除 VIP。
- 開始殺死 Master1 上的任何未完成的查詢。繼續循環終止任何查詢,以防使用它的應用程序嘗試執行新查詢。我們不應該依賴前面的步驟來終止查詢或連接。即客戶端可能繞過了 VIP 並直接連接到物理 IP 地址。
- 等待 Master2 上的複制延遲達到 0。理想情況下,將 Master2 上的從屬狀態與 Master1 上的主狀態進行比較。如果由於 Master1 關閉而發生故障轉移,則無法進行該比較,但您可以比較 Master2 上的從屬狀態是否顯示 SQL 執行緒已趕上 IO 執行緒。
- 使 Master2 可寫。
- 將 VIP 添加到 Master2。
- 停止在 Master1 上終止查詢。
如果它是自動化的,只要沒有明顯的複制延遲,這將導致不到一秒的停機時間。移動 VIP 比更新 DNS 快得多。
然後應用程序必須重新連接到 VIP,從而訪問新的主實例並重新執行它們需要的任何查詢。
顯然,應用程序不應該使用備用 MySQL 實例,因為重點是允許它離線以進行更新、配置更改等。如果 MySQL 正在執行的主機伺服器出現問題,這也為您提供了一種快速響應的方法在。我們每週都會遇到一些主機崩潰或磁碟故障,因此我們快速執行此切換以確保應用程序可以繼續執行。
不可避免的是,這會導致應用程序連接斷開並必須重新連接的短暫“短暫”,但它比任何其他解決方案都更短暫的中斷。儘管如此,應用程序必須設計為檢測斷開的連接並重新連接。我們最大的問題是教育應用程序開發人員這樣做。他們一直抱怨說他們會因為失去連接而收到警報,我們告訴他們,“我們已經記錄了您需要做的事情——它不應該因為一個信號而發出警報。”
這個系統已經工作了好幾年,但我們現在有一個混合環境,我們有許多雲 MySQL 實例。我們需要一個新的解決方案,因為我們無法在雲中使用 BGP 創建 VIP。
因此,我們使用Envoy作為 MySQL 的代理進行了原型設計。我們相信這是可行的,但是我們需要開發一個服務來在我們進行成功轉移時通知 Envoy 代理更改。Envoy 支持 GRPC 協議,因此我們可以動態地向它發送消息,它會開始將流量路由到不同的目標 MySQL 實例。這種基於代理的解決方案在雲中的工作方式應該與在數據中心中的工作方式相同。但是這個解決方案可能比你想像的要多。
我們也可以使用ProxySQL來做類似的事情,但是 Envoy 在我們公司已經大量採用了服務到服務的流量,所以如果我們可以利用它而不是一種新型代理,我們就可以使用更少的技術來實現採用。
更新評論:
上面列表中的第 4 步等待複製趕上,而兩個實例都是只讀的。因此,在此期間 Master1 上不允許有新的更新,而 Master2 只需執行在 Master1 設置為只讀之前送出的一組剩餘更新。希望這是一個非常短暫的等待,除非 Master2 已經落後很多。
執行 successover 的服務如果檢測到 Master2 具有高複制延遲,則甚至拒絕開始操作。鼓勵使用者稍後再試。
當然,在現實世界中,有時您必須因為緊急情況而超越這種限制,因此可以選擇強制繼承。但這會帶來風險,因為如果您將 Master2 設為主要並開始允許直接在其上進行新查詢,而由於複製滯後仍有待處理的未完成更新,您最終會陷入腦裂的情況:您可以進行update 然後將被二進制日誌中過去實際發生的事件替換。
所以理論上你可以在 Master2 上啟用 VIP,但讓 Master2 保持只讀狀態,直到它完全趕上複製。這至少執行了部分成功轉移,並允許客戶端臨時讀取數據,但不能更新。這對於某些應用程序來說可能在短時間內是可以接受的,但這取決於應用程序的要求。
在實踐中,我們的successover 實現不會執行這種臨時只讀模式。我們只是盡量不願意使用強制繼承選項,因為腦裂極難清理(可能不可能)。我們寧願在沒有複製延遲的情況下嘗試successover。