讀寫分離主要目的就是分?jǐn)傊鲙斓膲毫Α?/p>
讀寫分離主要有兩種架構(gòu):客戶端直連和中間代理層proxy
- 客戶端直連:性能好、架構(gòu)簡單、排查方便树碱,伴隨組件Zookeeper一起用
- proxy架構(gòu):對(duì)客戶端友好,客戶端不需要關(guān)注后端細(xì)節(jié),架構(gòu)復(fù)雜杜耙,需要高可用架構(gòu)
應(yīng)對(duì)主備延遲的幾種方案
- 強(qiáng)制走主庫
- sleep
- 判斷主備無延遲
- 配合semi-sync
- 等主庫位點(diǎn)
- 等GTID
1. 強(qiáng)制走主庫
將查詢分類,對(duì)必須要拿到最新結(jié)果的查詢拂盯,就強(qiáng)制走主庫佑女,其它就走從庫
2. sleep
主庫更新后,讀從之前先sleep一下
3. 判斷主備無延遲
每次從庫執(zhí)行查詢請(qǐng)求前谈竿,先判斷 seconds_behind_master 是否已經(jīng)等于 0团驱。如果還不等于 0 ,那就必須等到這個(gè)參數(shù)變?yōu)?0 才能執(zhí)行查詢請(qǐng)求空凸。
seconds_behind_master 的單位是秒嚎花,如果你覺得精度不夠的話,還可以采用對(duì)比位點(diǎn)和 GTID 的方法來確保主備無延遲呀洲,也就是我們接下來要說的第二和第三種方法紊选。
4. 配合semi-sync
要解決這個(gè)問題,就要引入半同步復(fù)制道逗,也就是 semi-sync replication兵罢。
semi-sync 做了這樣的設(shè)計(jì):
- 事務(wù)提交的時(shí)候,主庫把 binlog 發(fā)給從庫滓窍;
- 從庫收到 binlog 以后卖词,發(fā)回給主庫一個(gè) ack,表示收到了吏夯;
- 主庫收到這個(gè) ack 以后此蜈,才能給客戶端返回“事務(wù)完成”的確認(rèn)。
也就是說噪生,如果啟用了 semi-sync裆赵,就表示所有給客戶端發(fā)送過確認(rèn)的事務(wù),都確保了備庫已經(jīng)收到了這個(gè)日志跺嗽。
5. 等主庫位點(diǎn)
- trx1 事務(wù)更新完成后顾瞪,馬上執(zhí)行 show master status 得到當(dāng)前主庫執(zhí)行到的 File 和 Position;
- 選定一個(gè)從庫執(zhí)行查詢語句抛蚁;
- 在從庫上執(zhí)行 select master_pos_wait(File, Position, 1)陈醒;
- 如果返回值是 >=0 的正整數(shù),則在這個(gè)從庫執(zhí)行查詢語句瞧甩;
- 否則钉跷,到主庫執(zhí)行查詢語句。
6. 等GTID
從MySQL 5.6.5 開始新增了一種基于 GTID 的復(fù)制方式肚逸。通過 GTID 保證了每個(gè)在主庫上提交的事務(wù)在集群中有一個(gè)唯一的ID爷辙。這種方式強(qiáng)化了數(shù)據(jù)庫的主備一致性彬坏,故障恢復(fù)以及容錯(cuò)能力。
GTID (Global Transaction ID)是全局事務(wù)ID,當(dāng)在主庫上提交事務(wù)或者被從庫應(yīng)用時(shí)膝晾,可以定位和追蹤每一個(gè)事務(wù)栓始。
GTID 的執(zhí)行流程就變成了:
- trx1 事務(wù)更新完成后,從返回包直接獲取這個(gè)事務(wù)的 GTID血当,記為 gtid1幻赚;
- 選定一個(gè)從庫執(zhí)行查詢語句;
- 在從庫上執(zhí)行 select wait_for_executed_gtid_set(gtid1, 1)臊旭;
- 如果返回值是 0落恼,則在這個(gè)從庫執(zhí)行查詢語句;
- 否則离熏,到主庫執(zhí)行查詢語句佳谦。