面試官:MySQL雙主架構(gòu)有什么優(yōu)缺點(diǎn)?
大家好,我是君哥。
雙主架構(gòu)是 MySQL 常見(jiàn)的一種架構(gòu)模式,它的特點(diǎn)是有兩個(gè)主節(jié)點(diǎn)對(duì)外提供服務(wù),并且這兩個(gè)主節(jié)點(diǎn)互為主備。今天來(lái)學(xué)習(xí)一下雙主架構(gòu)。
1.雙主復(fù)制
這種架構(gòu)的特點(diǎn)配置兩個(gè)主庫(kù),每個(gè)主庫(kù)都提供讀寫服務(wù),并且這兩個(gè)主庫(kù)互為主備。如下圖:
在 M1 寫入的數(shù)據(jù)要同步到 M2,在 M2 寫入的數(shù)據(jù)要同步到 M1。這種兩個(gè)主庫(kù)同時(shí)支持寫入,這種架構(gòu)模式一個(gè)明顯的優(yōu)勢(shì)寫入效率高。比如一個(gè)應(yīng)用在不同的城市部署了兩個(gè)主節(jié)點(diǎn),請(qǐng)求可以就近選擇寫入數(shù)據(jù)庫(kù)。
但這種架構(gòu)在數(shù)據(jù)同步時(shí)很容易出問(wèn)題。
案例一:M1 和 M2 同時(shí)收到一張表的插入請(qǐng)求,這張表是自增主鍵,兩張表插入后主鍵相同。這時(shí)發(fā)生數(shù)據(jù)同步,這條插入語(yǔ)句在 binlog 里面記錄的是 row 格式,同步時(shí)發(fā)生主鍵沖突。
MySQL binlog 有三種格式:
- STATEMENT:記錄的是 SQL 語(yǔ)句本身;
- ROW:記錄的是數(shù)據(jù)的變化;
- MIXED:STATEMENT 和 ROW 格式的結(jié)合,MySQL 會(huì)根據(jù) SQL 語(yǔ)句特性選擇使用 STATEMENT 還是 ROW 格式。
MySQL 5.0 后可以通過(guò)設(shè)置 auto_increment_increment 和 auto_increment_offset 這兩個(gè)選項(xiàng)來(lái)解決這個(gè)問(wèn)題。
案例二:在 M1 上執(zhí)行了一條語(yǔ)句,生成 binlog 后發(fā)給 M2 進(jìn)行同步,M2 執(zhí)行完成后又生成 binlog 同步給 A,導(dǎo)致一條語(yǔ)句循環(huán)復(fù)制。
這個(gè)問(wèn)題的解決方法是要求 M1 和 M2 的 server id不相同,M1 產(chǎn)生的 binlog 記錄 server id 是 M1,M2 執(zhí)行同步時(shí)生成的 binlog 也記錄 server id 為 M1。這樣同步給 M1 是,M1 判斷到 server id 跟自己相同,就丟棄這個(gè)日志,不做同步。
案例三:同步過(guò)程中會(huì)有數(shù)據(jù)不一致的問(wèn)題。比如用戶 xiaoming 的賬戶余額是 100。M1 執(zhí)行了 update 操作把賬戶余額更新成 150,M2 執(zhí)行了 update 操作更新成 130。
解決這種數(shù)據(jù)不一致問(wèn)題的一個(gè)思路是嚴(yán)格劃分?jǐn)?shù)據(jù)和設(shè)置權(quán)限,比如案例中小明的所有數(shù)據(jù)只能在 M1 上操作。
案例四:因?yàn)楣?jié)點(diǎn)發(fā)生故障,M1 不能復(fù)制了,但是應(yīng)用可以寫數(shù)據(jù)庫(kù),M2 能正常寫和復(fù)制,這個(gè)問(wèn)題就很難解決了。
解決這個(gè)問(wèn)題,需要給 M1 和 M2 配置從節(jié)點(diǎn),主節(jié)點(diǎn)故障后切換到從節(jié)點(diǎn)進(jìn)行工作。
2.主備復(fù)制
這個(gè)架構(gòu)模式的特點(diǎn)是雙主節(jié)點(diǎn)中,同一時(shí)刻只有一個(gè)主節(jié)點(diǎn)提供寫服務(wù),另一個(gè)主節(jié)點(diǎn)只能提供讀服務(wù)。如下圖:
這個(gè)架構(gòu)相當(dāng)于比單主節(jié)點(diǎn)架構(gòu)多了一個(gè)熱備,有如下優(yōu)勢(shì):
- 因?yàn)?M1 和 M2 配置對(duì)稱,切換主備比較容易;
- 有助于故障轉(zhuǎn)移和恢復(fù);
- 可以在不影響應(yīng)用的情況下進(jìn)行數(shù)據(jù)庫(kù)升級(jí)和維護(hù);
- 不用考慮循環(huán)復(fù)制問(wèn)題和主備不一致問(wèn)題。
當(dāng)然,主備架構(gòu)也有缺點(diǎn),那就是寫性能不能得到提升。
3.主主架構(gòu)擁有備庫(kù)
主主架構(gòu)中每個(gè)主庫(kù)也可以擁有備庫(kù),如下圖:
這種配置為每個(gè)主庫(kù)增加了一個(gè)備份,可以防止單點(diǎn)故障,同時(shí)備庫(kù)也可以處理讀請(qǐng)求,提高數(shù)據(jù)庫(kù)整體讀效率。
這個(gè)架構(gòu)的缺點(diǎn)是增加了機(jī)器成本。
4.環(huán)形復(fù)制
環(huán)形復(fù)制架構(gòu)是 MySQL 集群中擁有多個(gè)主庫(kù),主庫(kù)之間形成一個(gè)環(huán)形,前面一個(gè)節(jié)點(diǎn)是當(dāng)前節(jié)點(diǎn)的主庫(kù),當(dāng)前節(jié)點(diǎn)是前面節(jié)點(diǎn)的備庫(kù),也是后面一個(gè)節(jié)點(diǎn)的主庫(kù)。如下圖:
環(huán)形復(fù)制這種架構(gòu)其實(shí)并不推薦,因?yàn)樗茈y做到故障轉(zhuǎn)移,高可用特性依賴于每個(gè)節(jié)點(diǎn)不出故障。但是如果一個(gè)節(jié)點(diǎn)出了故障,去掉這個(gè)節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)產(chǎn)生的 binlog 將一直循環(huán)復(fù)制下去,因?yàn)橹挥型ㄟ^(guò)這個(gè)節(jié)點(diǎn)的 server id 才能做出判斷停止復(fù)制。
5.總結(jié)
本文介紹了 MySQL 雙主架構(gòu)的多種復(fù)制架構(gòu),雙主架構(gòu)需要注意解決循環(huán)復(fù)制、單點(diǎn)故障問(wèn)題,同時(shí)做好數(shù)據(jù)權(quán)限劃分。