MySQL之讀寫分離
1. 前言
MySQL
讀寫分離的作用同Redis
主從複製一樣,寫請求由Master
負責,讀請求由Slave
負責。從而實現讀寫在不同實例完成,提高讀寫的併發量。
2. 複製的工作原理
複製分爲以下3
個步驟:
master
把數據更改記錄到二進制日誌(binlog
)中。slave
把主服務器的二進制日誌複製到自己的中繼日誌(relay log
)中。- 從服務器重做中繼日誌中的日誌,把更改應用到自己的數據庫上,以達到數據的一致性。
複製並不是實時地進行同步,而是異步實時。這樣就有可能在數據被寫入到master
後,還沒有同步到slave
,在這期間便造成了主從不一致。
主服務器有一個線程負責發送二進制日誌。
從服務器有 2 個線程,一個是I/O
線程,負責讀取主服務器地二進制日誌,並將其保存爲中繼日誌;另一個是SQL
線程,負責執行中繼日誌。
3. 主從不一致原因
- 從庫同步主庫數據的過程是串行化的,也就是說主庫上並行的操作,在從庫上會串行執行。所以這就是一個非常重要的點了,由於從庫從主庫拷貝日誌以及串行執行
SQL
的特點,在高併發場景下,從庫的數據一定會比主庫慢一些,是有延時的。所以經常出現,剛寫入主庫的數據可能是讀不到的,要過幾十毫秒,甚至幾百毫秒才能讀取到。 - 還有另外一個問題,就是如果主庫突然宕機,然後恰好數據還沒同步到從庫,那麼有些數據可能在從庫上是沒有的,有些數據可能就丟失了。
4. 主從不一致解決方案
- 半同步複製
半同步複製,用來解決主庫數據丟失問題。
semi-sync
複製,指的就是主庫寫入binlog
日誌之後,就會將強制此時立即將數據同步到從庫,從庫將日誌寫入自己本地的relay log
之後,接着會返回一個ack
給主庫,主庫接收到至少一個從庫的ack
之後纔會認爲寫操作完成了。
- 並行複製
並行複製,用來解決主從同步延時問題。
並行複製,指的是從庫開啓多個線程,並行讀取relay log
中不同庫的日誌,然後並行重寫不同庫的日誌,這是庫級別的並行。但這是庫級別的並行,所以有時候作用不是很大。
如果主從延遲較爲嚴重,可以採用以下方案:
- 分庫
不進行讀寫分離,將一個主庫拆分成多個主庫,這樣便可以提高併發量和吞吐量。在Redis
分佈式鎖的實現中,正是由於主從數據可能不一致,我們選擇多個Master
,而沒有使用讀寫分離的方案。
- 如果確實是存在必須先插入,立馬要求就查詢到,然後立馬就要反過來執行一些操作,對這個查詢設置直連主庫。
這樣造成的效果便是我們原本採用讀寫分離的方案,但此時沒有進行分離。
- 修改代碼邏輯