主從同步與讀寫分離
阿新 • • 發佈:2019-01-12
一、基本概念
通過主從複製的方式來同步資料,再通過讀寫分離來提升資料庫的併發負載能力
1. 主從同步:
1)主從同步使得資料可以從一個數據庫伺服器複製到其他伺服器上,在複製資料時,一個伺服器充當主伺服器(master),其餘的伺服器充當從伺服器(slave)
2)因為複製是非同步進行的,所以從伺服器不需要一直連線著主伺服器,從伺服器甚至可以通過撥號斷斷續續地連線主伺服器。通過配置檔案,可以指定複製所有的資料庫,某個資料庫,甚至是某個資料庫上的某個表
2. 讀寫分離:
1)讀寫分離就是在主伺服器上修改,資料會同步到從伺服器,從伺服器只能提供讀取資料,不能寫入,實現備份的同時也實現了資料庫效能的優化,以及提升了伺服器安全
二、好處
1. 在業務複雜的系統中,有這麼一個情景,有一句sql語句需要鎖表,導致暫時不能使用讀的服務,那麼就很影響執行中的業務,使用主從複製,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現了鎖表的情景,通過讀從庫也可以保證業務的正常運作
2. 做資料的熱備
3. 架構的擴充套件。業務量越來越大,I/O訪問頻率過高,單機無法滿足,此時做多庫的儲存,降低磁碟I/O訪問的頻率,提高單個機器的I/O效能
4. 通過增加從伺服器來提高資料庫的效能,在主伺服器上執行寫入和更新,在從伺服器上向外提供讀功能,可以動態地調整從伺服器的數量,從而調整整個資料庫的效能
三、主從同步原理
1. 相關元件
主庫:
1)binlog(主庫)
(1)binary log,主庫中儲存更新事件日誌的二進位制檔案 (2)主從複製的基礎是主庫記錄資料庫的所有變更記錄到binlog。binlog是資料庫中儲存配置中過期時間內所有修改資料庫結構或內容的一個檔案。如果過期時間是10d的話,那麼就是最近10d的資料庫修改記錄 (3)mysql主從複製是一個非同步的複製過程,主庫傳送更新事件到從庫,從庫讀取更新記錄,並執行更新記錄,使得從庫的內容與主庫保持一致 (4)在主庫裡,只要有更新事件出現,就會被依次地寫入到binlog裡面,是之後從庫連線到主庫時,從主庫拉取過來進行復制操作的資料來源
2)binlog輸出執行緒(主庫)
(1)每當有從庫連線到主庫的時候,主庫都會建立一個執行緒然後傳送binlog內容到從庫。對於每一個即將傳送給從庫的sql事件,binlog輸出執行緒會將其鎖住。一旦該事件被執行緒讀取完之後,該鎖會被釋放,即使在該事件完全傳送到從庫的時候,該鎖也會被釋放
在從庫裡,當複製開始的時候,從庫就會建立兩個執行緒進行處理:
3)從庫I/O執行緒(從庫)
(1)當START SLAVE語句在從庫開始執行之後,從庫建立一個I/O執行緒,該執行緒連線到主庫並請求主庫傳送binlog裡面的更新記錄到從庫上
(2)從庫I/O執行緒讀取主庫的binlog輸出執行緒傳送的更新並拷貝這些更新到本地檔案,其中包括relay log檔案
4)從庫的SQL執行緒(從庫)
(1)從庫建立一個SQL執行緒,這個執行緒讀取從庫I/O執行緒寫到relay log的更新事件並執行
注:
(1)對於每一個主從複製的連線,都有三個執行緒。擁有多個從庫的主庫為每一個連線到主庫的從庫建立一個binlog輸出執行緒,每一個從庫都有它自己的I/O執行緒和SQL執行緒
(2)從庫通過建立兩個獨立的執行緒,使得在進行復制時,從庫的讀和寫進行了分離。因此,即使負責執行的執行緒執行較慢,負責讀取更新語句的執行緒並不會因此變得緩慢
(3)比如說,如果從庫有一段時間沒運行了,當它在此啟動的時候,儘管它的SQL執行緒執行比較慢,它的I/O執行緒可以快速地從主庫裡讀取所有的binlog內容。這樣一來,即使從庫在SQL執行緒執行完所有讀取到的語句前停止運行了,I/O執行緒也至少完全讀取了所有的內容,並將其安全地備份在從庫本地的relay log,隨時準備在從庫下一次啟動的時候執行語句
2. 流程(非同步的)
1)主庫db的更新事件(update、insert、delete)被寫到binlog
2)從庫發起連線,連線到主庫
3)此時主庫建立一個binlog dump thread,把binlog的內容傳送到從庫
4)從庫啟動之後,建立一個I/O執行緒,讀取主庫傳過來的binlog內容並寫入到relay log
5)還會建立一個SQL執行緒,從relay log裡面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db
四、讀寫分離實現
1. 基於程式程式碼內部實現
1)在程式碼中根據select 、insert進行路由分類,這類方法也是目前生產環境下應用最廣泛的。優點是效能較好,因為程式在程式碼中實現,不需要增加額外的硬體開支,缺點是需要開發人員來實現,運維人員無從下手
2. 基於中間代理層實現
1)代理一般介於應用伺服器和資料庫伺服器之間,代理資料庫伺服器接收到應用伺服器的請求後根據判斷後轉發到後端資料庫
2)常用中介軟體:
(1)mysql_proxy。mysql_proxy是Mysql的一個開源專案,通過其自帶的lua指令碼進行sql判斷
(2)Atlas。是由 Qihoo 360, Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的資料中間層專案。它是在mysql-proxy 0.8.2版本的基礎上,對其進行了優化,增加了一些新的功能特性。360內部使用Atlas執行的mysql業務,每天承載的讀寫請求數達幾十億條。支援事物以及儲存過程
(3)Amoeba。由阿里巴巴集團在職員工陳思儒使用序java語言進行開發,阿里巴巴集團將其使用者生產環境下,但是他並不支援事物以及存數過程
注:經過上述簡單的比較,不是所有的應用都能夠在基於程式程式碼中實現讀寫分離,像一些大型的java應用,如果在程式程式碼中實現讀寫分離對程式碼的改動就較大,所以,像這種應用一般會考慮使用代理層來實現,那麼今天就使用Amoeba為例,完成主從複製和讀寫分離
五、Mysql主從部署與讀寫分離案例(待學習)
參考網址
注:文章是經過參考其他的文章然後自己整理出來的,有可能是小部分參考,也有可能是大部分參考,但絕對不是直接轉載,覺得侵權了我會刪,我只是把這個用於自己的筆記,順便整理下知識的同時,能幫到一部分人。
ps : 有錯誤的還望各位大佬指正,小弟不勝感激