如何實現 MySQL 的讀寫分離?MySQL 主從複製原理的是啥?如何解決 MySQL 主從同步的延時問題?

 

  高併發這個階段,確定是須要作讀寫分離的,啥意思?由於實際上大部分的互聯網公司,一些網站,或者是 app,其實都是讀多寫少。因此針對這個狀況,就是寫一個主庫,可是主庫掛多個從庫,而後從多個從庫來讀,那不就能夠支撐更高的讀併發壓力了嗎?sql

如何實現 MySQL 的讀寫分離?

  其實很簡單,就是基於主從複製架構,簡單來講,就搞一個主庫,掛多個從庫,而後咱們就單單只是寫主庫,而後主庫會自動把數據給同步到從庫上去。架構

MySQL 主從複製原理的是啥?

  主庫將變動寫入 binlog 日誌,而後從庫鏈接到主庫以後,從庫有一個 IO 線程,將主庫的 binlog 日誌拷貝到本身本地,寫入一個 relay 中繼日誌中。接着從庫中有一個 SQL 線程會從中繼日誌讀取 binlog,而後執行 binlog 日誌中的內容,也就是在本身本地再次執行一遍 SQL,這樣就能夠保證本身跟主庫的數據是同樣的。併發

  這裏有一個很是重要的一點,就是從庫同步主庫數據的過程是串行化的,也就是說主庫上並行的操做,在從庫上會串行執行。因此這就是一個很是重要的點了,因爲從庫從主庫拷貝日誌以及串行執行 SQL 的特色,在高併發場景下,從庫的數據必定會比主庫慢一些,是有延時的。因此常常出現,剛寫入主庫的數據多是讀不到的,要過幾十毫秒,甚至幾百毫秒才能讀取到。app

  並且這裏還有另一個問題,就是若是主庫忽然宕機,而後剛好數據還沒同步到從庫,那麼有些數據可能在從庫上是沒有的,有些數據可能就丟失了。高併發

  因此 MySQL 實際上在這一塊有兩個機制,一個是半同步複製,用來解決主庫數據丟失問題;一個是並行複製,用來解決主從同步延時問題。網站

  這個所謂半同步複製,也叫 semi-sync 複製,指的就是主庫寫入 binlog 日誌以後,就會將強制此時當即將數據同步到從庫,從庫將日誌寫入本身本地的 relay log 以後,接着會返回一個 ack 給主庫,主庫接收到至少一個從庫的 ack 以後纔會認爲寫操做完成了。線程

  所謂並行複製,指的是從庫開啓多個線程,並行讀取 relay log 中不一樣庫的日誌,而後並行重放不一樣庫的日誌,這是庫級別的並行。日誌

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

  之前線上確實處理過由於主從同步延時問題而致使的線上的 bug,屬於小型的生產事故。code

是這個麼場景。有個同窗是這樣寫代碼邏輯的。先插入一條數據,再把它查出來,而後更新這條數據。在生產環境高峯期,寫併發達到了 2000/s,這個時候,主從複製延時大概是在小几十毫秒。線上會發現,天天總有那麼一些數據,咱們指望更新一些重要的數據狀態,但在高峯期時候卻沒更新。用戶跟客服反饋,而客服就會反饋給咱們。blog

咱們經過 MySQL 命令:

show status

  查看 Seconds_Behind_Master,能夠看到從庫複製主庫的數據落後了幾 ms。

  通常來講,若是主從延遲較爲嚴重,有如下解決方案:

  • 分庫,將一個主庫拆分爲多個主庫,每一個主庫的寫併發就減小了幾倍,此時主從延遲能夠忽略不計。
  • 打開 MySQL 支持的並行複製,多個庫並行複製。若是說某個庫的寫入併發就是特別高,單庫寫併發達到了 2000/s,並行複製仍是沒意義。
  • 重寫代碼,寫代碼的同窗,要慎重,插入數據時立馬查詢可能查不到。
  • 若是確實是存在必須先插入,立馬要求就查詢到,而後立馬就要反過來執行一些操做,對這個查詢設置直連主庫。不推薦這種方法,你要是這麼搞,讀寫分離的意義就喪失了。
相關文章
相關標籤/搜索