【原創】基於 Keepalived 作主備的 MySQL 在切換時遇到的問題


問題描述
MySQL 基於 keepalived 實現主備切換,業務 A 和業務 B (其實 A 和 B 上跑的業務是相同的 )同時使用 MySQL 作數據庫查詢。經過重啓 keepalived 服務來測試 MySQL 主備切換後,可以爲業務提供正常的服務。

問題現象
測試人員發現 MySQL 主從切換以後,與業務 A 相關的 TCP 鏈接信息已經變動爲新 TCP 鏈接,而與業務 B 相關的 TCP 鏈接信息仍舊未變化。

具體環境以下
業務A:172.16.177.158
業務B:172.16.177.159

VIP:172.16.177.147
MySQL master:172.16.177.148
MySQL slave:172.16.177.149




在業務正常運行狀態下,業務A 經過 VIP 與 MySQL master(148)創建 6 條 TCP 鏈接(業務開發人員告知的),分別對應端口
4366六、 4366八、 4366九、 43670、 4367三、 43674。

當經過重啓 148 機器上的 keepalived 服務來完成 VIP 切換,從而達成 MySQL 主備切換時,能夠看到以下抓包信息:

以下爲 158 上的 TCP 連接信息。




能夠看到,上面出現了 10 個 RST ……,呃,先無論爲何多出來 4 個吧。

下面看一下 148 (原 MySQL master)上來自 158 的鏈接信息。



      從上面兩個截圖中,只能看到有兩條 TCP 鏈路上出現了新的請求,而且由於重啓了 keepalived 的緣由,出現了 TCP 的重發。這兩條 TCP 鏈路對應的端口分別爲: 4367三、43669。
這裏重發請求的端口與 158 上的抓包中顯示的一致。

再看一下 149 (原 MySQL slave)上來自 158 的鏈接信息。




能夠看到這裏也出現了 10 條 TCP 鏈路被 RST 。與上面的 10 條 TCP 連接是對應的。

綜上,整個過程能夠描述爲:
  • 最開始 158 與 148 創建了6條 OCS 業務的 TCP 鏈接;
  • 在重啓 keepalived 的時候,剛好使用端口 43673 和 43669 的 TCP 鏈接正在信令交互,而此時正處於 VIP 147 從 148 向 149 漂移的過程之中,此時這兩條 TCP 鏈路上的請求會由於得不到任何迴應而觸發重傳;
  • 當 VIP 成功綁定到 149 上後,上述兩條 TCP 鏈路上的重傳請求會被 RST,而當其餘 TCP 鏈路上有新的請求時,纔會被 RST。被 RST 後,OSC 會從新創建 TCP 鏈接。
下面單獨看下每條 TCP 鏈路的情況:

端口 43673 的 TCP 鏈路。

端口爲 43669 的 TCP 鏈路。

端口爲 43666 的 TCP 鏈路。

端口爲 43674 的 TCP 鏈路。

端口爲 43670 的 TCP 鏈路。

端口爲 43668 的 TCP 鏈路。

端口爲 43671 的 TCP 鏈路。

端口爲 43665 的 TCP 鏈路。

端口爲 43672 的 TCP 鏈路。

端口爲 43667 的 TCP 鏈路。



上述現象在對於 159 上的業務來講也是這樣,再也不重複說明。

總結:
      上述問題的出現值得思考的地方有,經過重啓 keepalived 來促使 MySQL 主備切換這種方式對於實際應用場景是否有意義?!若是實際狀況中真的出現相似於 keepalived 重啓致使的 MySQL 主從切換,那麼由此致使的主從不一致將如何解決 ?!業務程序經過某種保活機制觸發對當前 TCP 鏈路是否處於「半打開」狀態的檢測時間間隔多少比較合適?MySQL 上的 wait_timeout 設置多少比較合適!?
      真正讓人感到不安的是,僅經過重啓 keepalived 來進行主備切換,不管是 MySQL 側仍是業務側,竟然都不會收到 TCP 的 FIN 或 RST ,而只會在業務層面有「動做」時才能發現 TCP 鏈路的問題,這種現象對相似 MySQL 這種服務來講必然會形成一些問題。
相關文章
相關標籤/搜索