突破Java面試(50)-MySQL讀寫分離及主從同步延時(shí)解決方案

0 Github

1 面試題

  • 有沒有做過MySQL讀寫分離
  • 如何實(shí)現(xiàn)MySQL的讀寫分離
  • 主從復(fù)制原理
  • 如何解決MySQL主從同步的延時(shí)問題

準(zhǔn)備好面對(duì)這炮轟式面試了嗎?

2 考點(diǎn)分析

高并發(fā)階段,肯定需要做讀寫分離.

實(shí)際上大部分互聯(lián)網(wǎng)公司/網(wǎng)站/APP,都是讀多寫少

針對(duì)現(xiàn)狀,寫一個(gè)主庫,掛著多個(gè)從庫,然后從多個(gè)從庫來讀,那不就可以支撐更高的讀并發(fā)壓力了嗎?

3 MySQL讀寫分離的實(shí)現(xiàn)

基于主從復(fù)制架構(gòu)

搞一個(gè)主庫,掛多個(gè)從庫,然后就單單只是寫主庫,接著主庫會(huì)自動(dòng)將數(shù)據(jù)同步到從庫

4 MySQL主從復(fù)制的原理

  • 為什么MySQL要讀寫分離?

    image

主庫將變更寫binlog日志,然后從庫連接到主庫后,從庫有一個(gè)I/O線程,將主庫的binlog日志拷貝到本地,寫入一個(gè)中繼日志

接著從庫中有一個(gè)SQL線程會(huì)從中繼日志讀取binlog,然后執(zhí)行binlog日志中的內(nèi)容

即在本地再次執(zhí)行一遍SQL,確保跟主庫的數(shù)據(jù)相同

  • MySQL主從復(fù)制原理

    image

從庫同步主庫數(shù)據(jù)的過程是串行化的,即主庫上并行的操作,在從庫上會(huì)串行執(zhí)行.

由于從庫從主庫拷貝日志以及串行執(zhí)行SQL的特點(diǎn),在高并發(fā)場(chǎng)景下是有延時(shí)的,從庫數(shù)據(jù)一定會(huì)比主庫慢一些,所以經(jīng)常出現(xiàn),剛寫入主庫的數(shù)據(jù)可能是讀不到的,要過幾十甚至幾百ms才能讀到

而且這里還有另外一個(gè)問題,若主庫突然宕機(jī),恰好數(shù)據(jù)還沒同步到從庫,那么有些數(shù)據(jù)可能在從庫上是沒有的,可能就這么丟失了

所以MySQL實(shí)際上在這有兩個(gè)機(jī)制

半同步復(fù)制(semi-sync)

解決主庫數(shù)據(jù)丟失問題

主庫寫入binlog日志后,就會(huì)強(qiáng)制此時(shí)立即將數(shù)據(jù)同步到從庫

從庫將日志寫入自己本地的relay log后,會(huì)返回一個(gè)ack給主庫

主庫接收到至少一個(gè)從庫的ack之后才會(huì)認(rèn)為寫操作完成

并行復(fù)制

解決主從同步延時(shí)問題

從庫開啟多個(gè)線程,并行讀取relay log中不同庫的日志,然后并行重放不同庫的日志,這是庫級(jí)別的并行

5 MySQL主從同步延時(shí)問題(核心)

  • MySQL主從延遲導(dǎo)致的生產(chǎn)環(huán)境的問題

    image

你可以看到從庫復(fù)制主庫的數(shù)據(jù)落后了多少ms

其實(shí)這塊東西經(jīng)常會(huì)碰到,就比如說用了MySQL主從架構(gòu)后,可能會(huì)發(fā)現(xiàn),剛寫入庫的數(shù)據(jù)結(jié)果沒查到,結(jié)果就完蛋了

所以實(shí)際上你要考慮好應(yīng)該在什么場(chǎng)景下來用這個(gè)MySQL主從同步

建議一般在讀遠(yuǎn)遠(yuǎn)多于寫,且讀的時(shí)候一般對(duì)數(shù)據(jù)時(shí)效性要求沒那么高的時(shí)候采用

所以我們可以考慮的就是,你可以用MySQL的并行復(fù)制,但問題是那是庫級(jí)別的并行,所以有時(shí)候作用不是很大

此時(shí),通常來說,我們會(huì)對(duì)于那種寫后立馬就要保證可以查到的場(chǎng)景,采用強(qiáng)制讀主庫的方式

確保你肯定可以讀到數(shù)據(jù)。其實(shí)用一些數(shù)據(jù)庫中間件也是沒問題的。

一般若主從延遲較為嚴(yán)重

  1. 分庫 : 將一個(gè)主庫拆分為4個(gè)主庫,每個(gè)主庫的寫并發(fā)就500/s,此時(shí)主從延遲可忽略不計(jì)
  2. 打開MySQL支持的并行復(fù)制,多個(gè)庫并行復(fù)制,若某個(gè)庫的寫入并發(fā)特別高,寫并發(fā)達(dá)到了2000/s,并行復(fù)制還是沒意義。二八法則,很多時(shí)候比如說,就是少數(shù)的幾個(gè)訂單表,寫入了2000/s,其他幾十個(gè)表10/s
  3. 重寫代碼 : 寫代碼的同學(xué),要慎重,重寫一下代碼,插入數(shù)據(jù)之后,直接就更新,不要查詢
  4. 若確實(shí)存在必須先插入,立馬要求就查詢到,然后立馬就要反過來執(zhí)行一些操作,對(duì)這個(gè)查詢?cè)O(shè)置直連主庫(不推薦,這么搞導(dǎo)致讀寫分離的意義就喪失了)

參考

  • 《Java工程師面試突擊第1季-中華石杉老師》
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容