最近在梳理Consul健康檢查邏輯的時候,也發現了一些潛在的問題,這些問題雖然不會直接造成業務故障,但是在故障發生的時候還是存在較高的概率導致一些意料之外的影響。
從解耦的設計思路來看,我們希望很多事情能夠做到多重校驗,即設計一個組件的時候,如何涉及外部環節,我們需要從故障設計的角度來進行考量,即認為我們的服務或者組件是存在故障的風險,按照這個來設計,就能夠導致一些后續設計中的尷尬。
對于Consul的邏輯檢查,說簡單也可以,說復雜確實需要補充很多的內容,以下是在之前整理的一版基礎上進行細化得到的。
MySQL在Consul服務中的健康檢查邏輯
整體上腳本分為兩個部分,第一個部分是判斷數據庫的角色,第二個部分根據讀寫策略進行補充。
數據庫角色判斷的邏輯如下:
第二個部分是根據角色和讀寫策略完成健康檢查,如果正常返回0,否則返回2
我來做一下解釋,目前的讀寫分離如果是主庫,則為write,如果是查詢操作主從庫均可讀,則為Mixed_Read,如果查詢只在從庫可行,則為Read_only.
在這個基礎上我們來梳理一下這種策略的潛在風險。
既然設置了健康檢查,我們就不能指望服務狀態始終不變,如果發生了服務宕機,在服務重啟后,如果因為健康檢查策略導致主從混寫,那這個問題就嚴重了。
所以在目前的檢查模式下,如果主庫宕機,在重啟服務前需要暫時停止健康檢查邏輯,否則就會造成數據錯亂的嚴重問題。
如果從庫宕機,則健康檢查邏輯還是比較穩定,除了原本的讀混合模式會漂移到主庫之外,其他的部分沒有變化。
如果是主從復制失敗,則問題依然是可控的。
做完這些分析之后,我覺得目前的健康檢查邏輯是存在潛在風險的,因為有些環節需要依賴人工的檢查,因為一旦失誤,就會造成數據問題。所以在這一點上我覺得健康檢查的邏輯需要進行補充和整改。
我們可以換一個角度來考慮,就是什么時候應該會發生健康檢查狀態的變化,目前梳理了下主要有以下幾種。
除非主庫宕機,其實我們是不希望域名頻繁的做切換的,如果發生切換,主要有兩個場景,一個是異常宕機,另外一個就是基于ACL的key-value檢測。
從這個角度來看,域名服務是相對恒定的,實時的檢測其實都對于每一次檢測都是實時的,如果出現超時,連接異常等情況,其實是盡可能希望在當前域名范圍內處理,畢竟這個時候域名和IP僅僅的連接的形式不同而已,如果要建立更加穩定的健康檢查,應該是ACL+實時檢測組合的方案,基本思路就是ACL檢測優先,在服務故障切換之后,會補充檢測健康檢查的邏輯,把這兩個部分整合起來處理,就會避免那些意料之外的異常域名切換。
相關鏈接:
個人新書 《MySQL DBA工作筆記》