實現高可用性的原則很簡單:html
只要有單點故障(SPOF:Single Point of Failure)的存在,就沒法保證系統的高可用性(關於單點故障能夠參考Fenng的這篇文章,比較通俗易懂)。mysql
爲了搞清楚哪裏須要冗餘機制,咱們須要找到部署中全部潛在的單點。雖說起來簡單,可是須要一點想象力,以確保真正找到所有單點。交換機,路由器,網卡甚至電纜都是單點,除了這些,電源和物理設施也很重要。還有一些也爲成爲單點,好比只有一個員工知道如何處理某種類型的故障,全部的網絡都被集中到一個web頁面進行管理等。但定位到全部的單點並不意味着你必需要所有消除它們,由於有些單點或許由於經濟上,技術上或者地理上的緣由而沒法徹底消除,但知道這些單點的存在將有助於出錯時排錯。web
在考慮要不要消除某個單點,有些因素須要考慮:複製組件的成本,不一樣組件發生故障的機率,替換組件的時機以及修復組件時的擔當的風險。好比你替換一個組件須要一週時間,在這一週期間,運行中的備用組件也有可能出現故障,這些你都必需要考慮到。sql
一旦肯定要消除的單點,接下來就須要考慮如何創建冗餘機制,有兩種方案可供選擇:1)爲每個組件創建一個備用組件,若是原始組件發生故障,當即啓用備用組件;2)系統自己有額外的容量,當一個組件出現故障時仍能hold住。第一種方案,雖然看起來簡單,可是成本高。你必須讓備用組件處於standby狀態,一直和主組件保持一致。其優勢就是在切換組件的時候不會損失性能,並且切換到standby組件所花的時間一般要比從新構建組件快。方案二爲系統構建額外容量的方案可讓你使用全部組件(資源)來運行系統,這樣系統能夠處理更高的瞬間峯值負載。但有一點必須明白,這種方案時,系統必須擁有額外的容量以保證在某些組件出現故障時系統仍然能hold住。有時候只爲一個服務器發生故障留有餘地還不夠,這個時候你須要權衡,以及這種狀況出現的機率是多少。好比安裝了100臺服務器,其中一臺服務器發生故障的機率是1%,那麼1臺,2臺,3臺服務器發生故障的機率會是多少呢?根據二項式定理計算可獲得依次爲100%,20.33%,16.17%。數據庫
只作冗餘仍是不夠,當你一個組件發生故障時,你還須要知道如何去應對。在以前的例子裏,當Slave服務器出現故障時很容易去處理,由於只需把新的鏈接所有重定向到能工做的Slave服務器,同時你須要考慮:1)現有的鏈接怎麼處理?僅僅停止程序並給用戶返回一個出錯信息明顯不是一個好主意。一般狀況下,在用戶和數據庫之間有一個應用層,這個時候應該讓應用層向別的服務器提交查詢;2)若是Master發生故障怎麼處理?假設你已經提供了一個額外的Master作冗餘,你還必須提供機制讓全部Slave重定向新的Master。安全
下面介紹一下如何處理各類拓撲結構下MySQL服務器宕機的技術。通常來講,須要考慮三種角色:Master,Slave,Relay。服務器
若是你管理一個小站點,你能夠不用規劃並手動管理這些服務器,可是隨着服務器數量的快速增加,自動化就變得頗有必要。特別是下列的這些工做:網絡
最簡單的複製服務器的拓撲就是熱備份的拓撲。該拓撲結構裏面包括一個Master和一個被稱做熱備份的專用服務器。工做原理就是當Master發生故障時,熱備份當即充當Master的鏡像服務器,全部的客戶端和Slave服務器所有切換到熱備份服務器進行工做。不過切換的時候須要考慮一些細節的問題:1)當切換到熱備份的服務器時,你須要從新定位須要從哪裏開始複製二進制日誌,通常熱備份的日誌位置信息和Master不同;2)某個Slave可能須要的二進制日誌在熱備份服務器上不必定有;3)當修好的Master切換回來的時候,它上面的有些修改可能任何其餘Slave都將來得及複製。架構
首先,問題簡單化,咱們看看從Master切換到熱備份服務器的過程,該過程Master並不宕機。默認狀況下,slave線程執行的事件並不寫入二進制日誌,可是做爲熱備份的slave明顯是須要這些二進制日誌的,因此爲熱備份服務器增長這樣一個參數。負載均衡
[mysqld]
log-slave-updates
切換時的主要問題在於,如何使得從熱備份服務器開始複製的位置和從Master中止複製的位置徹底相同。有不少緣由可使得熱備服務器和Master服務器的二進制日誌位置信息不一致,好比Master啓動的時候熱備份服務器並無連上,即便這個沒問題,也不能保證同一個事件寫入Master和熱備份服務器二進制日誌的過程和時機徹底同樣。
切換的基本思路是:確認讓slave和熱備份服務器在同一點上中止複製,而後讓salve連到熱備份服務器。
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
# 從上可知說明熱備份服務器的日誌位置要領先於Slave,因此須要讓Slave從Master繼續複製到和熱備份同樣的位置
slave>START SLAVE UNTIL MASTER_LOG_FILE = 'master-bin.000096' MASTER_LOG_POS = 756648;
slave>SELECT MASTER_POS_WAIT('master-bin.000096', 756648);
# 如今Slave和熱備份服務器都在同一個點中止複製,就可讓Slave連到熱備份服務器上,可是指定從哪一個文件和位置開始複製呢。對於同一個複製點在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的複製位置在熱備份服務器以前的話,咱們只需互換一下上面的步驟。下一節咱們將考慮如何處理Master意外中止的狀況。
雙Master拓撲結構中,兩個Master互相複製數據以保持同步。由於是對稱的,這種設置容易使用。這種設置中,服務器能夠是主動的(active),也能夠是被動(passive)的。主動的服務器是指接受寫操做,而後這些變化經過複製傳播到其餘Slave上。被動的服務器是指不接受寫而僅僅是跟隨主動Master,隨時準備切換。兩個服務器有兩種設置,一種是active-active,一種是active-passive,第二種很像熱備份的的拓撲,帶是因爲是對稱,切換起來比較方便。在雙Master配置中,passive服務器並不必定要求接受讀請求,這個時候其實就是一個冷備份。在雙Master的拓撲中,並不必定非要經過複製來保證兩個Master的同步。
active-active型雙Master的經常使用的一個場景就是讓服務器在物理上接近不一樣的用戶組。用戶使用本地服務器,更改會被複制到另一臺服務器來保持二者同步。因爲事務是在本地提交的,因此響應比較快。但因爲事務是本地提交的,兩個服務器並非時時刻刻徹底一致的。這就會有些問題:1)若是同一個信息在兩臺服務器上更新,將會服務器將會產生衝突,複製也會終止。你能夠只讓其中一臺接受寫操做,能夠在某種程度上避免衝突的發生。2)若是兩臺服務器在處於不一致狀態下發生故障,有些事務將會丟失,這也是異步複製的硬傷,不過你能夠經過使用半同步複製(MySQL 5.5引入)來限制事務丟失的個數。
對於active-passive型的來講,你可能使用passive的Master來作服務器升級這樣的管理工做。active-passive有一個根本性的問題須要解決。split-brain syndrome:當網絡鏈接短期內中斷,從而使得從服務器主動升級爲主服務器,而後網絡又恢復了。若是在他們各自爲主服務器的時間裏,更改在兩臺服務器上都執行就會產生衝突。當使用共享磁盤的方式時,兩臺服務器同時寫磁盤會產生有趣的問題。
對於如何實現雙Master直接的同步,有幾種方案。
這是最直接的雙Master方案:兩個Master經過一個像SAN(Storage Area Network)的共享磁盤架構鏈接在一塊兒,並被設置成使用相同的文件。由於其中一個是passive,它不會寫任何東西到文件中,