和“兄弟”們一起“庫”!---UP楠哥

#說在前面
PAAS領(lǐng)域中有一個重要的部分,那就是數(shù)據(jù)庫,無論是關(guān)系型(如Oracle)還是非關(guān)系型(如HBase),無論是行式數(shù)據(jù)庫(如SqlServer)還是列式數(shù)據(jù)庫(如ClickHouse),我們在生產(chǎn)環(huán)境中是不忍心讓這些"數(shù)據(jù)庫爺爺"們孤獨的自運行,一定會給它(們)至少找一個"兄弟",一起為業(yè)務(wù)系統(tǒng)提供數(shù)據(jù)交互的承載平臺;So,Oracle的RAC、SqlSever的AlwaysOn、Mysql(Mariadb)的主從復(fù)制等等類似這樣的集群、讀寫分離機制,都是給數(shù)據(jù)庫安排"葫蘆娃"式的兄弟合力共創(chuàng)所提供的解決方案。UP楠哥深知這部分的內(nèi)容在PAAS領(lǐng)域中占據(jù)非常重要的位置,在未來的篇章中給那些已經(jīng)在IAAS領(lǐng)域的知識體系已有深刻理解同時還想在PAAS中深挖的童鞋們做一些參考,一起來看關(guān)于數(shù)據(jù)庫集群方案中的實現(xiàn)要點和效果驗證;今天我們先從Mysql(Mariadb)的主從復(fù)制開始聊起。Let's go!
?
#Mysql(Mariadb)的主從復(fù)制原理概述
Mysql(Mariadb)主從同步是基于從庫對主庫Binlog文件的增量實現(xiàn),復(fù)制的工作主要是由主庫上Master dump線程、從庫上的Slave IO線程以及SlaveSQL線程完成。
當(dāng)在從庫上執(zhí)行START SLAVE?語句來開啟復(fù)制功能時,會產(chǎn)生一個SlaveIO線程和一個slave SQL線程。slave IO線程負責(zé)連接到主庫,然后接收主庫master dump線程發(fā)送過來的Binlog內(nèi)容,寫到本地的Relay-log中。slave SQL線程負責(zé)重放relay-log中的內(nèi)容,將主庫的所有修改反映到從庫上。
復(fù)制的大概過程可以總結(jié)為如下3步:
(1)主庫將所有的修改以事件的形式記錄到binlog中,主庫的Master Dump線程負責(zé)發(fā)送Binlog內(nèi)容到從庫;
(2)從庫的SlaveIO線程將接收到的Binlog事件記錄到從庫本地的Relay-log中;
(3)從庫的SlaveSQL線程重放Relay-log中的事件。
?
#Mysql(Mariadb)的主從復(fù)制集群模式
Mysql(Mariadb)主從復(fù)制架構(gòu)有一主多從復(fù)制架構(gòu)、多級復(fù)制架構(gòu)等,當(dāng)然,還有什么雙主(Dual Master)復(fù)制架構(gòu)等。
##一主多從復(fù)制架構(gòu)
在Mariadb-Master庫讀取請求壓力很大的情況下,通過配置一主多從復(fù)制架構(gòu)實現(xiàn)讀寫分離,把對實時性要求不高讀方面的數(shù)據(jù)請求分攤到多個Mariadb-Slave庫上,與此同時,可以使用類似LoadBalancer負載機制,從而降低Mariadb-Master庫的讀壓力。另外,在Mariadb-Master庫出現(xiàn)異常宕機的情況下,可以把一個Mariadb-Slave庫切換為Mariadb-Master庫繼續(xù)提供服務(wù)。邏輯圖如下:

##多級復(fù)制架構(gòu)
既然有了一主多從復(fù)制架構(gòu),為何還要再有多級復(fù)制架構(gòu)呢?一直多從復(fù)制架構(gòu)看似解決了很多問題,但其實還有些許瑕疵的。
相比較對比一主多從的架構(gòu),多級復(fù)制架構(gòu)只是在一主多從的架構(gòu)基礎(chǔ)之上主庫增加了一個Mariadb-Master2的角色,這樣的話,Mariadb-Master1只給Mariadb-Master2發(fā)送Binlog日志就可以,從而減輕了Mariadb-Master1的壓力;此時,Mariadb-Master1再發(fā)送Binlog日志給Mariadb-Slave所有從庫節(jié)點。具體如下:

