1. 程式人生 > >MySQL之——叢集的那些事

MySQL之——叢集的那些事

1   資料複製技術簡介

資料庫複製是指頻繁的將資料從一個節點(伺服器上的一個數據庫)複製到另一個節點,可以將資料庫複製系統看作一個分散式資料庫,但是其中所有節點共享相同的資訊。這類系統也稱為資料庫叢集。

1.1 Master-Slave/Multi-Master複製

1.1.1Master-Slave複製

在Master-Slave系統中,Master節點記錄資料修改日誌,並將日誌通過網路傳送到Slave節點。Slave節點從Master節點接收修改操作流,並重放修改。

1.1.2Multi-Master複製

在Multi-Master複製系統中,能夠將修改提交到任意一個數據庫節點(主要是環形複製),這些修改通過網路傳送到其他資料庫節點,所有節點都作為Master使用。

這是跨機房的HA。為了容災或者加速,很多公司都採用在不同機房部署資料庫的方式,所以就涉及到資料同步。為了保證每個機房產生的資料不衝突,一般來說我們採用的是auto_increment_increment,auto_increment_offset這兩個引數,可以控制步進。例如雙MAster,我們會配置主庫是奇數序列的ID,備庫是偶數序列的ID,這樣切換時就算有少量binlog還未應用,也不會導致資料衝突。跨機房以後,例如兩個機房都有雙Master,兩個機房之間資料又需要同步,以前需要藉助第三方指令碼或者程式,有了多Master,按如下方式搭建,設定步進為4,就可以保證每個機房有雙MAster HA,機房之間資料又可以同步。

這是一備多的備份。因為我們採用的分庫策略,使我們一個叢集會有很多個例項,每個例項裡面有幾個Schema,但是肯定不會重複。例如第一個例項是1~3號Schema。第二個例項就是4~6號Schema,所以binlog應用到一起並不會衝突資料。

1.2 Asynchronous/Synchronous/並行複製

1.2.1Asynchronous複製

非同步複製採用延時(lazy)複製策略,Master資料庫非同步方式傳送修改複本到其他節點。在日誌記錄(或)日誌傳送後,Master節點提交事務。當事務提交後,至少短暫時間內,部分節點擁有不同資料。

1.2.2Asynchronous複製缺點

slave會對master有一個更新延遲,當master宕機,slave被提升為新的master時,必然會發生資料丟失。

1.2.3Synchronous複製

同步複製採用即時(eager)複製策略,通過在一個事務中完成所有複本修改保持節點複本同步。當事務提交後,所有節點擁有相同資料。

理論上來講,同步複製具有如下優點:(1)高可用,節點崩潰時沒有資料丟失、資料複本一致、不需要複雜耗時的故障切換;(2)提升效能,可以在所有節點上並行執行事務;(3)跨叢集因果關係,例如,事務執行後傳送的SELECT query總能夠看到事務效果,即使事務是在其他節點上執行的。

傳統的即時複製協議一次協調一個操作,並使用兩階段提交或分散式鎖。假設系統中n個節點o個操作每秒t個事務吞吐量,每秒訊息數是:

這就意味著,每增加節點,都會導致事務響應時間和衝突與死鎖頻率指數級增長。

1.2.4Synchronous複製缺點

效能低下

原因:當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。因為需要等待所有從庫執行完該事務才能返回,所以全同步複製的效能必然會收到嚴重的影響。

1.2.5 並行複製

半同步複製解決了Master-Slave的強一致問題,那麼效能問題呢?可以看到參與複製的主要有兩個執行緒:IO執行緒和SQL執行緒,分別用於拉取和回放binlog。對於Slave而言,所有拉取和解析binlog的動作都是序列的,相對於Master併發處理使用者請求,在高負載下, 若Master產生binlog的速度超過Slave消費binlog的速度,導致Slave出現延遲。如圖4,可以看到,Users和Master之間的管道遠遠大於Master和Slave之間的管道。

那麼如何並行化,並行IO執行緒,還是並行SQL執行緒?其實兩方面都可以並行,但是並行SQL執行緒的收益更大,因為SQL執行緒做的事情更多(解析,執行)。並行IO執行緒,可以將從Master拉取和寫Relaylog分為兩個執行緒;並行SQL執行緒則可以根據需要做到庫級並行,表級並行,事務級並行。庫級並行在mysql官方版本5.6已經實現。如圖,並行複製框架實際包含了一個協調執行緒和若干個工作執行緒,協調執行緒負責分發和解決衝突,工作執行緒只負責執行。圖中,DB1,DB2和DB3的事務就可以併發執行,提高了複製的效能。有時候庫級併發可能不夠,需要做表級併發,或更細粒度的事務級併發。

並行複製如何處理衝突?併發的世界是美好的,但不能亂併發,否則資料就亂了。Master上面通過鎖機制來保證併發的事務有序進行,那麼並行複製呢?Slave必需保證回放的順序與Master上事務執行順序一致,因此只要做到順序讀取binlog,將不衝突的事務併發執行即可。對於庫級併發而言,協調執行緒要保證執行同一個庫的事務放在一個工作執行緒序列執行;對於表級併發而言,協調執行緒要保證同一個表的事務序列執行;對於事務級而言,則是保證操作同一行的事務序列執行。

