讀寫(xiě)分離主要目的就是分?jǐn)傊鲙?kù)的壓力。
讀寫(xiě)分離主要有兩種架構(gòu):客戶端直連和中間代理層proxy
- 客戶端直連:性能好、架構(gòu)簡(jiǎn)單、排查方便,伴隨組件Zookeeper一起用
- proxy架構(gòu):對(duì)客戶端友好,客戶端不需要關(guān)注后端細(xì)節(jié),架構(gòu)復(fù)雜,需要高可用架構(gòu)
應(yīng)對(duì)主備延遲的幾種方案
- 強(qiáng)制走主庫(kù)
- sleep
- 判斷主備無(wú)延遲
- 配合semi-sync
- 等主庫(kù)位點(diǎn)
- 等GTID
1. 強(qiáng)制走主庫(kù)
將查詢分類,對(duì)必須要拿到最新結(jié)果的查詢,就強(qiáng)制走主庫(kù),其它就走從庫(kù)
2. sleep
主庫(kù)更新后,讀從之前先sleep一下
3. 判斷主備無(wú)延遲
每次從庫(kù)執(zhí)行查詢請(qǐng)求前,先判斷 seconds_behind_master 是否已經(jīng)等于 0。如果還不等于 0 ,那就必須等到這個(gè)參數(shù)變?yōu)?0 才能執(zhí)行查詢請(qǐng)求。
seconds_behind_master 的單位是秒,如果你覺(jué)得精度不夠的話,還可以采用對(duì)比位點(diǎn)和 GTID 的方法來(lái)確保主備無(wú)延遲,也就是我們接下來(lái)要說(shuō)的第二和第三種方法。
4. 配合semi-sync
要解決這個(gè)問(wèn)題,就要引入半同步復(fù)制,也就是 semi-sync replication。
semi-sync 做了這樣的設(shè)計(jì):
- 事務(wù)提交的時(shí)候,主庫(kù)把 binlog 發(fā)給從庫(kù);
- 從庫(kù)收到 binlog 以后,發(fā)回給主庫(kù)一個(gè) ack,表示收到了;
- 主庫(kù)收到這個(gè) ack 以后,才能給客戶端返回“事務(wù)完成”的確認(rèn)。
也就是說(shuō),如果啟用了 semi-sync,就表示所有給客戶端發(fā)送過(guò)確認(rèn)的事務(wù),都確保了備庫(kù)已經(jīng)收到了這個(gè)日志。
5. 等主庫(kù)位點(diǎn)
- trx1 事務(wù)更新完成后,馬上執(zhí)行 show master status 得到當(dāng)前主庫(kù)執(zhí)行到的 File 和 Position;
- 選定一個(gè)從庫(kù)執(zhí)行查詢語(yǔ)句;
- 在從庫(kù)上執(zhí)行 select master_pos_wait(File, Position, 1);
- 如果返回值是 >=0 的正整數(shù),則在這個(gè)從庫(kù)執(zhí)行查詢語(yǔ)句;
- 否則,到主庫(kù)執(zhí)行查詢語(yǔ)句。
6. 等GTID
從MySQL 5.6.5 開(kāi)始新增了一種基于 GTID 的復(fù)制方式。通過(guò) GTID 保證了每個(gè)在主庫(kù)上提交的事務(wù)在集群中有一個(gè)唯一的ID。這種方式強(qiáng)化了數(shù)據(jù)庫(kù)的主備一致性,故障恢復(fù)以及容錯(cuò)能力。
GTID (Global Transaction ID)是全局事務(wù)ID,當(dāng)在主庫(kù)上提交事務(wù)或者被從庫(kù)應(yīng)用時(shí),可以定位和追蹤每一個(gè)事務(wù)。
GTID 的執(zhí)行流程就變成了:
- trx1 事務(wù)更新完成后,從返回包直接獲取這個(gè)事務(wù)的 GTID,記為 gtid1;
- 選定一個(gè)從庫(kù)執(zhí)行查詢語(yǔ)句;
- 在從庫(kù)上執(zhí)行 select wait_for_executed_gtid_set(gtid1, 1);
- 如果返回值是 0,則在這個(gè)從庫(kù)執(zhí)行查詢語(yǔ)句;
- 否則,到主庫(kù)執(zhí)行查詢語(yǔ)句。