既然又多了一層,延遲的問題也會如期而至,一定會比一主多從復(fù)制架構(gòu)產(chǎn)生的延遲問題更多。別擔(dān)心,有一個被稱作“BLACKHOLE“的引擎,可以在Mariadb-Master2上選擇表引擎為BLACKHOLE來降低多級復(fù)制的延遲。寫入BLACKHOLE表的數(shù)據(jù)并不會落到磁盤上,BLACKHOLE表永遠都是”空“表,諸如INSERT、UPDATE、DELETE等DML語句操作僅僅在BINLOG中記錄事件。
?
##雙主復(fù)制架構(gòu)
在雙主復(fù)制架構(gòu)中,Mariadb-Master1和Mariadb-Master2互為主從,Client的讀&寫操作請求都訪問主庫Mariadb-Master1或Mariadb-Master2。通過雙主復(fù)制架構(gòu)可以減輕一主多從架構(gòu)下Mariadb-Master1庫進行維護帶來的額外搭建Mariadb-Slave庫的工作。

#Binlog格式
這個時候,我們就要看下Binlog包含了哪些格式,具體如下:
(1)Statement:記錄每一條更改數(shù)據(jù)的sql優(yōu)點:binlog文件較小,節(jié)約I/O,性能較高。缺點:不是所有的數(shù)據(jù)更改都會寫入binlog文件中,尤其是使用MySQL中的一些特殊函數(shù)(如LOAD_FILE()、UUID()等)和一些不確定的語句操作,從而導(dǎo)致主從數(shù)據(jù)無法復(fù)制的問題。
(2)Row:不記錄sql,只記錄每行數(shù)據(jù)的更改細節(jié)優(yōu)點:詳細的記錄了每一行數(shù)據(jù)的更改細節(jié),這也意味著不會由于使用一些特殊函數(shù)或其他情況導(dǎo)致不能復(fù)制的問題。缺點:由于row格式記錄了每一行數(shù)據(jù)的更改細節(jié),會產(chǎn)生大量的binlog日志內(nèi)容,性能不佳,并且會增大主從同步延遲出現(xiàn)的幾率。
(3)Mixed:一般的語句修改使用statment格式保存binlog,如一些函數(shù),statement無法完成主從復(fù)制的操作,則采用row格式保存binlog,MySQL會根據(jù)執(zhí)行的每一條具體的sql語句來區(qū)分對待記錄的日志形式,也就是在Statement和Row之間選擇一種。
鑒于以上三種格式,我們到底怎么選才合適呢,UP楠哥通過生產(chǎn)環(huán)境實踐,建議大家選擇Mixed這種格式是最合適的Binlog-format。接下來,我們看,UP楠哥找來了Linux 7.x版本和Linux8.x版本所自帶的mariadb軟件包安裝后所默認的Binlog格式。

第一張圖是來自于Linux7.x自帶的mariadb版本為5.5.56版本儼然有些老氣^-^當(dāng)然這不是重點,重點是紅框框內(nèi)的STATEMENT,表示默認情況下的Binlog_format。

第二張圖是來自于Linux8.x自帶的mariadb版本為10.3.17,紅框框內(nèi)的MIXED,表示較新版本的mariadb默認情況下的Binlog_format。
?
#更改binlog-format
剛才UP楠哥也有提到過,通過生產(chǎn)環(huán)境實踐,建議大家選擇Mixed這種格式是最合適的Binlog-format。我們來看下如何更改,具體如下:

更改完成后,執(zhí)行systemctl restart mariadb,再進行查看會發(fā)現(xiàn)格式變成了Mixed。

#Binlog的復(fù)制模式
最后再來嘮一嘮Binlog的復(fù)制模式,具體如下:
ü?異步復(fù)制(Asynchronous replication)
ü?全同步復(fù)制(Fully synchronous replication)
ü?半同步復(fù)制(Semisynchronous replication)
ü?MGR 組復(fù)制(MySQL Group Replication,簡稱MGR是半同步復(fù)制改進版本)在mysql5.7之后的版本能夠?qū)崿F(xiàn)無損復(fù)制。
?
#主從復(fù)制實現(xiàn)的效果
通過主從復(fù)制機制所實現(xiàn)的效果,具體如下:
通過sql語句在Mariadb-Master庫創(chuàng)建一個測試數(shù)據(jù)庫,創(chuàng)建后到Mariadb-Slave庫執(zhí)行show databases;會看到有同樣的數(shù)據(jù)庫名稱存在。


此時看到這里,大家就知道效果了,當(dāng)然也可以做一些表的創(chuàng)建和數(shù)據(jù)的插入去驗證同步復(fù)制的效果,具體詳細的我就不再給大家做過多演示。詳細的實現(xiàn)步驟,大家可以關(guān)注下UP楠哥后期的Online公開課,UP楠哥會在公開課演示實戰(zhàn)步驟,后續(xù)也會放到實戰(zhàn)部分的潮流小文中供大家參考使用!