是否粒度越細,效能越好?這個並不是一定的。相對於串行復制而言,並行複製多了一個協調執行緒。協調執行緒一個重要作用是解決衝突,粒度越細的併發,可能會有更多的衝突,最終可能也是序列執行的,但消耗了大量的衝突檢測代價。

1.2.6同步複製改進方案

1.3 MySQL同步粒度及引擎

1.3.1 MySQL同步粒度

可通過配置檔案my.cnf配置,如下

引數binlog-do-db=要給從節點同步的庫,如果不配置此引數,整個資料庫都將進行同步,如果之前設定了要同步的庫,然後將此引數刪除,同步的庫包括(兩個資料庫中庫名錶名欄位名及資料內容相同的庫將會進行同步)。

1.3.2 MySQL同步支援引擎

經過測試mysql主從同步支援引擎有(innodb,myisam,黑洞引擎,isam等資料庫引擎),且資料庫引擎還可交叉使用,(如主節點使用innodb,從節點使用myisam,黑洞引擎等)

2   MySQL資料庫複製方案

2.1 MySQL Replication

MySQL Replication是MSQL Server提供的功能,允許從一個MSQL資料庫伺服器(稱為master)複製到一個或多個MySQL資料庫伺服器(稱為slaves)。MySQL Replication的採用非同步複製機制,複製過程不是即時的,不能確保slaves和master內容相同。

MySQL Replication使用靈活,根據配置,可以複製所有資料庫、選中的資料庫,甚至是一個數據中選中的表。

在MySQLReplication中,相關伺服器具有下面兩個角色中的一個:(1)Master:Master MySQL伺服器將所有修改資料的事務寫入到binary log中;(2)Slave:Slave MySQL伺服器啟動時連線master,從master的binary log中下載事務,然後將本地伺服器重放(apply)事務。

需要注意的是,Slaves本身也可以作為masters,Slaves從其master重放的事務可以再寫入到其自身的binary log中,能夠像其直接生成的事務那樣尤其slaves重放。

2.1.1 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,這在資料分析、資料備份與容災等方面有很大幫助。

2.1.2 MySQL Replication架構方式

2.1.2.1  Master-Slave

單個Master和一個或多個Slaves是最簡單的架構方式。這種架構方式中,Master和Slave中資料可能不一致,並且不同的Slaves的資料可能略有差異,例如當Slaves通過不同網路連線方式接入到Master時,本地連線的Slave資料可能更新,因為Internet傳輸延遲會減緩資料複製過程。

Master-Slave架構具有如下優點:(1)不同的MySQL伺服器上可以執行稍有差異的結構(如不同的索引),這樣可以將少量開銷很大的queries在指定的Slave上執行,以免拖慢Master;(2)配置管理簡單。

Master-Slave架構具有如下不足:(1)沒有自動冗餘,在Master故障時,Slaves可能資料與Master不一致,不能提升為Master,這在Slave部署在低配裝置上時尤其常見;(2)Write query不能在Slave上執行;(3)複製與RAID1相同,磁碟空間使用率不高;(4)在下載binary log時,每個Slave都增加一些Master負載,因此Slaves個數不能無限制增加。

2.1.2.2  Master-Master

Master-Master架構方式包含兩個MySQLServer,兩個都配置為Master和Slave,一個伺服器執行的事務能夠被另一個獲得,反之亦然。

這種架構方式具有很致命的問題:(1)相互衝突的query在兩個節點上同時執行導致的某些query的不確定性和競爭條件,很容易導致資料的不一致性;(2)一旦存在不一致,還很難發現,直到嚴重到由於複製query不能執行導致複製斷開。

由於存在致命的一致性問題,這種方案不宜使用,如果確實需要多個活體,考慮使用其他高可用解決方案。

2.1.2.3 Active/Passive Master

Active/PassiveMaster架構方式包含兩個MySQL伺服器,配置為Master-Master複製,但是在一個Passive節點外設定了某種形式的“write barrier”,以確保在任意時間點只能有一個節點能夠執行修改資料的query。

2.1.3 MySQL Replication工作機制

2.1.3.1 MySQL主從同步流程

Slave 上面的IO執行緒連線上 Master,並請求從指定日誌檔案的指定位置(或者從最開始的日誌)之後的日誌內容;

Master 接收到來自 Slave 的 IO 執行緒的請求後,通過複製的 IO 執行緒根據請求資訊讀取指定日誌指定位置之後的日誌資訊,返回給 Slave 端的 IO 執行緒。返回資訊中除了日誌所包含的資訊之外,還包括本次返回的資訊在 Master 端的 Binary Log 檔案的名稱以及在 Binary Log 中的位置;

