1. 程式人生 > >mysql master 和slave的replication

mysql master 和slave的replication

.主從mysql server的工作原理:(如圖及其過程分析)

過程:
   Mysql的複製(replication)是一個非同步的複製,從一個Mysql instace(稱之為Master)複製到另一個Mysql instance(稱之Slave)。實現整個複製操作主要由三個程序完成的,其中兩個程序在Slave(Sql程序和IO程序),另外一個程序在 Master(IO程序)上。
要實施複製,首先必須開啟Master端的binary log(bin-log)功能,否則無法實現。因為整個複製過程實際上就是Slave從Master端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。

複製的基本過程如下:
(1)Slave上面的IO程序連線上Master,並請求從指定日誌檔案的指定位置(或者從最開始的日誌)之後的日誌內容;
(2)Master接收到來自Slave的IO程序的請求後,通過負責複製的IO程序根據請求資訊讀取制定日誌指定位置之後的日誌資訊,返回給Slave 的IO程序。返回資訊中除了日誌所包含的資訊之外,還包括本次返回的資訊已經到Master端的bin-log檔案的名稱以及bin-log的位置;
(3)Slave的IO程序接收到資訊後,將接收到的日誌內容依次新增到Slave端的relay-log檔案的最末端,並將讀取到的Master端的 bin-log的檔名和位置記錄到master-info檔案中,以便在下一次讀取的時候能夠清楚的高速Master“我需要從某個bin-log的哪個位置開始往後的日誌內容,請發給我”;

(4)Slave的Sql程序檢測到relay-log中新增加了內容後,會馬上解析relay-log的內容成為在Master端真實執行時候的那些可執行的內容,並在自身執行。

############################################

