大家有沒有作 MySQL 讀寫分離?如何實現 MySQL 的讀寫分離?MySQL 主從複製原理的是啥?如何解決 MySQL 主從同步的延時問題?面試
主庫將變動寫入 binlog 日誌,而後從庫鏈接到主庫以後,從庫有一個 IO 線程,將主庫的 binlog 日誌拷貝到本身本地,寫入一個 relay 中繼日誌中。接着從庫中有一個 SQL 線程會從中繼日誌讀取 binlog,而後執行 binlog 日誌中的內容,也就是在本身本地再次執行一遍 SQL,這樣就能夠保證本身跟主庫的數據是同樣的。併發
這裏有一個很是重要的一點,就是從庫同步主庫數據的過程是串行化的,也就是說主庫上並行的操做,在從庫上會串行執行。因此這就是一個很是重要的點了,因爲從庫從主庫拷貝日誌以及串行執行 SQL 的特色,在高併發場景下,從庫的數據必定會比主庫慢一些,是有延時的。因此常常出現,剛寫入主庫的數據多是讀不到的,要過幾十毫秒,甚至幾百毫秒才能讀取到。高併發
並且這裏還有另一個問題,就是若是主庫忽然宕機,而後剛好數據還沒同步到從庫,那麼有些數據可能在從庫上是沒有的,有些數據可能就丟失了。線程
因此 MySQL 實際上在這一塊有兩個機制,一個是半同步複製,用來解決主庫數據丟失問題;一個是並行複製,用來解決主從同步延時問題。日誌
這個所謂半同步複製,也叫 semi-sync 複製,指的就是主庫寫入 binlog 日誌以後,就會將強制此時當即將數據同步到從庫,從庫將日誌寫入本身本地的 relay log 以後,接着會返回一個 ack 給主庫,主庫接收到至少一個從庫的 ack 以後纔會認爲寫操做完成了。cdn
所謂並行複製,指的是從庫開啓多個線程,並行讀取 relay log 中不一樣庫的日誌,而後並行重放不一樣庫的日誌,這是庫級別的並行。blog
之前線上確實處理過由於主從同步延時問題而致使的線上的 bug,屬於小型的生產事故。同步
是這個麼場景。有個同窗是這樣寫代碼邏輯的。先插入一條數據,再把它查出來,而後更新這條數據。在生產環境高峯期,寫併發達到了 2000/s,這個時候,主從複製延時大概是在小几十毫秒。線上會發現,天天總有那麼一些數據,咱們指望更新一些重要的數據狀態,但在高峯期時候卻沒更新。用戶跟客服反饋,而客服就會反饋給咱們。it
咱們經過 MySQL 命令:io
show status 查看 Seconds_Behind_Master,能夠看到從庫複製主庫的數據落後了幾 ms。
通常來講,若是主從延遲較爲嚴重,有如下解決方案:
分庫,將一個主庫拆分爲多個主庫,每一個主庫的寫併發就減小了幾倍,此時主從延遲能夠忽略不計。 打開 MySQL 支持的並行複製,多個庫並行複製。若是說某個庫的寫入併發就是特別高,單庫寫併發達到了 2000/s,並行複製仍是沒意義。 重寫代碼,寫代碼的同窗,要慎重,插入數據時立馬查詢可能查不到。 若是確實是存在必須先插入,立馬要求就查詢到,而後立馬就要反過來執行一些操做,對這個查詢設置直連主庫。不推薦這種方法,你要是這麼搞,讀寫分離的意義就喪失了。