Slave 的 IO 執行緒接收到資訊後,將接收到的日誌內容依次寫入到 Slave 端的Relay Log檔案(mysql-relay-bin.xxxxxx)的最末端,並將讀取到的Master端的bin-log的檔名和位置記錄到master- info檔案中,以便在下一次讀取的時候能夠清楚的高速Master“我需要從某個bin-log的哪個位置開始往後的日誌內容,請發給我”;

Slave 的 SQL 執行緒檢測到 Relay Log 中新增加了內容後,會馬上解析該 Log 檔案中的內容成為在 Master 端真實執行時候的那些可執行的 Query 語句,並在自身執行這些 Query。這樣,實際上就是在 Master 端和 Slave 端執行了同樣的 Query,所以兩端的資料是完全一樣的。

2.1.3.2 MySQL主從同步延遲原因

從上面來看,主從同步延遲的主要原因是因為主庫採用多執行緒更新,而從庫採用單執行緒更新。看起來解決問題很簡單,只要從庫也採用多執行緒更新即可。

但這樣做會帶來一個新問題,當從relay_log讀到對同一個條記錄的多條操作時(比如先後insert和update 了同一個記錄),此時如果這兩個操作分配給了2個sql 執行緒併發去更新從庫,那就不能保證它們的執行順序了。

解決這個問題的方法是,當有多個sql_thread執行緒來更新從庫的時候,必須讓每個sql_thread對應一張表,如果從庫有10張表,那麼就使用10個sql_thread分別更新,這樣就解決了併發帶引起的亂序的問題;

2.1.3.3 MySQL主從同步解決方案

改進的主從同步方案:

1、在io_thread接收主庫日之後,分成N份relay-log存放;
2、再用N個sql_thread分別讀取日誌分發;
3、確保同一個表的更新語句順序與主庫binlog相同

2.2 Multi MasterReplication Manager(MMM)

MMM(Multi Master Replication Manager)是開源的Perl指令碼集,用於Active/Passive Master架構方式的自動化建立和管理。

Active/Passive底層的MySQL Replication複製機制是非同步的,當Master故障時可能導致部分事務丟失,Multi Master ReplicationManager並不能處理這種情況。實際上,如果這種事務丟失不可接受,任何基於非同步複製的高可用技術都不適用。

2.3 DistributedReplicated Block Device(DRBD)

DRBD是領先的Block級複製開源軟體。Block級複製通過機器間硬碟驅動(Block)級資料複製實現高可用資料庫。換句話說,在兩個機器上,每次mainServer核心上的Write操作,都被髮送到另一個Server上,寫入到其硬碟。

DRBD通過在叢集相關Linux機器上安裝一個核心模組,一旦載入,該核心模組在磁碟驅動排程執行寫入前捕獲IO Write操作,並通過TCP/IP傳送到複本Server上,複本Server將Write傳送到其本地磁碟。在此過程中的某個階段,第一個節點像其磁碟傳送Write,並向MySQL報告Write執行完成。這裡需要一致性和效能的折中考慮,由一個配置引數可以指定在節點接收到Write的處理過程中的哪個點通知應用Write執行完成。為了最大持久化,通常是在Write在對等節點磁碟上執行之後才通知應用,這種稱為同步模式(synchronousmode),執行過程如圖所示。

DRBD預設不支援同時寫入到多個節點上,如果想要同時寫入到多個節點上,需要使用叢集感知檔案系統(如GFS)。

2.3.1.1 DRBD 架構

2.3.2 DRBD 主要功能

儘管複製磁碟的思想從概念上來說是很簡單的(開發也相對比較容易),但是一個健壯的實現也有很多固有的複雜性。例如,向一個網路驅動器複製塊相對比較簡單,但是,處理故障和暫時斷電(以及隨後的驅動器同步)才是真正解決方案的開始。本節將介紹 DRBD 提供的主要功能,包括各種 DRBD 支援的故障模型。

2.3.2.1 複製模式

本文前面探究了節點之間複製資料的各種方法(尤其是這兩種 — 完全同步和完全非同步)。DRBD 支援每種方法的變體,這些方法比非同步模式提供更多的資料保護,代價是效能略有下降。記憶體非同步模式(或半非同步模式) 是介於同步模式和非同步模式之間的一個變體。在這種模式下,寫操作是在資料儲存到本地磁碟並映象到對等節點記憶體後被確認的。該模式提供更多保護,因為資料被映象到另一個節點,這僅僅是針對易失性記憶體,而不是非易失性磁碟。這仍然可能丟失資料(例如,如果兩個節點都發生故障),但是主節點故障不會引起資料丟失,因為資料已經被複制了。

2.3.2.2 聯機裝置驗證

DRBD 允許對本地和遠端對等裝置進行聯網驗證(在輸入/輸出發生的同時)。驗證意味著 DRBD 可以核實本地和遠端磁碟是否是相互間的副本,這是一個耗時的操作。但是相比在節點之間移動資料進行驗證,DRBD 提供了一個更為高效的方法。為了保護節點間的頻寬(可能是一個受限資源),DRBD不需要在節點間移動資料進行驗證,而是移動資料(hash)的加密摘要。這樣一來,一個節點可以計算一個塊的雜湊值;將較小的簽名轉移到對等節點,該節點也可以計算雜湊值,然後對兩者進行比較。如果雜湊值是相同的,資料塊已經被正確的複製了。如果雜湊值不相同,將過期的資料塊標記為不同步,隨後的同步確保資料塊是正確同步的。