Replication的思想是將資料在叢集的多個節點同步、備份,以提高叢集資料的可用性(HA);Mysql使用Replication架構來實現上述目的,同時可以提升了叢集整體的併發能力。5.6版本作為一個里程碑,對replication做了不少的優化調整,提高了叢集資料的一致性、同步的效能以及資料自動恢復(recovery)的能力。(本文內容基於MySQL 5.6+,不過在5.7+版本仍有部分調整)

    Replication架構通常由一個master和一個或者多個slaves構成,master接收應用的writes操作(事務中的read、write操作均有master處理),slaves接收read操作。在master上發生的資料變更,都將會複製給slaves,從直觀而言,replication架構解決了:1)資料多點備份,提高資料可用性 2)讀寫分流,提高叢集的併發能力。(並非是負載均衡)3)讓一些非實時的資料操作,轉移到slaves上進行。

    下文中提到的“變更操作”為“insert”、“update”、“delete”等,與MySQL中的“update events”、“事務操作”、“writes”同義。

    Replication具有如下優點:

    1)擴充套件:將負載分佈在多個slaves上以提高效能,所有的writes以及事務中的read操作都將有master處理,其他reads將轉發給slaves;對於“讀寫比”較高的應用,replication可以通過增加slaves節點來提高併發能力;因為write只能在master上提交,因此架構擴充套件對提升write併發能力並不明顯,對於writes密集性應用我們應該考慮其他架構。

    2)資料安全:slave可以中斷自己的replication程序,這不會打斷master上的資料請求,所以可以在slave上執行backup服務,定期全量backup是保護資料的手段之一。(如果在master上執行backup,需要讓master處於readonly狀態,這也意味這所有的write請求需要阻塞)。

    3)分析:資料在master上建立,那麼資料分析可以在slave上進行,這將不會影響master的效能。利用mysql做資料分析(或者資料分析平臺的源資料),通常都是將某個slave作為資料輸入端。

    4)遠距資料分佈:如果master的物理位置較遠,你可以在臨近需求的地方部署slaves,以便就近使用資料,而不需要總是訪問遠端的master,這在資料分析、資料備份與容災等方面有很大幫助。

    MySQL架構的演變分多個階段,目前基於replication架構模式的更高階架構設計有“MySQL Fabric”和“MySQL Cluster”。本文主要講解基本的replication模式,如下為replication與Fabirc、Cluster的區別,以便我們做技術選型:

    1、MySQL Fabirc

    Farbic由replication基礎特性和一些擴充套件框架構建而成,用於管理MySQL Servers Farms,與基本的replicaiton相比,它實現了2個核心的特性:HA和sharding。Fabric叢集中任何時候只有一個Primary(即master),其他的例項為Secondaries(即slaves);通過使用replication,將資料在多個節點上備份,HA總是保持叢集的資料可用性。如下特性是replication所不具備的:

    1)故障檢測和角色遷移(Failover):Fabric程序用於監控叢集中的所有節點,如果發現primary失效,稍後他將從Secondaries中選擇一個“資料最新”的節點,並提升為primary;此後其他的secondaries將從新的priamry上同步資料變更操作。Connectors(比如Connector/J客戶端)發現primary故障時也會通知Fabirc,那麼Fabric將通知資訊作為決策的一部分來判定priamry的狀態。這個特性簡稱為“自動Failover”,是replication架構中必備的手段之一。

    2)資料庫請求路由(Router):當Fabric提升一個新的primary後,它將會更新state store(儲存replication的節點狀態等),此後Connectors將會獲取新的state資料並在客戶端本地cache。因此,application不需要時刻關注(aware)叢集中servers拓撲結構的變化,只需要根據state cache中的server狀態,將writes傳送給相應的primary即可。這種特性有Connectors客戶端與與Fabric共同實現,在普通的replication架構中,客戶端自動角色路由是無法完成的。如果cache中拓撲不是最新的,application的操作異常將會反饋給Fabirc,參考1)。

    Fabirc支援sharding,對較大規模的資料可以非常便捷的在叢集中分佈而無需太多人工干預,我們可以簡單的認為Fabric是replication模式的完善,支援自動Failover。對於網際網路應用,Fabric架構簡單而且有效,是首選方案。

    2、MySQL Cluster

    相對於Fabirc,MySQL Cluster支援更大規模的資料,其架構模式和原理也更加複雜。Cluster是一個易於擴充套件、實時的、ACID相容的事務性資料庫,支援“全分散式”、“多Master”架構,無單點問題;MySQL Cluster可以部署在普通的商業機器上,多節點水平擴充套件、Server間資料自動sharding和負載均衡,用於服務read、write都密集的應用,可以使用SQL和NOSQL介面訪問資料。Cluster的架構思想與Hadoop非常類似,它設計的前提是“認為每個Node都是易於出錯的”、叢集規模巨大、多租戶,所以它提供了資料備份機制、自動遷移、自動Failover等特性,來保證可用性、健壯性。

    MySQL Cluster使用了一個外掛式的儲存引擎,與MySQL 儲存引擎(InnoDB、MySAM)架構有很大不同,我們在此不做詳細介紹,只需要知道它的核心特性為:資料集並不是儲存某個特定的MySQL例項上,而是被分佈在多個Data Nodes中,即一個table的資料可能被分散在多個物理節點上,任何資料都會在多個Data Nodes上冗餘備份。任何一個數據變更操作,都將在一組Data Nodes上同步(嚴格意義上的同步,synchronous,二階段提交?)以保證資料的一致性。

    由此可見,Replication架構簡單、易於管理;Fabric是Replicaiton模式的完善和補充,增加了自動Failover和sharding機制,以支撐更大規模的資料訪問,減少人工干預;Cluster是一個全分散式架構,是面向大規模資料儲存的解決方案。

一、基礎

    Replication模式的主要目的是將master上的資料變更復制到一個或者多個slaves上,多個節點備份以提高資料的可用性,避免單點問題;如果只有一個mysql節點,那麼當此節點的宿主機器損壞,將可能導致資料永久性丟失。Replication與Connector配合,可以實現讀寫分流的功能,從而提升叢集整體的併發能力。

    根據實際需要,我們可以指定某個(些)Databases或者tables參與replication,不過replication的表現態仍然是叢集中所有的例項上資料集一樣,這與Farbic、Cluster不同,在Cluster中不同的Data Nodes上資料集或許完全不同。

    Repliction模式中,在master上發生的資料變更都將被立即寫入binlog,此後它們被slaves讀取到本地,並應用這些資料變更操作,從而實現資料“replication”。slaves的資料同步只會消耗較少的master資源(每個slave或許有1%的額外開支),通常一個master組合幾個slaves(3~5個)是比較常見的,而不會有數十個slaves,否則你應該考慮Cluster架構。



 

