新聞中心
大家好,我是Tom哥!

作為一名開(kāi)發(fā)同學(xué),大家對(duì) MySQL 一定不陌生,像常見(jiàn)的 事務(wù)特性、隔離級(jí)別 、索引等也都是老生常談。
今天,我們就來(lái)聊個(gè)深度話題,關(guān)于 MySQL 的 高可用。
一、什么是高可用?
維基百科定義:
高可用性(high availability,縮寫(xiě) HA),指系統(tǒng)無(wú)中斷地執(zhí)行其功能的能力,代表系統(tǒng)的可用性程度。高可用性通常通過(guò)提高系統(tǒng)的容錯(cuò)能力來(lái)實(shí)現(xiàn)。
MySQL 的高可用是如何實(shí)現(xiàn)的呢?
首先,我們來(lái)看張圖:
過(guò)程:
- 開(kāi)始時(shí),處理流程主要是 場(chǎng)景一;
- 客戶端讀、寫(xiě),訪問(wèn)的是主庫(kù);
- 主庫(kù)通過(guò)某種機(jī)制,將數(shù)據(jù)實(shí)時(shí)同步給備庫(kù);
- 當(dāng)主庫(kù)突然發(fā)生故障(如:磁盤(pán)損壞等),無(wú)法正常響應(yīng)客戶端的請(qǐng)求。此時(shí)會(huì)自動(dòng)主備切換,進(jìn)入 場(chǎng)景二;
- 客戶端讀寫(xiě),訪問(wèn)的是備庫(kù)(此時(shí)備庫(kù)升級(jí)為新主庫(kù));
看似天衣無(wú)縫,那是不是可以高枕無(wú)憂了呢???兄弟,想多了。
主備切換,確實(shí)能滿足高可用。但有個(gè)前提,主備庫(kù)的數(shù)據(jù)要同步。
不過(guò),數(shù)據(jù)同步是個(gè)異步操作,不可能做到實(shí)時(shí),所以說(shuō)主備延遲是一定存在的。
二、什么是主備延遲?
主庫(kù)完成一個(gè)事務(wù),寫(xiě)入binlog。binlog 中有一個(gè)時(shí)間字段,用于記錄主庫(kù)寫(xiě)入的時(shí)間【時(shí)刻 t1】;
- binlog 同步給備庫(kù),備庫(kù)接收并存儲(chǔ)到中繼日志 【時(shí)刻 t2】;
- 備庫(kù)SQL執(zhí)行線程執(zhí)行binlog,數(shù)據(jù)寫(xiě)入到備庫(kù)表中 【時(shí)刻 t3】;
主備延遲時(shí)間計(jì)算公式:t3 - t1
有沒(méi)有簡(jiǎn)單命令,直接查看。在備庫(kù)執(zhí)行 show slave status 命令。
seconds_behind_master,表示當(dāng)前備庫(kù)延遲了多少秒。
心細(xì)的同學(xué)會(huì)有疑問(wèn)了, t3 和 t1 分屬于兩臺(tái)機(jī)器,如果時(shí)鐘不一致怎么辦?
初始化時(shí),備庫(kù)連接到主庫(kù),會(huì)執(zhí)行 SELECT UNIX_TIMESTAMP() 來(lái)獲得當(dāng)前主庫(kù)的系統(tǒng)時(shí)間。
如果發(fā)現(xiàn)主庫(kù)的系統(tǒng)時(shí)間與備庫(kù)不一致,備庫(kù)在計(jì)算 seconds_behind_master 會(huì)自動(dòng)減掉這個(gè)差值。
注意:
binlog 數(shù)據(jù)傳輸?shù)臅r(shí)間(t2 - t1)非常短,可以忽略。主要延遲花費(fèi)在備庫(kù)執(zhí)行binlog日志。
三、主備延遲常見(jiàn)原因
1.備庫(kù)機(jī)器配置差
這個(gè)不難理解,“門(mén)當(dāng)戶對(duì)”、“志同道合”,如果主備機(jī)器的性能差別大,直接導(dǎo)致備庫(kù)的同步速度跟不上主庫(kù)的生產(chǎn)節(jié)奏。
就像跑步一樣,落后差距會(huì)越來(lái)越大。
解決方案:升級(jí)備庫(kù)的機(jī)器配置
2.備庫(kù)干私活
備庫(kù)除了服務(wù)于正常的讀業(yè)務(wù)外,是否有被其他特殊業(yè)務(wù)征用,如:運(yùn)營(yíng)數(shù)據(jù)統(tǒng)計(jì)等,這類操作非常消耗系統(tǒng)資源,也會(huì)影響數(shù)據(jù)同步速度。
解決方案:可以借助大數(shù)據(jù)平臺(tái),數(shù)據(jù)異構(gòu),滿足各種這些特殊的統(tǒng)計(jì)類查詢。
3.大事務(wù)
我們知道 binglog 是在事務(wù)提交時(shí)才生成的。
如果是處理大事務(wù),執(zhí)行時(shí)間比較長(zhǎng)(比如 5分鐘)。雖然備庫(kù)很快拿到 binlog,但是在備庫(kù)回放執(zhí)行也要花費(fèi)差不多的時(shí)間,也要 5分鐘 (備庫(kù)中,只有這個(gè)事務(wù)執(zhí)行完提交,備庫(kù)才真正對(duì)外可見(jiàn)),從而導(dǎo)致主備延遲很大。
比如 delete 操作,慎用 delete from 表名,建議采用分批刪除,減少大事務(wù)。
四、主庫(kù)不可用,主備切換有哪些策略?
1.可靠?jī)?yōu)先
當(dāng)主庫(kù)A 發(fā)生故障不可用時(shí),開(kāi)始進(jìn)入主備切換。
- 首先,判斷 B庫(kù) seconds_behind_master 是否小于設(shè)定的閾值(比如 4 秒),如果滿足條件
- 將 A庫(kù) 改為只讀狀態(tài),將 readonly 設(shè)置為 true。斷掉 A 庫(kù)的寫(xiě)入操作,保證不會(huì)有新的寫(xiě)流量進(jìn)來(lái)
- 判斷 B庫(kù)的 seconds_behind_master ,直到為 0
- 修改 B庫(kù) 為 讀、寫(xiě)狀態(tài)
- 客戶端的請(qǐng)求打到 B庫(kù)
此時(shí),主備切換完成。
優(yōu)點(diǎn):
數(shù)據(jù)不會(huì)丟失,所以我們稱為可靠性高。
缺點(diǎn):
中間有個(gè)階段,A庫(kù)和B庫(kù)都是只讀狀態(tài),此時(shí)系統(tǒng)對(duì)外不能提供寫(xiě)服務(wù)。
2.可用優(yōu)先
當(dāng)然我們也可以不用等主備數(shù)據(jù)同步完成,在一開(kāi)始時(shí)就直接將流量切到備庫(kù)。
這樣備庫(kù)的流量就可能有兩個(gè)來(lái)源:
- 主庫(kù)之前的剩余流量 binlog;
- 客戶端新請(qǐng)求進(jìn)來(lái)的流量。
兩部分流量沖擊,會(huì)對(duì) 數(shù)據(jù)一致性 造成一些影響。
我們來(lái)做個(gè)實(shí)驗(yàn):
首次創(chuàng)建一個(gè)用戶表:
CREATE TABLE `person` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
插入2條記錄:
insert into person(name) values ("tom");
insert into person(name) values ("jerry");實(shí)驗(yàn)一:
將 binlog 的格式設(shè)為 binlog_format=row;
說(shuō)明:row 模式,寫(xiě) binlog 時(shí)會(huì)記錄所有字段的值;
庫(kù)A 、庫(kù)B 在做數(shù)據(jù)同步時(shí),都會(huì)報(bào)主鍵沖突,最后只有一行數(shù)據(jù)不一致,但是會(huì)丟數(shù)據(jù)。
優(yōu)點(diǎn):同步過(guò)程中,出現(xiàn)問(wèn)題能夠及時(shí)發(fā)現(xiàn)。
實(shí)驗(yàn)二:
將 binlog 格式設(shè)置為 statement 或者 mixed;
按照 SQL 原始語(yǔ)句同步 binlog,可以看到,數(shù)據(jù)條數(shù)不會(huì)少,但是主鍵id會(huì)出現(xiàn)混亂。
3.結(jié)論
本著 "攘外必先安內(nèi)" ,保證內(nèi)部的數(shù)據(jù)的正確性是我們的選擇。所以,一般建議大家選擇 可靠?jī)?yōu)先。
但是可靠?jī)?yōu)先可能會(huì)導(dǎo)致一定時(shí)間內(nèi),數(shù)據(jù)庫(kù)不可用。這個(gè)時(shí)間值取決于主備延遲的時(shí)間大小。
所以,我們應(yīng)盡可能縮短主備庫(kù)的延遲時(shí)間大小,這樣一旦主庫(kù)發(fā)生故障,備庫(kù)才會(huì)更快的同步完數(shù)據(jù),主備切換才能完成,服務(wù)才能更快恢復(fù)。
當(dāng)前題目:MySQL主備延遲有哪些坑?主備切換策略
分享鏈接:http://m.5511xx.com/article/coocphg.html


咨詢
建站咨詢