2.3.2.3 通訊完整性

節點之間的通訊可能會將錯誤引入複製資料(由於軟體或防火牆漏洞,或者不能被 TCP/IP 的校驗碼檢測出來的其他錯誤)。為了提供資料的完整性,DRBD 計算訊息完整性程式碼,以隨資料一起在節點之間移動。這支援接收節點驗證輸入資料,並在發現一個錯誤時請求重發資料。DRBD 使用 Linux 加密應用程式程式設計介面,因此在完整性演算法使用方面是比較靈活的。

2.3.2.4 自動恢復

DRBD 可以從多種錯誤中恢復,但是一個最嚴重的錯誤就是所謂的 “裂腦(split-brain)”。在這個錯誤場景中,節點之間的通訊鏈發生故障,每個節點都認為自己是主節點。而對於主節點而言,每個節點支援寫操作,而不會將這些操作傳播到對等節點。這導致每個節點中的儲存不一致。

大多數情況下,腦裂恢復是人工進行的,但是 DRBD 提供幾個主動恢復這一狀況的操作方法,所用恢復演算法具體取決於實際的儲存方式。

發生裂腦之後,同步儲存最簡單的方法是在連結出現故障時其中一個節點沒有發現改變。這樣,已經發生改變的節點與潛在對等節點進行簡單的同步。另一個方法是丟棄變更較少的那個節點中的更改。這使得最大變更集合的節點可以繼續工作,但也意味著一個主機上的變更將丟失。

還有兩個方法是根據節點當時的狀態丟棄更改。一種方法是將最後一次轉換成主節點的那個節點中的變更丟棄,而另一種是將最老的主節點(是第一次轉換成主節點的節點)中的變更丟棄。您可以在 DRBD 配置檔案中操作每個節點,但是它們最終的使用取決於使用儲存的應用程式以及資料是否有必要丟棄或進行人工恢復。

2.3.2.5 優化同步

複製儲存裝置的一個關鍵因素是節點之間資料同步的方法是否高效。DRBD 使用的模式其中兩個是活動日誌和快速同步點陣圖。活動日誌儲存最近寫入的塊並確定故障恢復後應同步哪些塊。快速同步點陣圖確定連線斷開時同步(或不同步)的資料塊。節點重新連線之後,可使用這些點陣圖快速同步節點,彼此之間進行精確的複製。時間是很重要的,因為它代表輔助磁碟不一致時的視窗。

2.4 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.4.1 MySQL Fabirc架構及實現原理

Fabric使用HA組實現高可用性,其中一臺是主伺服器,其他是備份伺服器, 備份伺服器通過同步複製實現資料冗餘。應用程式使用特定的驅動,連線到Fabric 的Connector元件,當主伺服器發生故障後,Connector自動升級其中一個備份伺服器為主伺服器,應用程式無需修改。

2.4.2 Fabric支援可擴充套件性及負載均衡的架構

http://www.2cto.com/database/201504/387166.html

http://www.2cto.com/database/201408/327941.html

2.5.1 MySQL Cluster簡介:

MySQLCluster 是MySQL 官方叢集部署方案,它的歷史較久。支援通過自動分片支援讀寫擴充套件,通過實時備份冗餘資料,是可用性最高的方案,聲稱可做到99.999%的可用性。

2.5.2 架構及實現原理

MySQL Cluster是無共享記憶體資料庫叢集,整合標準MySQL伺服器與NDB(NetWorkDataBase)記憶體叢集儲存引擎。採用無共享架構,可以使用低廉的硬體,且對硬體和軟體需求具體要求很小。

MySQL Cluster設計方式不存在單點故障。無共享架構方式的系統中每個元件都有獨立的記憶體和磁碟,並且不推薦使用共享儲存機制,如網路共享、網路檔案系統、SAN等。

MySQL Cluster由成為主機的計算機集組成,每個主機上執行一個或多個程序。這些程序稱為節點,包括MySQL Server(用來訪問NDB資料)、資料節點(用來儲存資料)、一個或多個管理伺服器,並且可能還有特殊資料訪問程式,元件間關係如圖所示:

2.5.3 MySQL Cluster缺點及限制

對需要進行分片的表需要修改引擎Innodb為NDB,不需要分片的可以不修改。NDB的事務隔離級別只支援Read Committed,即一個事務在提交前,查詢不到在事務內所做的修改;而Innodb支援所有的事務隔離級別,預設使用Repeatable Read,不存在這個問題。外來鍵支援:雖然最新的Cluster版本已經支援外來鍵,但效能有問題(因為外來鍵所關聯的記錄可能在別的分片節點中),所以建議去掉所有外來鍵。Data Node節點資料會被儘量放在記憶體中,對記憶體要求大。 