二、複製模式(Replication models)

    replication支援兩種模式:asynchronous(非同步)、semi-synchronous(半同步);“synchronous”複製只有Cluster才支援,本文不做介紹。複製模式會對資料完整性有很大影響。

    1、Asynchronous複製

    這是replication的預設模式,在master上提交的updates操作執行成功且寫入binlog之後,master繼續處理其他的write請求,而不會等待slaves對此update資訊的複製或者應用;此後的任何時候,slaves均可以與master建立連結並複製那些尚未獲取的變更日誌,然後在本地應用(apply)。

    非同步模式,無法保證當master失效後所有的updates已經複製到了slaves上,只有重啟master才能繼續恢復這些資料,如果master因為宿主機器物理損壞而無法修復,那些尚未複製到slaves上的updates將永久性丟失;因此非同步方式存在一定的資料丟失的風險,但它的優點就是master支援的write併發能力較強,因為master上的writes操作與slaves的複製是互為獨立的。

    不過這種模式,slaves總有一定的延後,這種延後在事務操作密集的應用中更加明顯,不過通常這種延後時間都極其短暫的。從另一個方面來說,非同步方式不要求slaves必須時刻與master建立連結,可能slaves離線、中斷了replication程序或者連結的傳輸延遲很高,這都不會影響master對writes請求的處理效率。比如對於“遠距分佈”的slaves,非同步複製是比較好的選擇

    此模式下,如果master失效,我們通常的做法是重啟master,而不是failover到其他的slave,除非master無法恢復;因為master上會有些updates尚未複製給slaves,如果此時failover則意味著那些updates將丟失。

    2、Semi-synchronous

    “半同步”並不是MySQL內建的replication模式,而且由外掛實現,即在使用此特性之前,需要在master和slaves上安裝外掛,且通過配置檔案開啟“半同步”。當slave與master建立連線時會表明其是否開啟了“半同步”特性;此模式正常運作,需要master和至少一個slaves同時開啟,否則仍將採用“非同步”複製

    在master上執行事務提交的執行緒,在事務提交後將會阻塞,直到至少一個“半同步”的slave返回確認訊息(ACK)或者所有的半同步slave都等待超時;slave將接收到事務的資訊寫入到本地的relay log檔案且flush到磁碟後,才會向master返回確認訊息,需要注意slave並不需要此時就執行事務提交,此過程可以稍後進行。當所有的半同步slaves均在指定的時間內沒有返回確認訊息,即timeout,那麼此後master將轉換成非同步複製模式,直到至少一個半同步slave完全跟進才會轉換為半同步模式。在master阻塞結束後才會返回給客戶端執行的狀態,此期間不會處理其他的事務提交,當write請求返回時即表明此操作在master上提交成功,且在至少一個半同步slaves也複製成功或者超時,阻塞超時並不會導致事務的rollback。(對於事務性的表,比如innodb,預設是事務自動提交,當然可以關閉“autocommit”而手動提交事務,它們在replication複製機制中並沒有區別)

    半同步模式需要在master和slaves上同時開啟,如果僅在master上開啟,或者master開啟而slaves關閉,最終仍然不能使用半同步複製,而是採用非同步複製。

    與非同步複製相比,半同步提高了資料一致性,降低了資料丟失的風險。但是它也引入了一個問題,就是master阻塞等待slaves的確認資訊,在一定程度上降低了master的writes併發能力,特別是當slaves與master之間網路延遲較大時;因此我們斷定,半同步slaves應該部署在與master臨近的網路中,為了提高資料一致性,我們有必要將半同步作為replication的首選模式。

    在實際的部署環境中,並不要求所有的slaves都開啟半同步,我們可以將與master臨近的slaves開啟半同步,將那些“遠距分佈”的slaves使用非同步。

