<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MySQL 主從同步延時問題與解決方案

          共 1761字,需瀏覽 4分鐘

           ·

          2022-01-26 10:33

          本文摘自 Doocs 開源社區(qū)《互聯(lián)網(wǎng) Java 工程師進階知識完全掃盲》手冊,方便讀者隨時隨地閱讀學習。

          也歡迎讀者們關注 GitHub 項目:https://github.com/doocs/advanced-java

          面試題

          你們有沒有做 MySQL 讀寫分離?如何實現(xiàn) MySQL 的讀寫分離?MySQL 主從復制原理的是啥?如何解決 MySQL 主從同步的延時問題?

          面試官心理分析

          高并發(fā)這個階段,肯定是需要做讀寫分離的,啥意思?因為實際上大部分的互聯(lián)網(wǎng)公司,一些網(wǎng)站,或者是 app,其實都是讀多寫少。所以針對這個情況,就是寫一個主庫,但是主庫掛多個從庫,然后從多個從庫來讀,那不就可以支撐更高的讀并發(fā)壓力了嗎?

          面試題剖析

          如何實現(xiàn) MySQL 的讀寫分離?

          其實很簡單,就是基于主從復制架構,簡單來說,就搞一個主庫,掛多個從庫,然后我們就單單只是寫主庫,然后主庫會自動把數(shù)據(jù)給同步到從庫上去。

          MySQL 主從復制原理的是啥?

          主庫將變更寫入 binlog 日志,然后從庫連接到主庫之后,從庫有一個 IO 線程,將主庫的 binlog 日志拷貝到自己本地,寫入一個 relay 中繼日志中。接著從庫中有一個 SQL 線程會從中繼日志讀取 binlog,然后執(zhí)行 binlog 日志中的內容,也就是在自己本地再次執(zhí)行一遍 SQL,這樣就可以保證自己跟主庫的數(shù)據(jù)是一樣的。

          mysql-master-slave

          這里有一個非常重要的一點,就是從庫同步主庫數(shù)據(jù)的過程是串行化的,也就是說主庫上并行的操作,在從庫上會串行執(zhí)行。所以這就是一個非常重要的點了,由于從庫從主庫拷貝日志以及串行執(zhí)行 SQL 的特點,在高并發(fā)場景下,從庫的數(shù)據(jù)一定會比主庫慢一些,是有延時的。所以經(jīng)常出現(xiàn),剛寫入主庫的數(shù)據(jù)可能是讀不到的,要過幾十毫秒,甚至幾百毫秒才能讀取到。

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

          所以 MySQL 實際上在這一塊有兩個機制,一個是半同步復制,用來解決主庫數(shù)據(jù)丟失問題;一個是并行復制,用來解決主從同步延時問題。

          這個所謂半同步復制,也叫?semi-sync?復制,指的就是主庫寫入 binlog 日志之后,就會將強制此時立即將數(shù)據(jù)同步到從庫,從庫將日志寫入自己本地的 relay log 之后,接著會返回一個 ack 給主庫,主庫接收到至少一個從庫的 ack 之后才會認為寫操作完成了。

          所謂并行復制,指的是從庫開啟多個線程,并行讀取 relay log 中不同庫的日志,然后并行重放不同庫的日志,這是庫級別的并行。

          MySQL 主從同步延時問題(精華)

          以前線上確實處理過因為主從同步延時問題而導致的線上的 bug,屬于小型的生產(chǎn)事故。

          是這個么場景。有個同學是這樣寫代碼邏輯的。先插入一條數(shù)據(jù),再把它查出來,然后更新這條數(shù)據(jù)。在生產(chǎn)環(huán)境高峰期,寫并發(fā)達到了 2000/s,這個時候,主從復制延時大概是在小幾十毫秒。線上會發(fā)現(xiàn),每天總有那么一些數(shù)據(jù),我們期望更新一些重要的數(shù)據(jù)狀態(tài),但在高峰期時候卻沒更新。用戶跟客服反饋,而客服就會反饋給我們。

          我們通過 MySQL 命令:

          show?slave?status

          查看?Seconds_Behind_Master?,可以看到從庫復制主庫的數(shù)據(jù)落后了幾 ms。

          一般來說,如果主從延遲較為嚴重,有以下解決方案:

          ?分庫,將一個主庫拆分為多個主庫,每個主庫的寫并發(fā)就減少了幾倍,此時主從延遲可以忽略不計。?打開 MySQL 支持的并行復制,多個庫并行復制。如果說某個庫的寫入并發(fā)就是特別高,單庫寫并發(fā)達到了 2000/s,并行復制還是沒意義。?重寫代碼,寫代碼的同學,要慎重,插入數(shù)據(jù)時立馬查詢可能查不到。?如果確實是存在必須先插入,立馬要求就查詢到,然后立馬就要反過來執(zhí)行一些操作,對這個查詢設置直連主庫不推薦這種方法,你要是這么搞,讀寫分離的意義就喪失了。




          瀏覽 34
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产在线新址 | 女人天堂中文字幕 | 日韩免费毛片 | 国语对白自拍 | 蜜桃视频免费网站 |