資料庫系統提供了四種事務隔離級別:
A.Serializable(序列化):一個事務在執行過程中完全看不到其他事務對資料庫所做的更新(事務執行的時候不允許別的事務併發執行。事務序列化執行,事務只能一個接著一個地執行,而不能併發執行。)。
B.Repeatable Read(可重複讀):一個事務在執行過程中可以看到其他事務已經提交的新插入的記錄,但是不能看到其他其他事務對已有記錄的更新。
C.Read Commited(讀已提交資料):一個事務在執行過程中可以看到其他事務已經提交的新插入的記錄,而且能看到其他事務已經提交的對已有記錄的更新。
D.Read Uncommitted(讀未提交資料):一個事務在執行過程中可以看到其他事務沒有提交的新插入的記錄,而且能看到其他事務沒有提交的對已有記錄的更新。

Ø 資料節點(Data Node)

Ø SQL節點(SQL Node)

Ø 標準MySQL客戶端(Standard MySQL Clients)

Ø NDB客戶端程式(NDB Client Programs)

管理客戶端(Management Clients)

2.6 Galera Cluster

2.6.1 Galera注意事項

1.使用Galera必須要給MySQL-Server打wsrep補丁。可以直接使用官方提供的已經打好補丁的MySQL安裝包,如果伺服器上已經安裝了標準版MYSQL,需要先解除安裝再重新安裝。解除安裝前注意備份資料。

2.MySQL/Galera叢集只支援InnoDB儲存引擎。如果你的資料表使用的MyISAM,需要轉換為InnoDB,否則記錄不會在多臺複製。可以在備份老資料時,為mysqldump命令新增–skip-create-options引數,這樣會去掉表結構的宣告資訊,再匯入叢集時自動使用InnoDB引擎。不過這樣會將AUTO_INCREMENT一併去掉,已有AUTO_INCREMENT列的表,必須在匯入後重新定義。

3.MySQL 5.5及以下的InnoDB引擎不支援全文索引(FULLTEXT indexes),如果之前使用MyISAM並建了全文索引欄位的話,只能安裝MySQL 5.6 with wsrep patch。

4.所有資料表必須要有主鍵(PRIMARY),如果沒有主鍵可以建一條AUTO_INCREMENT列。

5.MySQL/Galera叢集不支援下面的查詢:LOCK/UNLOCK TABLES,不支援下面的系統變數:character_set_server、utf16、utf32及ucs2。

6.資料庫日誌不支援儲存到表,只能輸出到檔案(log_output= FILE),不能設定binlog-do-db、binlog-ignore-db。

7.跟其他叢集一樣,為了避免節點出現腦裂而破壞資料,建議Galera叢集最低新增3個節點。

8.在高併發的情況下,多主同時寫入時可能會發生事務衝突,此時只有一個事務請求會成功,其他的全部失敗。可以在寫入/更新失敗時,自動重試一次,再返回結果。

9.節點中每個節點的地位是平等的,沒有主次,向任何一個節點讀寫效果都是一樣的。實際可以配合VIP/LVS或HA使用,實現高可用性。

10.如果叢集中的機器全部重啟,如機房斷電,第一臺啟動的伺服器必須以空地址啟動:mysqld_safe–wsrep_cluster_address=gcomm://>/dev/null &

2.6.2 Replication API

2.6.2.1 wsrep API 

wsrep API通用的資料庫複製外掛介面,定義了實現事務型資料庫和類似應用的同步式writeset複製所需的應用回撥和複製外掛呼叫集。wsrep API旨在將複製實現從應用細節中抽象和隔離出來。wsrep API的主要目標是基於認證的(certification-based)multi-master複製,但同樣適用於非同步和同步式master/slave複製。

wsrep API使用認為資料庫伺服器有狀態的複製模型,其中狀態是指資料庫中的內容。當使用資料庫時,使用者修改資料庫的內容,因而改變其狀態。wsrep API將資料庫狀體表示為一系列原子改變(atomic changes),或者是事務。

在資料庫叢集中,所有節點總是保持相同的狀態,通過複製和按相同序列順序回放狀態修改保持彼此同步。

2.6.2.2 Global Transaction ID(GTID)

為了保持叢集中狀態是同一的,wsrep API使用GolbalTransaction ID(GTID),GTID能夠標識狀態改變,並能夠辨別當前狀態與上一個狀態改變的相對關係。GTID由兩部分組成:(1)StateUUID,狀態及其經歷的改變序列的唯一識別符號;(2)OrdinalSequence Number,seqno,表示改變在序列中位置的64位無符號整數。

2.6.2.3 Glaera Replication Plugin

2.6.2.4  Group ComunicationPlugins

2.6.2.5 參考資料

2.http://galeracluster.com/documentation-webpages/architecture.html

2.7 Percona XtraDBCluster(PXC)

2.7.1 Percona XtraDBCluster簡介

Percona XtraDB Cluster(PXC)是免費、開源的MyDSQL高可用軟體,具有如下特徵:(1)PXC由Node組成,建議叢集至少包含三個Node,但是兩個Node也能執行;(2)每個Node是普通的MySQL/Percona Server例項,可以將已有MySQL/Percona Server轉換為PXC重Node,也可以將Node從PXC中分離為普通Server;(3)每個Node包含所有資料。