三、日誌格式(Replication Formats)

    Replication之所以能夠工作,主要還是歸結於binlog(binary log),所以在replication模式下必須開啟binlog功能;slave從masters上增量獲取binlog資訊,並在本地應用日誌中的變更操作(即“重放”)。變更操作將根據選定的格式型別寫入binlog檔案,目前支援三種format:

    1、statement-based replication(SBR):master將SQL statements語句寫入binlog,slave也將statements複製到本地執行;簡單而言,就是在master上執行的SQL變更語句,也同樣在slaves上執行。SBR模式是MySQL最早支援的型別,也是replication預設型別。如論何種情況,DDL語句一定是SBR格式。

    2、row-based replication(RBR): master將每行資料的變更資訊寫入binlog,每條binlog資訊表示一行(row)資料的變更內容,對於slaves而言將會複製binlog資訊,然後單條或者批量執行變更操作。

    3、mix-format replication:混合模式,在這種模式下,master將根據根據儲存引擎、變更操作型別等,從SBR、RBR中來選擇更合適的日誌格式,預設為SBR;具體選擇那種格式,這取決於變更操作發生的儲存引擎、statement的型別以及特徵,優先選擇“資料一致性”最好的方式(RBR),然後才兼顧效能,比如statement中含有“不確定性”方法或者批量變更,那麼將選擇RBR方式,其他的將選擇SBR以減少binlog的大小。我們建議使用mix方式。

    SBR和RBR都有各自的優缺點,對於大部分用而言,mix方式在兼顧資料完整性和效能方面是最佳的選擇。

    SBR的優點:因為binlog中只寫入了變更操作的statements,所以日誌量將會很小;當使用SQL語句批量更新、刪除資料時,只需要在binlog中記錄statement即可,可以大大減少log檔案對磁碟的使用。當然這也意味著slave複製資訊量也更少,以及通過binlog恢復資料更加快速。

    SBR的缺點:有些變更操作使用SBR方式會帶來資料不一致的問題,一些結果具有不確定性的操作使用SBR將會引入資料不一致的問題。

    1)statement中使用了UDF,UDF的計算結果可能依賴於SQL執行的時機和系統變數,這可能在slave上執行的結果與master不同,此外如果使用了trigger,也會帶來同樣的問題。(User Defination Fuction)

    2)對於批量delete或者update操作中,使用了limit限定詞,但是沒有使用“order by”,這樣的SQL語句執行的結果是不確定的,無論是在master還是slaves,即使在同一個節點上不同時機執行結果都有可能不一樣,replication同理,這歸因於MySQL資料儲存的機制。(預設排序將採用底層資料檔案的實際儲存順序,innodb為primary key順序)

    3)statement中使用瞭如下函式的(舉例):UUID(),SYSDATE(),RAND()等,不過NOW()函式可以正確的被replication(但在UDF或者觸發器中則不行);這些函式的特點就是它們的值依賴於本地系統,RAND()本身就是隨機所以值是不確定的。如果statement中使用了上述函式,那麼將會在日誌中輸出warning資訊。【不確定性函式

    4)對於“INSERT ... SELECT”語句,SBR將比RBR需要更多的行鎖。如果UPDATE語句中沒有使用索引而導致全表掃描的話,SBR將比RBR需要更多的行鎖。(主要是為了保障資料一致性,需要同時鎖定受影響的所有的行,而RBR則不必要)

    5)對於InnoDB,使用“AUTO_INCREMENT”的insert語句,將會阻塞其他“非衝突”的INSERT。(因為AUTO_INCREMENT,為了避免併發導致的資料一致性問題,只能序列,但RBR則不需要)。

    6)對於複雜的SQL語句,在slaves上仍然需要評估(解析)然後才能執行,而對於RBR,SQL語句只需要直接更新相應的行資料即可。

    7)在slave上評估、執行SQL時可能會發生錯誤,這種錯誤會隨著時間的推移而不斷累加,資料一致性的問題或許會不斷增加。

    RBR的優點:

    1)所有的變更操作,都可以被正確的replication,這事最安全的方式。

    2)對於“INSERT ... SELECT”、包含“AUTO_INCREMENT”的inserts、沒有使用索引的UPDATE/DELETE,相對於SBR將需要更少的行鎖。(意味著併發能力更強)

    RBR的缺點:

    1)最大的缺點,就是RBR需要更多的日誌量。任何資料變更操作都將被寫入log,受影響的每行都要寫入日誌,日誌包含此行所有列的值(即使沒有值變更的列);因此RBR的日誌條數和尺寸都將會遠大於SBR,特別是在批量的UPDATE/DELETE時,可能會產生巨大的log量,反而對效能帶來影響,儘管這確實保障了資料一致性,確導致replication的效率較低。

    2)對於MyISAN儲存引擎,INSERT語句將會阻塞更長的時間,因為在RBR模式下,MyISAM表不支援併發插入。

    3)儘管是RBR模式,但是如果slave在更新非事務性表時,server被關閉,將會導致資料不一致性問題;所以在後續的版本中,我們希望master、slaves所有的表均使用InnoDB這樣的事務性儲存引擎,事務的有序性可以保證slave在crash之後啟動,資料恢復時仍能夠保證資料一致性。

    由此可見,SBR和RBR各有優缺點,這是個需要權衡的事情,本人認為資料一致性是資料庫的首要考慮的因素,replication效能次之,因此在新的版本中,我們建議使用RBR方式或者mixed,通常mixed是官方推薦的。

