從節(jié)點(diǎn)崩了,還怎么「主從讀寫分離」?
你好,我是悟空。
本篇主要內(nèi)容如下:
目錄
背景
我們的項(xiàng)目采用了讀寫分離的方案:查詢和更新的業(yè)務(wù)走主庫,統(tǒng)計相關(guān)的功能走從庫,從而減少主庫的壓力。原理如下圖所示:
讀寫分離的方案
如果從庫崩了,實(shí)在無法訪問了,就會把所有請求打到主庫上。原理如下圖所示:
從節(jié)點(diǎn)崩了,部分流量打到主節(jié)點(diǎn)
但是最近遇到一個問題,MySQL 從節(jié)點(diǎn)上的服務(wù)無緣無故的崩了,查看日志也找不到什么端倪。
為了保證從節(jié)點(diǎn)的可用性,我們使用了 Keepalived 軟件來監(jiān)測從節(jié)點(diǎn)存活狀態(tài),如果從節(jié)點(diǎn)崩了,則自動重啟 MySQL 容器。
本篇將會講解沒什么卵用的排查記錄,以及如何保證從節(jié)點(diǎn)可用性,注意,還不是完全的高可用。
一、排查記錄
雖說沒有找到 MySQL 從節(jié)點(diǎn)容器真正崩了的原因,但是這排查記錄還是得記錄下。
1.1 查看 MySQL 的容器日志
2023-02-08 6:27:30 開始 Shutdown 了,沒有提示為什么 shutdown。
2023-02-08 6:27:34 Shutdown 完成。
1.2 查看 MySQL 的錯誤日志
可以看到 6:27:30 沒有異常日志。
這不就尷尬了,完全不知道為啥崩了。
(備注:另外也可以看下容器的信息,docker inspect <容器 id>,會顯示容器什么時候啟動和停止的。)
二、怎么理解讀寫分離
讀寫分離有個限制條件就是主庫可以用來做讀寫,從庫實(shí)時同步主庫數(shù)據(jù),而且從庫是只讀的。
我們的項(xiàng)目中有統(tǒng)計功能就是連接從庫查詢數(shù)據(jù),從庫不會進(jìn)行數(shù)據(jù)更新的操作。
讀寫分離我認(rèn)為可以分為兩種:
- 1、完全的讀寫分離:主庫只用來更新數(shù)據(jù),從庫只用來查詢數(shù)據(jù)。
- 2、部分讀寫分離:主庫既可以用來讀數(shù)據(jù),又可以進(jìn)行查數(shù)據(jù);從庫作為只讀的備庫,分擔(dān)耗性能的查詢工作。
我們項(xiàng)目采用的是第二種方案,涉及到 I/O 密集型的查詢工作就交給 MySQL 從庫去處理。
部分讀寫分離
三、從節(jié)點(diǎn)的高可用如何保證?
3.1 保證從節(jié)點(diǎn)的可用性
采用 keepalived 自動檢測 MySQL 服務(wù)是否正常,如果不正常,自動重啟 MySQL 容器。
提高從節(jié)點(diǎn)的可用性
3.2 從節(jié)點(diǎn)數(shù)據(jù)庫無法重啟了怎么辦?
目前從節(jié)點(diǎn)只有一個節(jié)點(diǎn),如果從節(jié)點(diǎn)崩了,從哪執(zhí)行查詢?
有兩種方案:
- 方案一:讀操作切換到主庫去查詢。帶來的問題:主庫的壓力會很大。
- 方案二:部署兩個從節(jié)點(diǎn),從節(jié)點(diǎn)之間相互同步數(shù)據(jù),只有一個從節(jié)點(diǎn)提供服務(wù),另外一個節(jié)點(diǎn)作為備用從庫,前者崩了的話,流量自動切換到后者。(需要兩個節(jié)點(diǎn)開啟 Keepalived 來提供流量切換的能力)帶來的問題:部署的復(fù)雜性,主從同步延遲。
目前我們采用的是第一種方案,如果從節(jié)點(diǎn)崩了,讀操作會切換到主庫上去執(zhí)行。所以保證從節(jié)點(diǎn)不崩就很重要了。
四、實(shí)踐:保證從節(jié)點(diǎn)的可用性
這次我們要做的就是在在從節(jié)點(diǎn)開啟 Keepalived,以及修改重啟 MySQL 的腳本。從節(jié)點(diǎn)的 Keepalived 的 VIP 地址和主節(jié)點(diǎn)的 Keepalived 的 VIP 不一樣。
原理如下所示:
從節(jié)點(diǎn)首先得安裝和配置 keepalived 在之前的文章中已經(jīng)詳細(xì)講解過了。
我在講解主主切換的文章中提到過 keepalived 承擔(dān)的職責(zé)是就是監(jiān)測 MySQL 服務(wù)是否正常,如果不正常,則重啟 MySQL,如果重啟失敗,則退出 keepalived,自動將流量切換到另外一個節(jié)點(diǎn)。
這次的從節(jié)點(diǎn)只作為備庫,沒有切換到主庫的要求,所以在主庫宕機(jī)后,不需要接管讀寫的流量。
4.1 啟動 keeaplived 服務(wù)以及開機(jī)自啟動
安裝好 keepalived 之后,執(zhí)行以下命令啟動。
啟動 keeaplived 服務(wù)
還需要設(shè)置 keepalived 開機(jī)自啟動。
具體內(nèi)容可以看這篇實(shí)戰(zhàn) MySQL 高可用架構(gòu)
實(shí)戰(zhàn) MySQL 高可用架構(gòu)目錄
4.2 如何監(jiān)測 MySQL 服務(wù)的健康狀況
keepalived 配置文件中定時監(jiān)測 MySQL 服務(wù)的健康狀況。
修改配置文件:
4.3 如何自動重啟 MySQL 服務(wù)
自動重啟 MySQL 的腳本之前也講解過,這里再貼一下。當(dāng) keepalived 檢測到 MySQL 無法連接時,就自動重啟 MySQL 容器。
如何自動重啟 MySQL 服務(wù)
4.3 如何不讓 Keepalived 切換流量到其他機(jī)器
因?yàn)橹鞴?jié)點(diǎn)也是開啟了 Keepalived,如果主從的 Keepalived 的 VIP 都是同一個(之前配置的是 192.168.56.88),那么如果主節(jié)點(diǎn)崩了,就會將流量自動切換到從節(jié)點(diǎn),因?yàn)槲覀冞@個從節(jié)點(diǎn)只作為備庫,不需要它升級為主庫,所以可以將主從節(jié)點(diǎn)的 Keepalived 的 VIP 設(shè)置為不一樣,這樣的話,從節(jié)點(diǎn)就不會升級為主節(jié)點(diǎn)。
這里我們就把之前的 VIP 192.168.56.88? 改為 192.168.56.89。
修改配置文件:
如何自動重啟 MySQL 服務(wù)
同時重啟腳本中,有一行命令是強(qiáng)制退出 keepalived(killall keepalived),這行命令可以讓 Keepalived 就有將流量切換到其他機(jī)器的能力。如果讓 keepalived 強(qiáng)制退出,則會將流量切換到另外一臺 keepalived 還存活的機(jī)器上。
這里不需要切換,就可以注釋掉這行命令。
五、總結(jié)
我們項(xiàng)目采用了數(shù)據(jù)庫讀寫分離的模式,但是沒有對從節(jié)點(diǎn)做高可用,所以也遇到從節(jié)點(diǎn)不能提供服務(wù)的問題。
本篇通過一次 MySQL 從節(jié)點(diǎn)崩了的事件,引出了如何對從節(jié)點(diǎn)做高可用,然后從實(shí)踐的角度詳細(xì)講解了如何去配置 keepalived 來保證從節(jié)點(diǎn)的高可用。
后續(xù):如何讓項(xiàng)目實(shí)現(xiàn)讀寫分離?
關(guān)于我
8 年互聯(lián)網(wǎng)開發(fā)經(jīng)驗(yàn),擅長微服務(wù)、分布式、架構(gòu)設(shè)計。目前在一家大型上市公司從事基礎(chǔ)架構(gòu)和性能優(yōu)化工作。
InfoQ 簽約作者、藍(lán)橋簽約作者、阿里云專家博主、51CTO 紅人。
本文轉(zhuǎn)載自微信公眾號「 悟空聊架構(gòu)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系悟空聊架構(gòu)公眾號。