PXC主要優點:(1)query在Node本地執行,所有資料在本地可見,不需要遠端訪問;(2)沒有中央管控,任何Node任何時間失效都不影響Cluster的持續執行;(3)好的read負載擴充套件解決方案,可以在任何Node上執行read query。

PXC主要缺點:(1)增加新Node開銷大,新增Node需要從一個已有Node拷貝所有資料;(2)不能作為有效的write擴充套件方案,將write流量分離到多個Node上,能夠有些效能提升,但是不能期望太多,因為最終write將在所有Node上執行;(3)有多個數據複本,複本數與Node數相同。

PXC基於PerconaServer with XtraDB,並且需要Write Set Replication補丁,使用Galera Library實現Multi-Master同步複製。

3   負載均衡排程

3.1HAProxy

3.1.1 Haproxy簡介

HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支援虛擬主機,它是免費、快速並且可靠的一種解決方案。HAProxy特別適用於那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy執行在當前的硬體上,完全可以支援數以萬計的併發連線。並且它的執行模式使得它可以很簡單安全的整合進您當前的架構中,同時可以保護你的web伺服器不被暴露到網路上。

HAProxy實現了一種事件驅動, 單一程序模型,此模型支援非常大的併發連線數。多程序或多執行緒模型受記憶體限制、系統排程器限制以及無處不在的鎖限制,很少能處理數千併發連線。事件驅動模型因為在有更好的資源和時間管理的使用者空間(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程式通常擴充套件性較差。這就是為什麼他們必須進行優化以使每個CPU時間片(Cycle)做更多的工作

3.1.2 配置

配置HAProxy Session親緣性的三種方式

haproxy負載均衡保持客戶端和伺服器Session親緣性的三種方式:

1 使用者IP 識別aproxy 將使用者IP經過hash計算後 指定到固定的真實伺服器上(類似於nginx 的IP hash 指令)配置指令 balance source

2 cookie 識別:haproxy 將WEB服務端傳送給客戶端的cookie中插入(或新增字首)haproxy定義的後端的伺服器COOKIE ID。配置指令例舉 cookie SESSION_COOKIEinsert indirect nocache用firebug可以觀察到使用者的請求頭的cookie裡 有類似" Cookiejsessionid=0bc588656ca05ecf7588c65f9be214f5; SESSION_COOKIE=app1"SESSION_COOKIE=app1就是haproxy新增的內容

3 session 識別:haproxy 將後端伺服器產生的session和後端伺服器標識存在haproxy中的一張表裡。客戶端請求時先查詢這張表。配置指令例舉 appsessionJSESSIONID len 64 timeout 5h request-learn

4   MySQL資料同步錯誤及處理

4.1 mysql主從同步失敗原因

1.網路的延遲

2.主從兩臺機器的器的負載不一致

3.max_allowed_packet設定不一致

4.key自增鍵開始的鍵值跟自增步長設定不一致引起的主從不一致

5.mysql異常宕機情況下,如果未設定sync_binlog=1或者    innodb_flush_log_at_trx_commit=1很有可能出現binlog或者relaylog檔案出現損壞,導致主從不一致

6.mysql本身的bug引起的主從不同步

7.版本不一致,特別是高版本是主,低版本為從的情況下,主資料庫上面支援的功能,從資料庫上面不支援該功能

4.2 如何判斷mysql主從同步是否成功

執行show slave status 命令

檢視Slave_IO_Running: Slave_SQL_Running:這兩個引數的狀態,正常是YES,如果是NO,那麼主從複製肯定是有問題的

    Slave_IO_Running: 如果等於Connecting 表示Master 沒有啟動MySQL服務。Last_IO_Error: 和 Last_SQL_Error:是否為null,為null則無錯,有值則有錯

4.3 如何判斷mysql主從同步是否同步完成

簡單來講就是從庫先通過io執行緒讀取主庫的二進位制檔案Master_Log_File和位置Read_Master_Log_Pos然後快取到本地(從庫伺服器)的中繼檔案Relay_Log_File中並記錄已經讀取到的位置Relay_Log_Pos,再通過從庫的sql執行緒去讀取中繼檔案Relay_Log_File,這個sql執行緒執行會記錄已經執行到了哪個檔案Relay_Master_Log_File和哪個位置Exec_Master_Log_Pos,如果Exec_Master_Log_Pos和Read_Master_Log_Pos相等就說明同步完成,否則同步末完成,正在同步。

4.4.1 Slave_IO_Running :NO 錯誤處理

1)常見錯誤:

       1.1 網路問題;

       1.2  My.cnf配置檔案有誤

       1.3 授權問題 , replication slave和file許可權是必須要有的;

