MySQL的複製架構就是以一臺服務器充當主服務器,而一臺或多臺其它服務器充當從服務器。從服務器基於主服務器的二進制日誌跟蹤全部對數據庫的更改操做,以而在從服務器上的數據拷貝執行相同的更改操做。使用MySQL複製架構能夠經過在主服務器和從服務器之間分離客戶處理負荷,從而獲得更好的客戶響應時間。使用複製的另外一個好處是可使用一個從服務器執行備份,而不會干擾主服務器。於是,MySQL複製架構主要應用於:分佈數據、負載平衡(load balancing)、備份或其餘高可用性(high availability)和容錯的架構中。html
大致上,複製有3個步驟:mysql
1.主服務器把數據更改記錄到二進制日誌中(二進制日誌事件Binary Log Events)sql
2.從服務器把主服務器的二進制日誌事件拷貝到本身的中繼日誌(Relay Log)中。shell
3.從服務器重放中繼日誌中的事件,把更改應用到本身的數據上。數據庫
該過程的第一部分就是主服務器記錄二進制日誌。在每一個事務更新數據完成以前,主服務器在二日誌記錄這些改變。MySQL將事務串行的寫入二進制日誌,即便事務中的語句都是交叉執行的。在事件寫入二進制日誌完成後,主服務器通知存儲引擎提交事務。後端
下一步就是從服務器將主服務器的binary log拷貝到它本身的中繼日誌。首先,從服務器開始一個工做線程——I/O線程。I/O線程在主服務器上打開一個普通的鏈接,而後開始binlog dump process。Binlog dump process從主服務器的二進制日誌中讀取事件,若是已經跟上主服務器,它會睡眠並等待主服務器產生新的事件。I/O線程將這些事件寫入中繼日誌。緩存
SQL slave thread處理該過程的最後一步。SQL線程從中繼日誌讀取事件,更新slave的數據,使其與主服務器中的數據一致。只要該線程與I/O線程保持一致,中繼日誌一般會位於OS的緩存中,因此中繼日誌的開銷很小。服務器
可使用「show slave status\G」從下面的變量中獲取當前IO線程所狀態:網絡
•Master_Log_File – 最近從主服務器上覆制過來的文件 (多數狀況下它和主服務器最近寫入的二進制日誌文件相同)session
•Read_Master_Log_Pos – 主服務器上二進制日誌複製到從服務器上中繼日誌的位置.
能夠從下面的變量中獲取當前SQL線程的狀態:
•Relay_Master_Log_File – 來自主服務器的二進制日誌, 供SQL線程處理 (實際SQL線程是工做在中繼日誌上)
•Exec_Master_Log_Pos – SQL線程執行的二進制日誌的位置.
•Seconds_behind_master - 顯示從服務器的延遲
此外,在主服務器中也有一個工做線程:和其它MySQL的鏈接同樣,從服務器在主服務器中打開一個鏈接也會使得主服務器開始一個線程。複製過程有一個很重要的限制——複製在從服務器上是串行化的,也就是說主服務器上的並行更新操做不能在從服務器上並行操做。
咱們能夠經過下列命令來了解主服務器的狀態:
SHOW MASTER STATUS:命令查看主服務器當前二進制日誌的位置和配置。
SHOW MASTER LOGS:查詢主服務器哪一個二進制日誌在磁盤上。
SHOW BINLOG EVENTS:在二進制日誌中查看複製事件。
下圖是網上看到的一張圖,它比較形象地顯示了這個過程:
MySQL常見的複製拓撲結構以下:
1)主服務器和多個從服務器
這種配置在寫較少,讀取較多的時候最有用,能夠把讀取分攤到任意多的從服務器上,如:爲不一樣的角色使用不一樣的從服務器;把一個從服務器當成待命主服務器,除去複製就沒有其餘數據流量;把遠程的數據中心做爲從服務器,以備災恢復使用;延遲一個或多個從服務器,以備災恢復;爲備份、培訓、開發或測試使用從服務器。
須要注意的是:當slave增長到必定數量時,slave對master的負載以及網絡帶寬都會成爲一個嚴重的問題。
2)主動-主動模式下的主-主複製
主-主複製也叫雙主服務器複製或雙向複製,包含兩個服務器,每個服務器都便是主服務器也是對方的從服務器。
這種配置最大的老是是如何解決衝突。問題一般發生在兩個服務器同時更改了同一行數據,或同時向一個有AUTO_INCREMENT列的表中插入了數據。可能能夠經過分區數據和權限避免一些問題。
3)主動-被動模式下的主-主複製
這種模式是由主動-主動模式下的主-主複製結構變化而來的,避免了M-M的缺點,是一種具備容錯和高可用性的系統。這種配置與主動-主動模式下的主-主複製最大的不一樣在於其中一個服務只能進行只讀操做。
這種配置能夠輕易地來回交換主動服務器和被動服務器的角色,這時故障轉移和故障恢復就容易了,它能夠在不關閉服務器的狀況下執行維護、優化表、升級操做系統(或者應用程序,硬件)及其餘任務。
可使用MySQL主-主複製管理工具(http://code.google.com/p/mysql-master-master)來建立和管理這種拓撲結構。它使不少複雜的動做變得自動化了,如恢復和從新同步複製,建立新的從服務器等。
4)有從服務器的主-主複製
這種配置是給主服務器對添加從服務器,這種配置的好處是額外的冗餘度,對於位於不一樣地點的複製拓撲,它在每一個站點都能消除一個故障點,同時還能夠將讀密集型的請求放到從服務器上。
還有一些不常見的結構:如環、樹或金字塔結構等。
前面提到能夠採用MySQL複製架構在主服務器和從服務器之間分離負載,最典型的案例就是讀寫分離。一般咱們將讀操做分流到從服務器上,而將寫操做集中到主服務器上。在構建基於MySQL複製基礎上的讀寫分離架構時,比較理想的MySQL複製拓撲結構是帶從服務器的主動-被動模式下的主-主複製。這種拓撲結構還能夠採用MySQL主-主複製管理工具MMM進行管理(http://code.google.com/p/mysql-master-master)。
讀寫分離的方案有多種,在Spring+Hibernate的架構下,爲讀寫操做分別綁定到不一樣的數據庫鏈接上,關鍵點在於配置爲Spring+Hibernate配置多數據庫,能夠在網上找到許多關於Spring+Hibernate多數據庫的解決方案。這種方案比較簡單,容易實現,但不太利於擴展。單純將讀寫操做分離到不一樣的服務器上,將會趕上這樣的問題,用戶提交更改記錄後再次查詢會出現顯示的仍爲原更改前的記錄。這主要是因爲複製延時形成的,針對這種問題,常見的策略有:
A.以查詢爲基礎的分離:把全部寫操做和一些不接受舊數據的讀操做放在主服務器上,而其餘讀操做放在從服務器上。
B.舊數據分離:須要去檢查從服務器的遲滯程度,而後決定這些數據對讀操做是否是夠「陳舊」。許多報表類的應用可使用這個策略。
C.以session爲基礎的分離:若是用戶對數據有過更新,就在session層設置一個標誌,這樣當用戶執行讀查詢時,系統就會到主服務器上讀取數據。
D.以版本爲基礎的分離:根據從服務器上讀取對象的版本號和時間戳來判斷這些數據是否「陳舊」。
E.全局版本/會話分離:以版本爲基礎和以會話爲基礎的變種方法。
在MySQL的複製過程當中,總會出現一些不一樣的問題,好比:主服務器意外關閉或從服務器意外關閉、主服務器上的二進制日誌損壞或從服務器上中繼日誌損壞、二進制日誌和InnoDB事務日誌不一樣步、沒有磁盤空間、複製延時變大等等。不一樣的問題的解決方式不一樣,有時也許會爲不一樣的用途增長從服務器,或發生故障時切換主服務器或提高一從服務器爲主服務器等。
MMM工具能夠幫忙咱們解決其中一些問題。但咱們仍需仔細考慮在從服務器上負載均衡,如上述集成在應用中的讀寫分離方案還須要再增長實現相應的功能,並隨着應用的增加也會變得愈來愈複雜。咱們也能夠採用另外的方案,使用中間件來實現相應的讀寫分離。通常的是中間件方案都能比較方便地增長實現負載均衡和故障轉移(failover)的功能。同時咱們仍能夠在應用中集成故障轉移的功能,根據數據庫接入層返回來的狀態和應用中設定的閥值要求,在應用中發起故障轉移。
不少負載均衡的方案使用HAProxy,HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理。在百度百科中提到。(http://baike.baidu.com/view/2480120.htm),HAProxy實現了一種事件驅動, 單一進程模型,此模型支持很是大的併發鏈接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,不多能處理數千併發鏈接。事件驅動模型由於在有更好的資源和時間管理的用戶端(User-Space) 實現全部這些任務,因此沒有這些問題。此模型的弊端是,在多核系統上,這些程序一般擴展性較差。這就是爲何他們必須進行優化以使每一個CPU時間片(Cycle)作更多的工做。HAProxy可與Keepalived一塊兒來提供高可用性、負載均衡。HAProxy官方網址:http://haproxy.1wt.eu/, Keepalived官方網址:http://www.keepalived.org/
HAProxy是一種多用途的負載均衡器,並非爲MySQL專門設計的,它很難探測到MySQL的實際負荷,同時也易受應用中的鏈接池和持久性鏈接的影響(如增長從服務器時,因爲鏈接池保存現有鏈接而不生成新的鏈接時,新增長的從服務器很可貴到應用)。
MySQL Proxy是另一種可選用的負載均衡中間件,能夠實現主數據庫處理事務性查詢,從數據庫處理SELECT查詢,而數據庫複製將事務性查詢致使的變動同步到集羣中的從數據庫。關於這種使用方法以及鏈接池問題能夠參考<MySQL Proxy learns R/W Splitting>一文。MySQL-Proxy是處在MySQL數據庫客戶和服務端之間的中間件,經過截斷、改變並轉發客戶端的查詢請求等而後代理和後端數據庫之間的通訊來實現其主要功能。主要的工做過程是:
(1) MySQL Proxy以服務器的身份接受客戶端請求,根據Spy的配置對這些客戶端的請求進行分析處理
(2) 以客戶端的身份將客戶端的請求轉發給相應的後端數據庫服務器,而後再接受服務器的信息,返回給客戶端
MySQL Proxy是基於MySQL Protocol協議經過lua腳原本控制鏈接轉發的機制,能夠用來分析、監控和變換通訊數據。MySQL Proxy有着很是普遍的使用場景:查詢分析和日誌、負載平衡和故障轉移處理、SQL宏(SQL macros)、查詢重寫(query rewriting)、執行shell命令、實現數據分佈策略等。
參考:
<<高性能MySQL >>
第6章:MySQL中的複製 http://dev.mysql.com/doc/refman/5.1/zh/replication.html
http://dev.mysql.com/doc/refman/5.1/en/replication-solutions-switch.html
http://www.severalnines.com/resources/clustercontrol-mysql-haproxy-load-balancing-tutorial#failover
http://www.alexwilliams.ca/blog/2009/08/10/using-haproxy-for-mysql-failover-and-redundancy/
MySQL 複製:GTIDS實現自動故障恢復 http://www.oschina.net/translate/mysql_replication_self_healing_recovery
MySQL高可用方案:基於MHA實現的自動故障轉移羣集 http://www.2cto.com/database/201304/205011.html
MySQL Master-Slave架構下使用MMM的必要性 http://blog.csdn.net/starxu85/article/details/2693199
MySQL Proxy learns R/W Splitting http://jan.kneschke.de/2007/8/1/mysql-proxy-learns-r-w-splitting/