四、GTID

    GTID全名“Global Transaction Identifiers”,全域性事務性ID,每個事務都用一個ID標識,用於跟蹤master和slavers上事務提交的“進度”;這也意味著在Failover時,slaves可以不需要向新的master傳遞自己已經執行的log的positions(binglog的offset),只需要告知新的master自己已經執行的最後一條事務的ID即可,這極大的簡化了failover、日誌replication的複雜度。因為GTID完全基於事務,可以非常簡單的判定master與slaves是否一致,只要slaves與master上的事務提交均按照相同的順序提交,資料一致性是可以得到保證的,為了更加安全,我們建議使用RBR模式 + GTID。

   每個GTID是全域性唯一的,由master在建立事務時生成並與事務過程一併寫入binlog,slaves只對GTID讀取而不修改。GTID由“source_id:trasaction_id”組合而成(中間有“:”分割),其中source_id為源server的UUID(建立事務的master的UUID),transaction_id就是事務ID,是一個序列數字表示事務的順序(long型),每個事務都有不同的transaction_id;這種組合決定GTID的全域性一致性,同時我們也可以根據GTID來判定事務在哪個server上建立的。一個GTID的事務執行後,在此後遇到相同GTID的事務將會被忽略,在master上提交的事務,可以在slaves上多次重複執行(有序執行),這對資料恢復和保證資料一致性非常有幫助。

    在沒有GTID時,slave需要告知master,其已經複製的binlog檔案的offset;當使用GTID時,那麼GTID就想binlog的主鍵索引一樣,slave只需要交付GTID即可繼續進行replication,在使用“CHANGE MASTER TO”命令做failover時也不要指定“MASTER_LOG_FILE”/“MASTER_LOG_POS”選項,而是直接在命令中使用“MASTER_AUTO_POSITION”選項即可,這對運維操作非常便捷。(稍後參看運維部分)

    1)事務在master上執行並提交,並將此事務操作寫入binlog。

    2)master將binlog增量傳送給slaves,slaves將其內容儲存在relay log中(同binlog,主要用於replication)。

    3)slaves從relay log中讀取尚未執行的GTID,並將其值設為“gtid_next”;slave檢測並確保此GTID沒有被執行過,同時也確保沒有其他的執行緒也在讀取和操作此GTID(多執行緒replication時),然後再本地執行此transaction並將事務寫入本地的binlog中。

    基於GTID的repliction,有些特性將不能很好的支援。比如,在一個事務中更新了非事務性表(MyISAM)和事務性表(InnoDB),這將破壞事務的嚴格性,因為這種“混合更新”的事務在整個過程將會在binlog中產生多個GTIDs記錄,對slaves複製將會帶來影響,因此replication中在開啟GTID時將不支援“混合更新”。(稍後詳解“事務與replication”

 

 

    比如上圖架構圖,當master失效後,我們需要將其中一個slave提升為master,預設採用“非同步複製”方式,因此B和C或許都沒有完全複製master上的事務,而且有可能B和C的複製進度有一些差異。我們假定,B比C更加超前,所以,B將被提升為master,此後C需要與B建立從屬關係,並從B中複製、執行那些尚未接收到的事務(由GTID判定);當然B也需要從C中複製那些自己缺失的GTIDs,當B和C資料對齊之後,B正式提升為Master。

    在新的replication協議中,當slave與master建立連結後,它將會發送自己已經執行和提交的事務GTIDs的範圍(gtid_executed),master將會向slave響應slaves缺失的事務列表;如上例所示,C向B傳送id1,那麼B向C響應id2、id3。

五、實現原理

    在上述介紹中我們已經基本瞭解了replication的原理:每個slaves與master建立連結,並從master“拉取”(pull)binlog副本並儲存在本地(relay log),不是master主動push給slaves;slaves從本地log檔案中讀取變更操作並執行。每個slave都是互相獨立的,各自的replication過程互不干擾,當然每個slave可以根據需要啟動或者暫停replication程序,而不會影響master與其他slaves的複製。



 

    replication功能有三個執行緒實現,其中一個在master上,另外2個在slaves上。

    1、Binlog dump執行緒:master上建立一個執行緒用於向slave傳送binlog內容,我們可以通過“SHOW PROCESSLIST”指令檢視到一個名為“Binlog Dump”的執行緒。dump執行緒會對binlog檔案獲取一個讀鎖,並讀取內容傳送給slave,只要一個變更操作讀取完畢後,鎖即釋放,即使內容尚未傳送給slave。

    2、Slave I/O執行緒:當在slave上執行“START SLAVE”後,將會建立一個I/O執行緒,它負責與master建立連結並請求需要的binlog,並儲存在本地的relay log中。在slave上執行“SHOW SLAVE STATUS”可以檢視“Slave_IO_running”的狀態。

    3、Slave SQL執行緒:slave上執行“START SLAVE”時將會建立一個SQL執行緒用於從relay log中讀取變更操作,解析、評估並執行,就像變更操作(事務)在本機提交一樣,執行後將變更操作寫入自己的binlog日誌(可選,建議開啟)。

    master為每個slave建立一個單獨的Binlog dump執行緒,並同時與它們互動,每個slave持有各自的IO和SQL執行緒。slave使用2個單獨的執行緒來完成replication過程,以便它們互相影響,比如IO執行緒不會因為SQL執行緒執行較慢而拖累與master的讀取速率,當slave停止了一段時間後重啟,那麼IO執行緒仍然可以快速的與master跟進,即使SQL執行緒已經落後太多;這種執行緒分離,最大的收益就是提高了slave複製的效率,避免slave與master差距太大,從而保證了資料安全。

    我們可以通過“SHOW PROCESSLIST”來檢視上述執行緒的執行狀態。也可以使用“SHOW SLAVE STATUS”、“SHOW MASTER STATUS”來檢視與replication有關的更多狀態資訊。

    在replication期間,master只需要建立與更新binlog檔案即可,不過對於slave,為了複製和failover需要建立多種檔案。

    1、relay log:我們在上文中已經提到,slave IO執行緒從master讀取的binlog資料首先儲存在本地的relay log中;此後SQL執行緒即可從relay log中讀取變更操作並在本地應用。嚴格意義上說,relay log的內容應該與master binlog逐位元組一致的(byte-to-byte)。

    2、master info:master-info log檔案儲存了slave與當前master建立連結的一些配置資訊和連結狀態,日誌中包括:master的host名稱、login認證資訊,以及slave讀取master binlog的位置資訊。在5.6之前,資訊儲存在master.info檔案中,5.6之後,可以通過“--master-info-repository=TABLE”啟動引數(或者配置檔案)將資訊儲存在“mysql.slave_master_info”系統表中。

    3、relay log info:用於記錄relay log執行點的狀態資訊,在5.6之前預設寫入relay-log.info檔案,5.6之後可以通過“--relay-log-info-repository=TABLE”將資訊寫入“mysql.slave_relay_log_info”系統表中。

    為了避免crash對資料帶來的不一致問題,強烈建議將master-info、relay-log-info採用事務性表,而且建議開啟“--relay-log-recovery”。不過很遺憾的是,在5.6.5之前的版本中,slave_master_info、slave_relay_log_info表預設為MyISAM,需要手動修改為InnoDB。

    4、binlog:這個大家都很熟悉,slave上也可以開啟binlog功能,比如slave是其他slave的master時。

    relay log內容格式與binlog一樣,也可以使用mysqlbinlog shell檢視。 relay log也是有多個檔案組成,和binlog非常相似,檔名稱格式類似於“host_name-relay-bin.<number>”,此外還有一個index檔案用來記錄那些relay log檔案還在使用中,不能被刪除(對於master而言,binlog也是如此)。SQL執行緒執行完一個relay log中的變更操作後,將會自動刪除此檔案,因為它不再需要。關於relay log、master info檔案的內容請參看連結

六、架構拓撲

    根據replication的機制,它可以有多種架構拓撲結構,如圖所示:


    1、Master-slave、Master-slaves:這是目前最常見的架構模式,一個master與一個或者多個slaves組合,實施簡單而且有效,是首選方式之一,不僅實現了HA,而且還能讀寫分離,進而提升叢集的併發能力。

    2、Master-slave-slaves:多級複製模式, 部分slave不與master跟進,而是與其他slave跟進,這在某些特殊場景下非常有效!我們知道如果master有太多的slave跟進,master將會損耗一部分效能用於replication,在上文中已經知道“半同步”的特性,那麼我們可以讓3~5個slaves與master跟進,並使用“半同步”複製模式,其他的slaves作為二級,與其他slave(s)跟進,採用“非同步”複製模式,這樣不僅緩解了master的壓力,而且對資料一致性並沒有負面影響;而且二級slaves可以作為“離線資料統計”、“遠距資料中心”等特殊使用場景,因為它們對資料的實時性要求不要。

    3、Master-Master:這種模式不建議採用,對於多點寫入的架構模式(write操作密集型),建議採用MySQL Cluster!這種方式總是會引入“鎖併發”、“資料不一致”等問題,僅供參考!(3M架構)

七、優化調整

    1、多執行緒

    在slave上使用多執行緒方式進行replication過程,可以有效提高效率。

 

     slave將多個執行緒根據database分割,其中一個執行緒為“coordinator”(協調器),從relay log中讀取變更操作,然後將不同database的操作傳送給不同的worker執行緒,並由worker執行緒負責執行;可以通過“slave-parallel-workers”引數指定worker執行緒的個數。預設情況下slave只有一個執行緒,即SQL執行緒,此執行緒負責讀取relay log並執行變更操作,那麼在多執行緒模式下,一個執行緒專門負責讀取relay log,並將讀取的變更操作根據database分發給不同的worker執行緒,那麼多個database中的變更操作將可以並行的執行,這將極大的提高了replication的效率。不過這也會引入一些問題,比如事務的順序可能會與master不同,我們稍後在“【配置引數】”部分介紹。

    2、binlog批量提交(Group commit)

    binlog資料最終要寫入磁碟,磁碟寫入的頻率越高,效能也就越低(磁碟IO效率低);我們可以開啟binlog批量提交,而不是每個變更操作都立即寫入binlog,這樣可以有效的提高磁碟IO的效能。“sync_binlog”引數來控制磁碟寫入的頻率,預設為0,即有作業系統決定binlog檔案flush的時機,“1”表示每個變更操作寫入binlog後都立即flush磁碟,其他值表示多個變更操作後才flush磁碟。

    3、RBR優化

    前文已經提到,基於RBR複製時,master將會把變更操作影響的行的所有列的值都寫入binlog,這確實提高了資料的安全性,但是卻增加了binlog的日誌量,也增加了master與slave之間的網路傳輸量。我們可以通過“binlog-row-image”引數來控制binlog輸出:

    1)full:行的所有列,變更前和變更後的值都會輸出到binlog中,這種方式便於資料跟蹤、排錯,但是最大的問題就是日誌量太大;預設值。

    2)minimal:只記錄資料變更的列以及能夠標定此row的列(比如主鍵列);此選項通常比較合適,日誌量較少,而且實用。

    3)noblob:記錄所有的列(包括未變更的列),但是不包括blob和text型別的沒有變更的列;簡而言之,就是沒有變更的大欄位不會寫入binlog,其他欄位無論是否變更均會寫入,具有“full”和“minimal”的優點。

參考:

1、binlog:

    http://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html

    http://dev.mysql.com/doc/refman/5.7/en/binary-log.html

2、replication實現:

    http://dev.mysql.com/doc/refman/5.6/en/replication-implementation.html

3、複製模式:

    http://dev.mysql.com/doc/refman/5.6/en/replication-formats.html

4、GTIDs:

    http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html

5、半同步複製:

    http://dev.mysql.com/doc/refman/5.6/en/replication-semisync.html