1)資料沒有同步;

  2)從節點上進行寫操作;

   處理辦法:

   跳過當前錯誤:但是這樣資料已經不一致。 set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

   從做主從:這個方法不適用是資料量大的時候,因為從做主從會將主節點的bin-log檔案傳入到從節點中,進行重複制,資料量大工作量就會大,時間也會更多,所以不可取,

   從錯誤點開始重做主從:找到錯誤點,從這個點開始做複製,這樣這要及時的獲取到錯誤,資料量不在,資料也能及時同步,資料也能保證一致。語句為

change master to 
> master_host='master_ip',
> master_user='使用者名稱', 
> master_password='密碼', 
> master_port=埠, 
> master_log_file=File', 
> master_log_pos=120 ;

本語句就能保證你從錯誤開始做主從;

參見

4.5 命令詳解

SHOW SLAVE STATUS會返回以下欄位:

Slave_IO_State:SHOWPROCESSLIST輸出的State欄位的拷貝。SHOW PROCESSLIST用於從屬I/O執行緒。如果執行緒正在試圖連線到主伺服器,正在等待來自主伺服器的時間或正在連線到主伺服器等,本語句會通知您

 Master_User:被用於連線主伺服器的當前使用者。

Master_Port:當前的主伺服器介面。

Connect_Retry:--master-connect-retry選項的當前值

Master_Log_File:I/O執行緒當前正在讀取的主伺服器二進位制日誌檔案的名稱。

Read_Master_Log_Pos:在當前的主伺服器二進位制日誌中,I/O執行緒已經讀取的位置。

Relay_Log_File:SQL執行緒當前正在讀取和執行的中繼日誌檔案的名稱。

Relay_Log_Pos:在當前的中繼日誌中,SQL執行緒已讀取和執行的位置。

Relay_Master_Log_File:由SQL執行緒執行的包含多數近期事件的主伺服器二進位制日誌檔案的名稱。

Slave_IO_Running:I/O執行緒是否被啟動併成功地連線到主伺服器上。

Slave_SQL_Running:SQL執行緒是否被啟動。

Replicate_Do_DB,Replicate_Ignore_DB:使用--replicate-do-db和--replicate-ignore-db選項指定的資料庫清單。

Replicate_Do_Table,Replicate_Ignore_Table,Replicate_Wild_Do_Table,Replicate_Wild_Ignore_Table

使用

--replicate-do-table,--replicate-ignore-table,--replicate-wild-do-table

和--replicate-wild-ignore_table選項指定的表清單。

Last_Errno,Last_Error:被多數最近被執行的查詢返回的錯誤數量和錯誤訊息。錯誤數量為0並且訊息為空字串意味著“沒有錯誤”。如果Last_Error值不是空值,它也會在從屬伺服器的錯誤日誌中作為訊息顯示。

舉例說明:

Last_Errno: 1051Last_Error: error 'Unknown table 'z'' on query 'drop table z' 該訊息指示,表z曾經存在於在主伺服器中並已被取消了,但是它沒有在從屬伺服器中存在過,因此對於從屬伺服器,DROP TABLE失敗。(舉例說明,在設定複製時,如果您忘記了把此表拷貝到從屬伺服器中,則這有可能發生。)

Skip_Counter:最近被使用的用於SQL_SLAVE_SKIP_COUNTER的值。

Exec_Master_Log_Pos:來自主伺服器的二進位制日誌的由SQL執行緒執行的上一個時間的位置(Relay_Master_Log_File)。

在主伺服器的二進位制日誌中的(Relay_Master_Log_File,Exec_Master_Log_Pos)對應於在中繼日誌中的(Relay_Log_File,Relay_Log_Pos)。

Relay_Log_Space:所有原有的中繼日誌結合起來的總大小。

Until_Condition,Until_Log_File,Until_Log_Pos:在START SLAVE語句的UNTIL子句中指定的值。

Until_Condition具有以下值:如果沒有指定UNTIL子句,則沒有值

如果從屬伺服器正在讀取,直到達到主伺服器的二進位制日誌的給定位置為止,則值為Master

如果從屬伺服器正在讀取,直到達到其中繼日誌的給定位置為止,則值為Relay

Until_Log_File和Until_Log_Pos用於指示日誌檔名和位置值。日誌檔名和位置值定義了SQL執行緒在哪個點中止執行。

Master_SSL_Allowed,Master_SSL_CA_File,Master_SSL_CA_Path,Master_SSL_Cert,Master_SSL_Cipher,Master_SSL_Key

這些欄位顯示了被從屬伺服器使用的引數。這些引數用於連線主伺服器。Master_SSL_Allowed具有以下值:如果允許對主伺服器進行SSL連線,則值為Yes,如果不允許對主伺服器進行SSL連線,則值為No,如果允許SSL連線,但是從屬伺服器沒有讓SSL支援被啟用,則值為Ignored。

與SSL有關的欄位的值對應於--master-ca,--master-capath,--master-cert,--master-cipher和--master-key選項的值。

Seconds_Behind_Master:本欄位是從屬伺服器“落後”多少的一個指示。當從屬SQL執行緒正在執行時(處理更新),本欄位為在主伺服器上由此執行緒執行的最近的一個事件的時間標記開始,已經過的秒數。當此執行緒被從屬伺服器I/O執行緒趕上,並進入閒置狀態,等待來自I/O執行緒的更多的事件時,本欄位為零。總之,本欄位測量從屬伺服器SQL執行緒和從屬伺服器I/O執行緒之間的時間差距,單位以秒計。

