MYSQL主從復制原理
最近在做項目的時候,因為部署了 MYSQL主從復制 所以在這里記錄下整個過程。這里一共會分兩篇博客來寫:
1、Mysql主從復制原理
2、docker部署Mysql主從復制實戰
這篇只寫MYSQL主從復制原理。
一、概述
1、什么是主從復制?
概念
主從復制是用來建立一個和 主數據庫完全一樣的數據庫環境稱為從數據庫;主數據庫一般是准實時的業務數據庫。
2、主從復制作用
我們來思考如果在企業網站中,后端MYSQL數據庫只有一台時候,會有以下問題
1、單點故障服務不可用
2、無法處理大量的並發數據請求
3、數據丟失
所以通過主從復制后,它的優點就很明顯
1、如果主節點出現故障,那么我們就直接將服務切到從節點,來保證服務立馬可用。
2、如果並發請求特別大的時候,我們可用進行讀寫分離操作,讓主庫負責寫,從庫負責讀。
3、如果主庫數據丟失,但從庫還保存一份,減少數據丟失的風險。
二、主從復制原理
1、主從復制原理
這里先放一張圖,這張圖很好的詮釋的主從復制的原理

上面主要分成了三步,下面會詳細說明。
(1) Master的更新事件(update、insert、delete)會按照順序寫入bin-log
中。當Slave連接到Master的后,Master機器會為Slave開啟
binlog dump
線程,該線程會去讀取bin-log日志
(2) Slave連接到Master后,Slave庫有一個I/O線程
通過請求binlog dump thread讀取bin-log日志,然后寫入從庫的relay log
日志中。
(3) Slave還有一個 SQL線程
,實時監控 relay-log日志內容是否有更新,解析文件中的SQL語句,在Slave數據庫中去執行。
總結
(1) 既然是要把事件記錄到bin-log日志,那么對於Master就必須開啟bin-log功能。
(2) 整個Mysql主從復制一共開啟了3個線程。Master開啟 IO線程,Slave開啟 IO線程 和 SQL線程。
(3) 這點也很重要那就是Master和Slave交互的時候,記住這里是Slave去請求Master,而不是Master主動推給Slave
。Slave通過IO線程
連接Master后發起請求,Master服務器收到Slave IO線程發來的日志請求信息,io線程去將bin-log內容返回給slave IO線程。
2、MySQL主從復制同步方式
(1)異步復制
MySQL主從同步 默認是異步復制的。就是上面三步中,只有第一步是同步的(也就是Mater寫入bin log日志),就是主庫寫入binlog日志后即可成功返回客戶端,無須等待binlog
日志傳遞給從庫的過程。Master 不關心 Slave 的數據有沒有寫入成功。因此如果Master和Slave之間有網絡延遲,就會造成暫時的數據不一致的現象;如果Master出故障,而數據
還沒有復制過去,則會造成數據丟失;但也有好處,效率較其他兩種復制方式最高。
(2)同步復制
對於同步復制而言,Master主機將事件發送給Slave主機后會觸發一個等待,直到所有Slave節點
(如果有多個Slave)返回數據復制成功的信息給Master。這種復制方式最安
全,但是同時,效率也是最差的。
(3)半同步復制
對於半同步復制而言,Master主機將事件發送給Slave主機后會觸發一個等待,直到其中一個Slave節點
(如果有多個Slave)返回數據復制成功的信息給Master。由此增強了
數據的一致性,但是因為Master主機的確認開銷,會損耗一部分的性能;另外,半同步復制除了不需要等待所有Slave主機確認事件的接收外,半同步數據復制並不要求那些事件
完全地執行,因此,仍有可能看到在Slave主機上數據復制延遲的發生,如果因為網絡延遲等原因造成Slave遲遲沒有返回復制成功的信息,超過了Master設置的超時時長,半同步
復制就降級為異步復制方式,而后繼續數據復制。
三、Mysql主從同步延時
上面也說了,Mysql默認采用的異步操作,因為它的效率明顯是最高的。因為只要寫入bin log后事物就結束返回成功了。但由於從庫從主庫異步拷貝日志 以及
串行執行 SQL 的特點,所以從庫的數據一定會比主庫慢一些,是有延時的。所以經常出現,剛寫入主庫的數據可能是讀不到的,要過幾十毫秒,甚至幾百毫秒才能
讀取到。這就是主從同步延時問題。
1、如何查看主從延遲時間
通過監控 show slave status
命令輸出的Seconds_Behind_Master參數的值來判斷:
mysql> show slave status\G;
// 狀態一
Seconds_Behind_Master: NULL
// 狀態二
Seconds_Behind_Master: 0
// 狀態三
Seconds_Behind_Master: 79
Seconds_Behind_Master=0: 表示主從復制良好;
Seconds_Behind_Master=NULL: 表示io_thread或是sql_thread有任何一個發生故障;
Seconds_Behind_Master=79: 數字越大表示從庫延遲越嚴重。
2、影響延遲因素
這里整理了影響主從復制延遲大致有以下幾個原因:
1)主節點如果執行一個很大的事務,那么就會對主從延遲產生較大的影響
2)網絡延遲,日志較大,slave數量過多
3)主上多線程寫入,從節點只有單線程同步
4)機器性能問題,從節點是否使用了“爛機器”
5)鎖沖突問題也可能導致從機的SQL線程執行慢
3、優化主從復制延遲
這個沒有說去完全解決,要想解決那么就只能采用同步復制策略。不過,一般不建議使用這種同步模式。顯而易見,如果寫操作必須等待更新同步完成,肯定會
極大地影響性能,除非你不在乎性能。
1)大事務:將大事務分為小事務,分批更新數據
2)減少Slave的數量,不要超過5個,減少單次事務的大小
3)MySQL 5.7之后,可以使用多線程復制,使用MGR復制架構
4)在磁盤、raid卡、調度策略有問題的情況下可能會出現單個IO延遲很高的情況,可用iostat命令查看DB數據盤的IO情況,再進一步判斷
5)針對鎖問題可以通過抓去processlist以及查看information_schema下面和鎖以及事務相關的表來查看
總結
主機與從機之間的物理延遲是無法避免的,既然無法避免就可以考慮嘗試通過緩存等方式,降低新修改數據被立即讀取的概率。
參考
別人罵我胖,我會生氣,因為我心里承認了我胖。別人說我矮,我就會覺得好笑,因為我心里知道我不可能矮。這就是我們為什么會對別人的攻擊生氣。
攻我盾者,乃我內心之矛(32)