實現(xiàn)高可用性的原則很簡單:
- 冗余(Redundancy):如果一個組件出現(xiàn)故障,必須有一個備用組件。這個備用組件可以是standing by的,也可以是當(dāng)前系統(tǒng)部署中的一部分。
- 應(yīng)急計劃(Contigency plans):如果一個組件出現(xiàn)故障,你必須知道做什么。這依賴于哪個組件出現(xiàn)故障以及如何發(fā)生故障。
- 程序(Procedure):如果一個組件出現(xiàn)故障,你能夠及時發(fā)現(xiàn)并迅速有效的執(zhí)行你的計劃。
冗余(Redundancy)
只要有單點故障(SPOF:Single Point of Failure)的存在,就無法保證系統(tǒng)的高可用性(關(guān)于單點故障可以參考 Fenng 的這篇文章,比較通俗易懂)。
為了搞清楚哪里需要冗余機制,我們需要找到部署中所有潛在的單點。雖然說起來簡單,但是需要一點想象力,以確保真正找到全部單點。交換機,路由器,網(wǎng)卡甚至電纜都是單點,除了這些,電源和物理設(shè)施也很重要。還有一些也為成為單點,比如只有一個員工知道如何處理某種類型的故障,所有的網(wǎng)絡(luò)都被集中到一個web頁面進行管理等。但定位到所有的單點并不意味著你必須要全部消除它們,因為有些單點或許因為經(jīng)濟上,技術(shù)上或者地理上的原因而無法完全消除,但知道這些單點的存在將有助于出錯時排錯。
在考慮要不要消除某個單點,有些因素需要考慮:復(fù)制組件的成本,不同組件發(fā)生故障的概率,替換組件的時機以及修復(fù)組件時的擔(dān)當(dāng)?shù)娘L(fēng)險。比如你替換一個組件需要一周時間,在這一周期間,運行中的備用組件也有可能出現(xiàn)故障,這些你都必須要考慮到。
一旦確定要消除的單點,接下來就需要考慮如何建立冗余機制,有兩種方案可供選擇:1)為每一個組件建立一個備用組件,如果原始組件發(fā)生故障,立即啟用備用組件;2)系統(tǒng)本身有額外的容量,當(dāng)一個組件出現(xiàn)故障時仍能hold住。第一種方案,雖然看起來簡單,但是成本高。你必須讓備用組件處于standby狀態(tài),一直和主組件保持一致。其優(yōu)點就是在切換組件的時候不會損失性能,而且切換到standby組件所花的時間通常要比重新構(gòu)建組件快。方案二為系統(tǒng)構(gòu)建額外容量的方案可以讓你使用所有組件(資源)來運行系統(tǒng),這樣系統(tǒng)可以處理更高的瞬間峰值負載。但有一點必須明白,這種方案時,系統(tǒng)必須擁有額外的容量以保證在某些組件出現(xiàn)故障時系統(tǒng)仍然能hold住。有時候只為一個服務(wù)器發(fā)生故障留有余地還不夠,這個時候你需要權(quán)衡,以及這種情況出現(xiàn)的概率是多少。比如安裝了100臺服務(wù)器,其中一臺服務(wù)器發(fā)生故障的概率是1%,那么1臺,2臺,3臺服務(wù)器發(fā)生故障的概率會是多少呢?根據(jù)二項式定理計算可得到依次為100%,20.33%,16.17%。
?
應(yīng)急計劃(Contigency plans)
只做冗余還是不夠,當(dāng)你一個組件發(fā)生故障時,你還需要知道如何去應(yīng)對。在之前的例子里,當(dāng)Slave服務(wù)器出現(xiàn)故障時很容易去處理,因為只需把新的連接全部重定向到能工作的Slave服務(wù)器,同時你需要考慮:1)現(xiàn)有的連接怎么處理?僅僅中止程序并給用戶返回一個出錯信息明顯不是一個好主意。通常情況下,在用戶和數(shù)據(jù)庫之間有一個應(yīng)用層,這個時候應(yīng)該讓應(yīng)用層向別的服務(wù)器提交查詢;2)如果Master發(fā)生故障怎么處理?假設(shè)你已經(jīng)提供了一個額外的Master做冗余,你還必須提供機制讓所有Slave重定向新的Master。
下面介紹一下如何處理各種拓撲結(jié)構(gòu)下MySQL服務(wù)器宕機的技術(shù)。一般來說,需要考慮三種角色:Master,Slave,Relay。
- Slave故障:這是最簡單處理的故障。因為Slave僅僅是用于讀查詢,只需通知負載均衡器該Slave出故障,然后負載均衡器就會把新的請求都重定向到工作中的其他Slave。這就需要剩下的Slave能夠處理這些額外的負載。除了這之外,發(fā)生故障的Slave一般來說不會影響復(fù)制機制的拓撲結(jié)構(gòu),也就不用去考慮特殊的拓撲結(jié)構(gòu)以保證在Slave發(fā)生故障時易于管理。當(dāng)Slave發(fā)生故障時,對于已經(jīng)提交給該Slave并等待響應(yīng)的查詢,需要重新向工作的其他Slave提交查詢請求。
- Master故障:如果Master發(fā)生故障,就必須用備用的Master替換以保證部署的系統(tǒng)能正常運行,并且要快。當(dāng)Master發(fā)生故障時,所有的寫請求立即終止,因此首先要做的就是啟用新Master并把所有的寫請求重定位過去。因為主Master發(fā)生故障了,所有的Slave都失去了Master連接。這就意味著Slave上數(shù)據(jù)已不是最新的,雖然還能夠繼續(xù)響應(yīng)讀請求。盡管如此,如果有些請求需要監(jiān)聽到達Slave的變化,這些請求可能會被阻止,而有些請求或許把自己寫進Slave中繼日志,并最終由Slave執(zhí)行,這類請求就無需考慮。Master發(fā)生故障時,對于那些正在Master上等待某個事件的請求來說情況更加糟糕。對于這種情況,需要進行處理,一般來說就是用戶被通知請求失敗,然后需要重新發(fā)送請求。
- Relay故障:Relay服務(wù)器發(fā)生故障時需要進行一些特殊處理。如果Relay服務(wù)器發(fā)生故障,其他的Slave必須被重定向到其他的Relay服務(wù)器或者直接定向到Master。因為Relay服務(wù)器是用于緩解Master的負載,那么有可能出現(xiàn)Master無法處理Relay上的負載。
- 災(zāi)難恢復(fù):在高可用性的世界里,災(zāi)難并不意味著地震或者洪水,它只是表示服務(wù)器發(fā)生了極壞的狀況,并不是局部的狀況。比如說數(shù)據(jù)中心斷電了。災(zāi)難的本質(zhì)在于很多事情都同時出現(xiàn)故障,無法在一個數(shù)據(jù)中心通過備份服務(wù)器提供冗余解決問題。因此有必要要確保數(shù)據(jù)被保存在另外一個安全的地方。很多公司會把不同的組件放在不同的辦公室,即使公司相對較小的時候也這么干。
程序(Procedure)
如果你管理一個小站點,你可以不用規(guī)劃并手動管理這些服務(wù)器,但是隨著服務(wù)器數(shù)量的快速增長,自動化就變得很有必要。特別是下列的這些工作:
-
追加新Slave:追加新Slave的方法有很多。一般的步驟是先獲取現(xiàn)有一個服務(wù)器的快照,通常是一個Slave服務(wù)器,然后在新服務(wù)器上恢復(fù)快照,并在正確的位置開始復(fù)制。這個里需要注意的是獲取服務(wù)器快照這一步,因為這將直接決定你可以多長時間讓一個新Slave服務(wù)器上線。獲取快照的方法有以下幾種:
- 使用mysqldump:使用mysqldump安全但比較慢。這種方法允許你用與之前不同的存儲引擎去恢復(fù)數(shù)據(jù)。如果使用InnoDB表的話,還可以得到一致性快照,這也意味著你不需要脫機進行快照。
- 復(fù)制數(shù)據(jù)庫文件:這個相對來說要快一點,但是需要脫機。
- 使用在線備份方法:有不同的方法,比如InnoDB的熱備份(Hot Backup)
- 使用LVM獲取快照:在Linux系統(tǒng),可以使用Logical Volume Manager(LVM)來獲得卷快照。它要求你事先創(chuàng)建好特殊的LVM卷。
- 使用文件系統(tǒng)的快照方法:Solaris ZFS文件系統(tǒng)支持內(nèi)置快照,這種方法用于備份非常快。除了mysqldump以外,這些方法都不能使用一個不同的存儲引擎來重建數(shù)據(jù)。
- 刪除Slave:刪除Slave只需要通知負載均衡器該Slave不可使用即可。
- 切換Master:對于日常維護,將連在Master上的所有Slave切換到備份Master上,并通知負載均衡器該Master不可使用,是一件很平常的事。這個過程應(yīng)該可以無須宕機處理。這個可以通過Slave提升來完成,也可以采用更簡單的host standby來解決。
- 處理Slave故障:Slave會出現(xiàn)故障,這只是一個頻率問題。所以處理Slave故障在任何部署中都必須作為一個常規(guī)事件來對待。如果檢測到Slave不在,通知負載均衡器該Slave不可使用即可。
- 處理Master故障:當(dāng)Master突然出現(xiàn)故障時,你必須檢測到這個故障,并把所有的Slave都連到一個備用服務(wù)器上,或者把其中一個Slave提升為新Master。
- Slave升級:把Slave升級到一個新版本一般不會有問題,但會暫時不可使用,跟刪除Slave操作差不多。
- Master升級:為了升級Master,經(jīng)常有必要首先升級所有的Slave。但這也不一定。升級的時候,Master肯定不可用,這跟處理Master故障操作差不多。
?熱備份(Hot Standby)
最簡單的復(fù)制服務(wù)器的拓撲就是熱備份的拓撲。該拓撲結(jié)構(gòu)里面包括一個Master和一個被稱作熱備份的專用服務(wù)器。工作原理就是當(dāng)Master發(fā)生故障時,熱備份立即充當(dāng)Master的鏡像服務(wù)器,所有的客戶端和Slave服務(wù)器全部切換到熱備份服務(wù)器進行工作。不過切換的時候需要考慮一些細節(jié)的問題:1)當(dāng)切換到熱備份的服務(wù)器時,你需要重新定位需要從哪里開始復(fù)制二進制日志,一般熱備份的日志位置信息和Master不一樣;2)某個Slave可能需要的二進制日志在熱備份服務(wù)器上不一定有;3)當(dāng)修好的Master切換回來的時候,它上面的有些修改可能任何其他Slave都未來得及復(fù)制。
首先,問題簡單化,我們看看從Master切換到熱備份服務(wù)器的過程,該過程Master并不宕機。默認情況下,slave線程執(zhí)行的事件并不寫入二進制日志,但是作為熱備份的slave明顯是需要這些二進制日志的,所以為熱備份服務(wù)器增加這樣一個參數(shù)。
[mysqld]
log -slave-updates
切換時的主要問題在于,如何使得從熱備份服務(wù)器開始復(fù)制的位置和從Master停止復(fù)制的位置完全相同。有很多原因可以使得熱備服務(wù)器和Master服務(wù)器的二進制日志位置信息不一致,比如Master啟動的時候熱備份服務(wù)器并沒有連上,即使這個沒問題,也不能保證同一個事件寫入Master和熱備份服務(wù)器二進制日志的過程和時機完全一樣。
切換的基本思路是:確認讓slave和熱備份服務(wù)器在同一點上停止復(fù)制,然后讓salve連到熱備份服務(wù)器。
standby>SHOW SLAVE STATUS\G
...
Relay_Master_Log_File: master-bin. 000096
...
Exec_Master_Log_Pos: 756648
slave>SHOW SLAVE STATUS\G
...
Relay_Master_Log_File: master-bin. 000096
...
Exec_Master_Log_Pos: 743456
# 從上可知說明熱備份服務(wù)器的日志位置要領(lǐng)先于Slave,所以需要讓Slave從Master繼續(xù)復(fù)制到和熱備份一樣的位置
slave>START SLAVE UNTIL MASTER_LOG_FILE = ' master-bin.000096 ' MASTER_LOG_POS = 756648 ;
slave> SELECT MASTER_POS_WAIT( ' master-bin.000096 ' , 756648 );
# 現(xiàn)在Slave和熱備份服務(wù)器都在同一個點停止復(fù)制,就可以讓Slave連到熱備份服務(wù)器上,但是指定從哪個文件和位置開始復(fù)制呢。對于同一個復(fù)制點在Master上的文件和位置和熱備份上的文件和位置是不一樣的。
standby>SHOW MASTER STATUS\G
File: standby-bin. 000019
Position: 56447
Binlog_Do_DB:
Binlog_Ignore_DB:
slave>CHANGE MASTER TO
MASTER_HOST = ' standby-1 ' ,
MASTER_PORT = 3306 ,
MASTER_USER = ' repl_user ' ,
MASTER_PASSWORD = ' xyzzy ' ,
MASTER_LOG_FILE = ' standby-bin.000019 ' ,
MASTER_LOG_POS = 56447 ;
slave>START SLAVE;
如果Slave的復(fù)制位置在熱備份服務(wù)器之前的話,我們只需互換一下上面的步驟。下一節(jié)我們將考慮如何處理Master意外停止的情況。
雙Master(Dual Master)
雙Master拓撲結(jié)構(gòu)中,兩個Master互相復(fù)制數(shù)據(jù)以保持同步。因為是對稱的,這種設(shè)置容易使用。這種設(shè)置中,服務(wù)器可以是主動的(active),也可以是被動(passive)的。主動的服務(wù)器是指接受寫操作,然后這些變化通過復(fù)制傳播到其他Slave上。被動的服務(wù)器是指不接受寫而僅僅是跟隨主動Master,隨時準備切換。兩個服務(wù)器有兩種設(shè)置,一種是active-active,一種是active-passive,第二種很像熱備份的的拓撲,帶是由于是對稱,切換起來比較方便。在雙Master配置中,passive服務(wù)器并不一定要求接受讀請求,這個時候其實就是一個冷備份。在雙Master的拓撲中,并不一定非要通過復(fù)制來保證兩個Master的同步。
active-active型雙Master的常用的一個場景就是讓服務(wù)器在物理上接近不同的用戶組。用戶使用本地服務(wù)器,更改會被復(fù)制到另外一臺服務(wù)器來保持兩者同步。由于事務(wù)是在本地提交的,所以響應(yīng)比較快。但由于事務(wù)是本地提交的,兩個服務(wù)器并不是時時刻刻完全一致的。這就會有些問題:1)如果同一個信息在兩臺服務(wù)器上更新,將會服務(wù)器將會產(chǎn)生沖突,復(fù)制也會終止。你可以只讓其中一臺接受寫操作,可以在某種程度上避免沖突的發(fā)生。2)如果兩臺服務(wù)器在處于不一致狀態(tài)下發(fā)生故障,有些事務(wù)將會丟失,這也是異步復(fù)制的硬傷,不過你可以通過使用 半同步復(fù)制 (MySQL 5.5引入)來限制事務(wù)丟失的個數(shù)。
對于active-passive型的來說,你可能使用passive的Master來做服務(wù)器升級這樣的管理工作。active-passive有一個根本性的問題需要解決。split-brain syndrome:當(dāng)網(wǎng)絡(luò)連接短時間內(nèi)中斷,從而使得從服務(wù)器主動升級為主服務(wù)器,然后網(wǎng)絡(luò)又恢復(fù)了。如果在他們各自為主服務(wù)器的時間里,更改在兩臺服務(wù)器上都執(zhí)行就會產(chǎn)生沖突。當(dāng)使用共享磁盤的方式時,兩臺服務(wù)器同時寫磁盤會產(chǎn)生有趣的問題。
對于如何實現(xiàn)雙Master直接的同步,有幾種方案。
共享磁盤(Shared Disks)
?
?這是最直接的雙Master方案:兩個Master通過一個像SAN(Storage Area Network)的共享磁盤架構(gòu)連接在一起,并被設(shè)置成使用相同的文件。因為其中一個是passive,它不會寫任何東西到文件中,
使用DRBD復(fù)制磁盤(Replicated disks using DRBD)
?
雙向復(fù)制(bidirectional replication)
?
半同步復(fù)制(Semisynchronous Replication)
?
Slave提升(Slave Promotion)
?
?
?
?
?
?
?
?
?
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