如果主伺服器和從屬伺服器之間的網路連線較快,則從屬伺服器I/O執行緒會非常接近主伺服器,所以本欄位能夠十分近似地指示,從屬伺服器SQL執行緒比主伺服器落後多少。如果網路較慢,則這種指示不準確;從屬SQL執行緒經常會趕上讀取速度較慢地從屬伺服器I/O執行緒,因此,Seconds_Behind_Master經常顯示值為0。即使I/O執行緒落後於主伺服器時,也是如此。換句話說,本列只對速度快的網路有用。

即使主伺服器和從屬伺服器不具有相同的時鐘,時間差計算也會起作用(當從屬伺服器I/O執行緒啟動時,計算時間差。並假定從此時以後,時間差保持不變)。如果從屬SQL執行緒不執行,或者如果從屬伺服器I/O執行緒不執行或未與主伺服器連線,則Seconds_Behind_Master為NULL(意義為“未知”)。舉例說明,如果在重新連線之前,從屬伺服器I/O執行緒休眠了master-connect-retry秒,則顯示NULL,因為從屬伺服器不知道主伺服器正在做什麼,也不能有把握地說落後多少。

  參見

4.5.2   show status like 'wsrep%'詳解

叢集內每個節點的wsrep_cluster_state_uuid的value都應該是一樣的,否則說明該節點不在叢集中了

wsrep_cluster_conf_id:顯示了整個叢集的變化次數。所有節點都應相同,否則說明某個節點與叢集斷開了
    wsrep_cluster_size:顯示了叢集中節點的個數
    wsrep_cluster_status:顯示叢集裡節點的主狀態。標準返回primary。如返回non-Primary或其他值說明是多個節點改變導致的節點丟失或者腦裂。如果所有節點都返回不是Primary,

則要重設quorum。具體參見

二、檢查節點狀態

節點狀態顯示了叢集中的節點接受和更新write-set狀態,以及可能阻止複製的一些問題

1.wsrep_ready顯示了節點是否可以接受queries。ON表示正常,如果是OFF幾乎所有的query都會報錯,報錯資訊提示“ERROR 1047 (08501) UnknownCommand”

2. SHOW GLOBALSTATUS LIKE 'wsrep_connected’顯示該節點是否與其他節點有網路連線。(實驗得知,當把某節點的網絡卡down掉之後,該值仍為on。說明網路還在)丟失連線的問題可能在於配置wsrep_cluster_address或wsrep_cluster_name的錯誤

3.wsrep_local_state_comment以人能讀懂的方式顯示節點的狀態,正常的返回值是Joining, Waiting on SST, Joined,Synced or Donor,返回Initialized說明已不在正常工作狀態

三、檢視複製的健康狀態

通過Flow Control的反饋機制來管理複製程序。當本地收到的write-set超過某一閥值時,該節點會啟動flow control來暫停複製直到它趕上進度。監控本地收到的請求和flow control,有如下幾個引數:

wsrep_local_recv_queue_avg——平均請求佇列長度。當返回值大於0時,說明apply write-sets比收write-set慢,有等待。堆積太多可能導致啟動flow control

wsrep_local_recv_queue_max 和 wsrep_local_recv_queue_min可以看佇列設定的最大最小值。
    wsrep_flow_control_paused 顯示了自從上次查詢之後,節點由於flow control而暫停的時間佔整個查詢間隔時間比。總體反映節點落後叢集的狀況。如果返回值為1,說明自上次查詢之後,節點一直在暫停狀態。如果發現某節點頻繁落後叢集,則應該調整wsrep_slave_threads或者把節點剔除
    wsrep_cert_deps_distance顯示了平行apply的最低和最高排序編號或者sql編號之間的平均距離值。這代表了節點潛在的並行程度,和執行緒相關四、檢測網路慢的問題通過檢查傳送佇列來看傳出的連線狀況
    wsrep_local_send_queue_avg顯示自上次查詢之後的平均傳送佇列長度。比如網路瓶頸和flow control都可能是原因

wsrep_local_send_queue_max 和 wsrep_local_send_queue_min可以看佇列設定的最大值和最小值
五、日誌監控在my.cnf中做如下配置
# wsrep Log Options
wsrep_log_conflicts=ON   #會將衝突資訊寫入錯誤日誌中,例如兩個節點同時寫同一行資料
wsrep_provider_options="cert.log_conflicts=ON"    #複製過程中的錯誤資訊寫在日誌中
wsrep_debug=ON    #顯示debug 資訊在日誌中,其中也包括鑑權資訊,例如賬號密碼。因此在生產環境中不開啟

  參見

4.6 MySQL主從同步操作注意事項

 主從同步狀態下關資料庫順序  先主後從

 主從同步狀態下開資料庫順序  先從後主 開之後一定要檢視IO和SQL執行緒是否啟動