MySQL的高可用性
本章將講述提到的復(fù)制、可擴(kuò)展性以及髙可用性三個(gè)主題中的第三個(gè)。歸根結(jié)底,高可用性實(shí)際上意味著“更少的宕機(jī)時(shí)間”。然而糟糕的是,高可用性經(jīng)常和其他相關(guān)的概念混淆,例如冗余、保障數(shù)據(jù)不丟失,以及負(fù)載均衡。我們希望另外的兩章已經(jīng)很清楚地理解高可用性做了足夠的鋪墊。跟其他兩章一樣,這一章也不僅僅是關(guān)注高可用性的內(nèi)容,一些相關(guān)的話(huà)題也會(huì)綜合闡述。
1.什么是高可用性
髙可用性實(shí)際上有點(diǎn)像神秘的野獸。它通常以百分比表示,這本身也是一種暗示:髙可用性不是絕對(duì)的,只有相對(duì)更髙的可用性。100%的可用性是不可能達(dá)到的。可用性的“9”規(guī)則是表示可用性目標(biāo)最普遍的方法。你可能也知道,“5個(gè)9”表示99.999%的正常可用時(shí)間。換句話(huà)說(shuō),每年只允許5分鐘的宕機(jī)時(shí)間。對(duì)于大多數(shù)應(yīng)用這已經(jīng)是令人驚嘆的數(shù)字,盡管還有一些人試圖獲得更多的“9”。
每個(gè)應(yīng)用對(duì)可用性的需求各不相同。在設(shè)定一個(gè)可用時(shí)間的目標(biāo)之前,先問(wèn)問(wèn)自己,是不是確實(shí)需要達(dá)到這個(gè)目標(biāo)。可用性每提高一點(diǎn),所花費(fèi)的成本都會(huì)遠(yuǎn)超之前;可用性的效果和開(kāi)銷(xiāo)的比例并不是線(xiàn)性的。需要保證多少可用時(shí)間,取決于能夠承擔(dān)多少成本。高可用性實(shí)際上是在宕機(jī)造成的損失與降低宕機(jī)時(shí)間所花費(fèi)的成本之間取一個(gè)平衡。換句話(huà)說(shuō),如果需要花大量金錢(qián)去獲得更好的可用時(shí)間,但所帶來(lái)的收益卻很低,可能就不值得去做。總的來(lái)說(shuō),應(yīng)用在超過(guò)一定的點(diǎn)以后追求更高的可用性是非常困難的,成本也會(huì)很高,因此我們建議設(shè)定一個(gè)更現(xiàn)實(shí)的目標(biāo)并且避免過(guò)度設(shè)計(jì)。幸運(yùn)的是,建立2個(gè)9或3個(gè)9的可用時(shí)間的目標(biāo)可能并不困難,具體情況取決于應(yīng)用。
有時(shí)候人們將可用性定義成服務(wù)正在運(yùn)行的時(shí)間段。我們認(rèn)為可用性的定義還應(yīng)該包括應(yīng)用是否能以足夠好的性能處理請(qǐng)求。有許多方法可以讓一個(gè)服務(wù)器保持運(yùn)行,但服務(wù)并不是真正可用。對(duì)一個(gè)很大的服務(wù)器而言,重啟MySQL之后,可能需要幾個(gè)小時(shí)才能充分預(yù)熱以保證査詢(xún)請(qǐng)求的響應(yīng)時(shí)間是可以接受的,即使服務(wù)器只接收了正常流量的一小部分也是如此。
另一個(gè)需要考慮的問(wèn)題是,即使應(yīng)用并沒(méi)有停止服務(wù),但是否可能丟失了數(shù)據(jù)。如果服務(wù)器遭遇災(zāi)難性故障,可能多少都會(huì)丟失一些數(shù)據(jù),例如最近已經(jīng)寫(xiě)入(最新丟失的)二進(jìn)制日志但尚未傳遞到備庫(kù)的中繼日志中的事務(wù)。你能夠容忍嗎?大多數(shù)應(yīng)用能夠容忍;因?yàn)樘娲桨复蠖喾浅0嘿F且復(fù)雜,或者有一些性能開(kāi)銷(xiāo)。例如,可以使用同步復(fù)制,或是將二進(jìn)制日志放到一個(gè)通過(guò)DRBD進(jìn)行復(fù)制的設(shè)備上,這樣就算服務(wù)器完全失效也不用擔(dān)心丟失數(shù)據(jù)。(但是整個(gè)數(shù)據(jù)中心也有可能會(huì)掉電。)
一個(gè)良好的應(yīng)用架構(gòu)通常可以降低可用性方面的需求,至少對(duì)部分系統(tǒng)而言是這樣的,良好的架構(gòu)也更容易做到高可用。將應(yīng)用中重要和不重要的部分進(jìn)行分離可以節(jié)約不少工作量和金錢(qián),因?yàn)閷?duì)于一個(gè)更小的系統(tǒng)改進(jìn)可用性會(huì)更容易。可以通過(guò)計(jì)算“風(fēng)險(xiǎn)敞口(riskexposure)”,將失效概率與失效代價(jià)相乘來(lái)確認(rèn)高優(yōu)先級(jí)的風(fēng)險(xiǎn)。畫(huà)一個(gè)簡(jiǎn)單的風(fēng)險(xiǎn)計(jì)算表,以概率、代價(jià)和風(fēng)險(xiǎn)敞口作為列,這樣很容易找到需要優(yōu)先處理的項(xiàng)目。
在<MySQL的可擴(kuò)展性>通過(guò)討論如何避免導(dǎo)致糟糕的可擴(kuò)展性的原因,來(lái)推出如何獲得更好的可擴(kuò)展性。這里也會(huì)使用相似的方法來(lái)討論可用性,因?yàn)橄嘈牛斫饪捎眯宰詈玫姆椒ň褪茄芯克姆疵妗礄C(jī)時(shí)間。接下來(lái)的小節(jié)會(huì)討論為什么會(huì)出現(xiàn)宕機(jī)。
2.導(dǎo)致宕機(jī)的原因
我們經(jīng)常聽(tīng)到導(dǎo)致數(shù)據(jù)庫(kù)宕機(jī)最主要的原因是編寫(xiě)的SQL査詢(xún)性能很差,真的是這樣嗎?2009年我們決定分析我們客戶(hù)的數(shù)據(jù)庫(kù)所遇到的問(wèn)題,以找出那些真正引起宕機(jī)的問(wèn)題,以及如何避免這些問(wèn)題。結(jié)果證實(shí)了一些我們已有的猜想,但也否定了一些(錯(cuò)誤的)認(rèn)識(shí),我們從中學(xué)到了很多。
我們首先對(duì)宕機(jī)事件按表現(xiàn)方式而非導(dǎo)致的原因進(jìn)行分類(lèi)。一般來(lái)說(shuō),“運(yùn)行環(huán)境”是排名第一的宕機(jī)類(lèi)別,大約35%的事件屬于這一類(lèi)。運(yùn)行環(huán)境可以看作是支持?jǐn)?shù)據(jù)庫(kù)服務(wù)器運(yùn)行的系統(tǒng)和資源集合,包括操作系統(tǒng)、硬盤(pán)以及網(wǎng)絡(luò)等。性能問(wèn)題緊隨其后,也是約占35% ;然后是復(fù)制,占20%;最后剩下的10%包含各種類(lèi)型的數(shù)據(jù)丟失或損壞,以及其他問(wèn)題。
我們對(duì)事件按類(lèi)型進(jìn)行分類(lèi)后,確定了導(dǎo)致這些事件的原因。以下是一些需要注意的地方:
在運(yùn)行環(huán)境的問(wèn)題中,最普遍的問(wèn)題是磁盤(pán)空間耗盡。
在性能問(wèn)題中,最普遍的宕機(jī)原因確實(shí)是運(yùn)行很糟糕的SQL,但也不一定都是這個(gè)原因,比如也有很多問(wèn)題是由于服務(wù)器Bug或錯(cuò)誤的行為導(dǎo)致的。
糟糕的Schema和索引設(shè)計(jì)是第二大影響性能的問(wèn)題。
復(fù)制問(wèn)題通常由于主備數(shù)據(jù)不一致導(dǎo)致。
數(shù)據(jù)丟失問(wèn)題通常由于DROPTABLE的誤操作導(dǎo)致,并總是伴隨著缺少可用備份的問(wèn)題。
復(fù)制雖然常被人們用來(lái)改善可用時(shí)間,但卻也可能導(dǎo)致宕機(jī)。這主要是由于不正確的使用導(dǎo)致的,即便如此,它也闡明了一個(gè)普遍的情況:許多高可用性策略可能會(huì)產(chǎn)生反作用,我們會(huì)在后面討論這個(gè)話(huà)題。
現(xiàn)在我們已經(jīng)知道了主要宕機(jī)類(lèi)別,以及有什么需要注意,下面我們將專(zhuān)門(mén)介紹如何獲得高可用性。
3.如何實(shí)現(xiàn)高可用性
可以通過(guò)同時(shí)進(jìn)行以下兩步來(lái)獲得高可用性。首先,可以嘗試避免導(dǎo)致宕機(jī)的原因來(lái)減少宕機(jī)時(shí)間。許多問(wèn)題其實(shí)很容易避免,例如通過(guò)適當(dāng)?shù)呐渲谩⒈O(jiān)控,以及規(guī)范或安全保障措施來(lái)避免人為錯(cuò)誤。第二,盡量保證在發(fā)生宕機(jī)時(shí)能夠快速恢復(fù)。最常見(jiàn)的策略是在系統(tǒng)中制造冗余,并且具備故障轉(zhuǎn)移能力。這兩個(gè)維度的髙可用性可以通過(guò)兩個(gè)相關(guān)的度量來(lái)確定:平均失效時(shí)間(MTBF)和平均恢復(fù)時(shí)間(MTTR)。一些組織會(huì)非常仔細(xì)地追蹤這些度量值。
第二步——通過(guò)冗余快速恢復(fù)——很不幸,這里是最應(yīng)該注意的地方,但預(yù)防措施的投資回報(bào)率會(huì)很髙。接下來(lái)我們來(lái)探討一些預(yù)防措施。
3.1 提升平均失效時(shí)間(MTBF)
其實(shí)只要盡職盡責(zé)地做好一些應(yīng)做的事情,就可以避免很多宕機(jī)。在分類(lèi)整理宕機(jī)事件并追查導(dǎo)致宕機(jī)的根源時(shí),我們還發(fā)現(xiàn),很多宕機(jī)本來(lái)是有一些方法可以避免的。我們發(fā)現(xiàn)大部分宕機(jī)事件都可以通過(guò)全面的常識(shí)性系統(tǒng)管理辦法來(lái)避免。以下是從我們的白皮書(shū)中摘錄的指導(dǎo)性建議,在白皮書(shū)中有我們?cè)敿?xì)的分析結(jié)果。
測(cè)試恢復(fù)工具和流程,包括從備份中恢復(fù)數(shù)據(jù)。
遵從最小權(quán)限原則。
保持系統(tǒng)干凈、整潔。
使用好的命名和組織約定來(lái)避免產(chǎn)生混亂,例如服務(wù)器是用于開(kāi)發(fā)還是用于生產(chǎn)環(huán)境。
謹(jǐn)慎安排升級(jí)數(shù)據(jù)庫(kù)服務(wù)器。
在升級(jí)前,使用諸如PerconaToolkit中的pt-upgrade之類(lèi)的工具仔細(xì)檢査系統(tǒng)。
使用InnoDB并進(jìn)行適當(dāng)?shù)呐渲茫_保InnoDB是默認(rèn)存儲(chǔ)引擎。如果存儲(chǔ)引擎被禁止,服務(wù)器就無(wú)法啟動(dòng)。
確認(rèn)基本的服務(wù)器配置是正確的。
通過(guò)skip_name_resolve禁止DNS。
除非能證明有效,否則禁用査詢(xún)緩存。
避免使用復(fù)雜的特性,例如復(fù)制過(guò)濾和觸發(fā)器,除非確實(shí)需要。
監(jiān)控重要的組件和功能,特別是像磁盤(pán)空間和RAID卷狀態(tài)這樣的關(guān)鍵項(xiàng)目,但也要避免誤報(bào),只有當(dāng)確實(shí)發(fā)生問(wèn)題時(shí)才發(fā)送告警。
盡量記錄服務(wù)器的狀態(tài)和性能指數(shù),如果可能就盡量久地保存。
定期檢查復(fù)制完整性。
將備庫(kù)設(shè)置為只讀,不要讓復(fù)制自動(dòng)啟動(dòng)。
定期進(jìn)行查詢(xún)語(yǔ)句審査。
歸檔并清理不需要的數(shù)據(jù)。
為文件系統(tǒng)保留一些空間。在GNU/Linux中,可以使用-m選項(xiàng)來(lái)為文件系統(tǒng)本身保留空間。還可以在LVM卷組中留下一些空閑空間。或者,更簡(jiǎn)單的方法,僅僅創(chuàng)建一個(gè)巨大的空文件,在文件系統(tǒng)快滿(mǎn)時(shí),直接將其刪除。
養(yǎng)成習(xí)慣,評(píng)估和管理系統(tǒng)的改變、狀態(tài)以及性能信息。
我們發(fā)現(xiàn)對(duì)系統(tǒng)變更管理的缺失是所有導(dǎo)致宕機(jī)的事件中最普遍的原因。典型的錯(cuò)誤包括粗心的升級(jí)導(dǎo)致升級(jí)失敗并遭遇一些Bug,或是尚未測(cè)試就將Schema或査詢(xún)語(yǔ)句的更改直接運(yùn)行到線(xiàn)上,或者沒(méi)有為一些失敗的情況制定計(jì)劃,例如達(dá)到了磁盤(pán)容量限制。另外一個(gè)導(dǎo)致問(wèn)題的主要原因是缺少?lài)?yán)格的評(píng)估,例如因?yàn)槭韬鰶](méi)有確認(rèn)備份是否是可以恢復(fù)的。最后,可能沒(méi)有正確地監(jiān)控MySQL的相關(guān)信息。例如緩存命中率報(bào)警并不能說(shuō)明出現(xiàn)問(wèn)題,并且可能產(chǎn)生大量的誤報(bào),這會(huì)使監(jiān)控系統(tǒng)被認(rèn)為不太有用,于是一些人就會(huì)忽略報(bào)警。有時(shí)候監(jiān)控系統(tǒng)失效了,甚至沒(méi)人會(huì)注意到,直至你的老板質(zhì)問(wèn)你,“為什么Nagios沒(méi)有告訴我們磁盤(pán)已經(jīng)滿(mǎn)了”。
3.2 降低平均恢復(fù)時(shí)間(MTTR)
之前提到,可以通過(guò)減少恢復(fù)時(shí)間來(lái)獲得高可用性。事實(shí)上,一些人走得更遠(yuǎn),只專(zhuān)注于減少恢復(fù)時(shí)間的某個(gè)方面:通過(guò)在系統(tǒng)中建立冗余來(lái)避免系統(tǒng)完全失效,并避免單點(diǎn)失效問(wèn)題。
在降低恢復(fù)時(shí)間上進(jìn)行投資非常重要,一個(gè)能夠提供冗余和故障轉(zhuǎn)移能力的系統(tǒng)架構(gòu),則是降低恢復(fù)時(shí)間的關(guān)鍵環(huán)節(jié)。但實(shí)現(xiàn)高可用性不單單是一個(gè)技術(shù)問(wèn)題,還有許多個(gè)人和組織的因素。組織和個(gè)人在避免宕機(jī)和從宕機(jī)事件中恢復(fù)的成熟度和能力層次各不相同。
團(tuán)隊(duì)成員是最重要的髙可用性資產(chǎn),所以為恢復(fù)制定一個(gè)好的流程非常重要。擁有熟練技能、應(yīng)變能力、訓(xùn)練有素的雇員,以及處理緊急事件的詳細(xì)文檔和經(jīng)過(guò)仔細(xì)測(cè)試的流程,對(duì)從宕機(jī)中恢復(fù)有巨大的作用。但也不能完全依賴(lài)工具和系統(tǒng),因?yàn)樗鼈儾⒉荒芾斫鈱?shí)際情況的細(xì)微差別,有時(shí)候它們的行為在一般情況下是正確的,但在某些場(chǎng)景下卻會(huì)是個(gè)災(zāi)難!
對(duì)宕機(jī)事件進(jìn)行評(píng)估有助于提升組織學(xué)習(xí)能力,可以幫助避免未來(lái)發(fā)生相似的錯(cuò)誤,但是不要對(duì)“事后反思”或“事后的調(diào)査分析”期待太髙。后見(jiàn)之明被嚴(yán)重曲解,并且一味想找到導(dǎo)致問(wèn)題的唯一根源,這可熊會(huì)影響你的判斷力。許多流行的方法,例如“五個(gè)為什么”,可能會(huì)被過(guò)度使用,導(dǎo)致一些人將他們的精力集中在找到唯一的替罪羊。很難去回顧我們解決的問(wèn)題當(dāng)時(shí)所處的狀況,也很難理解真正的原因,因?yàn)樵蛲ǔJ嵌喾矫娴摹R虼耍M管事后反思可能是有用的,但也應(yīng)該對(duì)結(jié)論有所保留。即使是我們給出的建議,也是基于長(zhǎng)期研究導(dǎo)致宕機(jī)事件的原因以及如何預(yù)防它們所得,并且只是我們的觀點(diǎn)而已。
這里我們要反復(fù)提醒:所有的宕機(jī)事件都是由多方面的失效聯(lián)合在一起導(dǎo)致的。因此,可以通過(guò)利用合適的方法確保單點(diǎn)的安全來(lái)避免。整個(gè)鏈條必須要打斷,而不僅僅是單個(gè)環(huán)節(jié)。例如,那些向我們求助恢復(fù)數(shù)據(jù)的人不僅遭受數(shù)據(jù)丟失(存儲(chǔ)失效,DBA誤操作等),同時(shí)還缺少一個(gè)可用的備份。
這樣說(shuō)來(lái),當(dāng)開(kāi)始調(diào)査并嘗試阻止失效或加速恢復(fù)時(shí),大多數(shù)人和組織不應(yīng)太過(guò)于內(nèi)疚,而是要專(zhuān)注于技術(shù)上的一些措施——特別是那些很酷的方法,例如集群系統(tǒng)和冗余架構(gòu)。這些是有用的,但要記住這些系統(tǒng)依然會(huì)失效。事實(shí)上,有一種MMM復(fù)制管理,雖然它被證明可能導(dǎo)致更多宕機(jī)時(shí)間。你應(yīng)該不會(huì)奇怪一組Perl腳本會(huì)陷于混亂,但即使是特別昂貴并精密設(shè)計(jì)的系統(tǒng)也會(huì)出現(xiàn)災(zāi)難性的失效——是的,即使是花費(fèi)了大量金錢(qián)的SAN也是如此。我們已經(jīng)見(jiàn)過(guò)太多的SAN失效。
4.避免單點(diǎn)失效
找到并消除系統(tǒng)中的可能失效的單點(diǎn),并結(jié)合切換到備用組件的機(jī)制,這是一種通過(guò)減少恢復(fù)時(shí)間(MTTR)來(lái)改善可用性的方法。如果你夠聰明,有時(shí)候甚至能將實(shí)際的恢復(fù)時(shí)間降低至0,但總的來(lái)說(shuō)這很困難。(即使一些非常引人注目的技術(shù),例如昂貴的負(fù)載均衡器,在發(fā)現(xiàn)問(wèn)題并進(jìn)行反饋時(shí)也會(huì)導(dǎo)致一定的延遲。)
思考并梳理整個(gè)應(yīng)用,嘗試去定位任何可能失效的單點(diǎn)。是一個(gè)硬盤(pán)驅(qū)動(dòng)器,一臺(tái)服務(wù)器,一臺(tái)交換或路由器,還是某個(gè)機(jī)架的電源?所有數(shù)據(jù)都在一個(gè)數(shù)據(jù)中心,或者冗余數(shù)據(jù)中心是由同一個(gè)公司提供的嗎?系統(tǒng)中任何不冗余的部分都是一個(gè)可能失效的單點(diǎn)。其他比較普遍的單點(diǎn)失效依賴(lài)于一些服務(wù),例如DNS、單一網(wǎng)絡(luò)提供商、單個(gè)云“可用區(qū)域”,以及單個(gè)電力輸送網(wǎng),具體有哪些取決于你的關(guān)注點(diǎn)。
單點(diǎn)失效并不總是能夠消除。增加冗余或許也無(wú)法做到,因?yàn)橛行┫拗茻o(wú)法避開(kāi),例如地理位置,預(yù)算,或者時(shí)間限制等。試著去理解每一個(gè)影響可用性的部分,采取一種平衡的觀點(diǎn)來(lái)看待風(fēng)險(xiǎn),并首先解決其中影響最大的那個(gè)。一些人試圖編寫(xiě)一個(gè)軟件來(lái)處理所有的硬件失效,但軟件本身導(dǎo)致的宕機(jī)時(shí)間可能比它節(jié)約的還要多。也有人想建立一種“永不沉沒(méi)”的系統(tǒng),包括各種冗余,但他們忘記了數(shù)據(jù)中心可能掉電或失去連接。或許他們徹底忘記了惡意攻擊者和程序錯(cuò)誤的可能性,這些情況可能會(huì)刪除或損壞數(shù)據(jù)--個(gè)不小心執(zhí)行的DROPTABLE也會(huì)產(chǎn)生宕機(jī)時(shí)間。
可以采用兩種方法來(lái)為系統(tǒng)增加冗余:增加空余容量和重復(fù)組件。增加容量余量通常很簡(jiǎn)單——可以使用本章或前一章討論的任何技術(shù)。一個(gè)提升可用性的方法是創(chuàng)建一個(gè)集群或服務(wù)器池,并使用負(fù)載均衡解決方案。如果一臺(tái)服務(wù)器失效,其他服務(wù)器可以接管它的負(fù)載。有些人有意識(shí)地不使用組件的全部能力,這樣可以保留一些“動(dòng)態(tài)余量”來(lái)處理因?yàn)樨?fù)載增加或組件失效導(dǎo)致的性能問(wèn)題。
出于很多方面的考慮會(huì)需要冗余組件,并在主要組件失效時(shí)能有一個(gè)備件來(lái)隨時(shí)替換。冗余組件可以是空閑的網(wǎng)卡、路由器或者硬盤(pán)驅(qū)動(dòng)器——任何能想到的可能失效的東西。完全冗余MySQL服務(wù)器可能有點(diǎn)困難,因?yàn)橐粋€(gè)服務(wù)器在沒(méi)有數(shù)據(jù)時(shí)毫無(wú)用處。這意味著你必須確保備用服務(wù)器能夠獲得主服務(wù)器上的數(shù)據(jù)。共享或復(fù)制存儲(chǔ)是一個(gè)比較流行的辦法,但這真的是一個(gè)高可用性架構(gòu)嗎?讓我們深入其中看看。
4.1 共享存儲(chǔ)或磁盤(pán)復(fù)制
共享存儲(chǔ)能夠?yàn)閿?shù)據(jù)庫(kù)服務(wù)器和存儲(chǔ)解耦合,通常使用的是SAN。使用共享存儲(chǔ)時(shí),服務(wù)器常掛載文件系統(tǒng)并進(jìn)行操作。如果服務(wù)器掛了,備用服務(wù)器可以?huà)燧d相同的文件系統(tǒng),執(zhí)行需要的恢復(fù)操作,并在失效服務(wù)器的數(shù)據(jù)上啟動(dòng)MySQL。這個(gè)過(guò)程在邏輯上跟修復(fù)那臺(tái)故障的服務(wù)器沒(méi)什么兩樣,不過(guò)更快速,因?yàn)閭溆梅?wù)器已經(jīng)啟動(dòng),隨時(shí)可以運(yùn)行。當(dāng)開(kāi)始故障轉(zhuǎn)移時(shí),檢査文件系統(tǒng)、恢復(fù)InnoDB以及預(yù)熱,最有可能遇到延遲的地方,但檢測(cè)失效本身在許多設(shè)置中也會(huì)花費(fèi)很長(zhǎng)時(shí)間。
共享存儲(chǔ)有兩個(gè)優(yōu)點(diǎn):可以避免除存儲(chǔ)外的其他任何組件失效所引起的數(shù)據(jù)丟失,并為非存儲(chǔ)組件建立冗余提供可能。因此它有助于減少系統(tǒng)一些部分的可用性需求,這樣就可以集中精力關(guān)注一小部分組件來(lái)獲得高可用性。不過(guò),共享存儲(chǔ)本身仍是可能失效的單點(diǎn)。如果共享存儲(chǔ)失效了,那整個(gè)系統(tǒng)也失效了,盡管SAN通常設(shè)計(jì)良好,但也可能失效,有時(shí)候需要特別關(guān)注。就算SAN本身?yè)碛腥哂嘁矔?huì)失效。
共享存儲(chǔ)本身也有風(fēng)險(xiǎn),如果MySQL崩潰等故障導(dǎo)致數(shù)據(jù)文件損壞,可能會(huì)導(dǎo)致備用服務(wù)器無(wú)法恢復(fù)。我們強(qiáng)烈建議在使用共享存儲(chǔ)策略時(shí)選擇Innodb存儲(chǔ)引擎或其他穩(wěn)定的ACID存儲(chǔ)引擎。一次崩潰幾乎肯定會(huì)損壞MyISAM表,需要花費(fèi)很長(zhǎng)時(shí)間來(lái)修復(fù),并且會(huì)丟失數(shù)據(jù)。我們也強(qiáng)烈建議使用日志型文件系統(tǒng)。我們見(jiàn)過(guò)比較嚴(yán)重的情況是,使用非日志型文件系統(tǒng)和SAN(這是文件系統(tǒng)的問(wèn)題,跟SAN無(wú)關(guān))導(dǎo)致數(shù)據(jù)損壞無(wú)法恢復(fù)。
磁盤(pán)復(fù)制技術(shù)是另外一個(gè)獲得跟SAN類(lèi)似效果的方法。MySQL中最普遍使用的磁盤(pán)復(fù)制技術(shù)是DRBD,并結(jié)合Linux-HA項(xiàng)目中的工具使用(后面會(huì)介紹到)。
DRBD是一個(gè)以L(fǎng)inux內(nèi)核模塊方式實(shí)現(xiàn)的塊級(jí)別同步復(fù)制技術(shù)。它通過(guò)網(wǎng)卡將主服務(wù)器的每個(gè)塊復(fù)制到另外一個(gè)服務(wù)器的塊設(shè)備上(備用設(shè)備),并在主設(shè)備提交塊之前記錄下來(lái)由于在備用DRBD設(shè)備上的寫(xiě)入必須要在主設(shè)備上的寫(xiě)入完成之前,因此備用設(shè)備的性能至少要和主設(shè)備一樣,否則就會(huì)限制主設(shè)備的寫(xiě)入性能。同樣,如果正在使用DRBD磁盤(pán)復(fù)制技術(shù)以保證在主設(shè)備失效時(shí)有一個(gè)可隨時(shí)替換的備用設(shè)備,備用服務(wù)器的硬件應(yīng)該跟主服務(wù)器的相匹配。帶電池寫(xiě)緩存的RAID控制器對(duì)DRBD而言幾乎是必需的,因?yàn)樵跊](méi)有這樣的控制器時(shí)性能可能會(huì)很差。
如果主服務(wù)器失效,可以把備用設(shè)備提升為主設(shè)備。因?yàn)镈RBD是在磁盤(pán)塊層進(jìn)行復(fù)制,而文件系統(tǒng)也可能會(huì)不一致。這意味著最好是使用日志型文件系統(tǒng)來(lái)做快速恢復(fù)。一旦設(shè)備恢復(fù)完成,MySQL還需要運(yùn)行自身的恢復(fù)。原故障服務(wù)器恢復(fù)后,會(huì)與新的主設(shè)備進(jìn)行同步,并假定自身角色為備用設(shè)備。
從如何實(shí)際地實(shí)現(xiàn)故障轉(zhuǎn)移的角度來(lái)看,DRBD和SAN很相似:有一個(gè)熱備機(jī)器,開(kāi)始提供服務(wù)時(shí)會(huì)使用和故障機(jī)器相同的數(shù)據(jù)。最大的不同是,DRBD是復(fù)制存儲(chǔ)——不是共享存儲(chǔ)——所以當(dāng)使用DRBD時(shí),獲得的是一份復(fù)制的數(shù)據(jù),而SAN則是使用與故障機(jī)器同一物理設(shè)備上的相同數(shù)據(jù)副本。換句話(huà)說(shuō),磁盤(pán)復(fù)制技術(shù)的數(shù)據(jù)是冗余的,所以存儲(chǔ)和數(shù)據(jù)本身都不會(huì)存在單點(diǎn)失效問(wèn)題。這兩種情況下,當(dāng)啟動(dòng)備用機(jī)器時(shí),MySQL服務(wù)器的緩存都是空的。相比之下,備庫(kù)的緩存至少是部分預(yù)熱的。
DRBD有一些很好的特性和功能,可以防止集群軟件普遍會(huì)遇到的一些問(wèn)題。一個(gè)典型 的例子是“腦裂綜合征”,在兩個(gè)節(jié)點(diǎn)同時(shí)提升自己為主服務(wù)器時(shí)會(huì)發(fā)生這種問(wèn)題。可以通過(guò)配置DRBD來(lái)防止這種事件發(fā)生。但是DRBD也不是一個(gè)能滿(mǎn)足所有需求的完美解決方案。我們來(lái)看看它有哪些缺點(diǎn):
DRBD的故障轉(zhuǎn)移無(wú)法做到秒級(jí)以?xún)?nèi)。它通常至少需要幾秒鐘時(shí)間來(lái)將備用設(shè)備提升成主設(shè)備,這還不包括任何必要的文件系統(tǒng)恢復(fù)和MySQL恢復(fù)。
它很昂貴,因?yàn)楸仨氃谥鲃?dòng)一被動(dòng)模式下運(yùn)行。熱備服務(wù)器的復(fù)制設(shè)備因?yàn)樘幱诒粍?dòng)模式,無(wú)法用于其他任務(wù)。當(dāng)然這是不是缺點(diǎn)取決于看問(wèn)題的角度。如果你希望獲得真正的髙可用性并且在發(fā)生故障時(shí)不能容忍服務(wù)降級(jí),就不應(yīng)該在一臺(tái)機(jī)器上運(yùn)行兩臺(tái)服務(wù)器的負(fù)載量,因?yàn)槿绻@么做了,當(dāng)其中一臺(tái)發(fā)生故障時(shí),就無(wú)法處理這些負(fù)載了。可以用這些備用服務(wù)器做一些其他用途,例如用作備庫(kù),但還是會(huì)有一些資源浪費(fèi)。
對(duì)于MyISAM表實(shí)際上用處不大,因?yàn)镸yISAM表崩潰后需要花費(fèi)很長(zhǎng)時(shí)間來(lái)檢査和修復(fù)。對(duì)任何期望獲得高可用性的系統(tǒng)而言,MyISAM都不是一個(gè)好選擇;請(qǐng)使用InnoDB或其他支持快速、安全恢復(fù)的存儲(chǔ)引擎來(lái)代替MyISAM。
DRBD無(wú)法代替?zhèn)浞荨H绻疟P(pán)由于蓄意的破壞、誤操作、Bug或者其他硬件故障導(dǎo)致數(shù)據(jù)損壞,DRBD將無(wú)濟(jì)于事。此時(shí)復(fù)制的數(shù)據(jù)只是被損壞數(shù)據(jù)的完美副本。你需要使用備份(或MySQL延時(shí)復(fù)制)來(lái)避免這些問(wèn)題。
對(duì)寫(xiě)操作而言增加了負(fù)擔(dān)。具體會(huì)增加多少負(fù)擔(dān)呢?通常可以使用百分比來(lái)表示,但這并不是一個(gè)好的度量方法。你需要理解寫(xiě)入時(shí)增加的延遲主要由網(wǎng)絡(luò)往返開(kāi)銷(xiāo)和遠(yuǎn)程服務(wù)器存儲(chǔ)導(dǎo)致,特別是對(duì)于小的寫(xiě)入而言延遲會(huì)更大。盡管增加的延遲可能也就0.3ms,這看起來(lái)比在本地磁盤(pán)上I/O的4?10ms的延遲要小很多,但卻是正常的帶有寫(xiě)緩存的RAID控制器的延遲的3?4倍=使用DRBD導(dǎo)致服務(wù)器變慢最常見(jiàn)的原因是MySQL使用InnoDB并采取了完全持久化模式,這會(huì)導(dǎo)致許多小的寫(xiě)入和fsync()調(diào)用,通過(guò)DRBD同步時(shí)會(huì)非常慢。
我們傾向于只使用DRBD復(fù)制存放二進(jìn)制日志的設(shè)備。如果主動(dòng)節(jié)點(diǎn)失效,可以在被動(dòng)節(jié)點(diǎn)上開(kāi)啟一個(gè)日志服務(wù)器,然后對(duì)失效主庫(kù)的所有備庫(kù)應(yīng)用這些二進(jìn)制日志。接下來(lái)可以選擇其中一個(gè)備庫(kù)提升為主庫(kù),以代替失效的系統(tǒng)。
說(shuō)到底,共享存儲(chǔ)和磁盤(pán)復(fù)制與其說(shuō)是高可用性(低宕機(jī)時(shí)間)解決方案,不如說(shuō)是一種保證數(shù)據(jù)安全的方法。只要擁有數(shù)據(jù),就可以從故障中恢復(fù),并且比無(wú)法恢復(fù)的情況的MTTR更低。(即使是很長(zhǎng)的恢復(fù)時(shí)間也比不能恢復(fù)要快。)但是相比于備用服務(wù)器啟動(dòng)并一直運(yùn)行的架構(gòu),大多數(shù)共享存儲(chǔ)或磁盤(pán)復(fù)制架構(gòu)會(huì)增加MTTR。有兩種啟用備用設(shè)備并運(yùn)行的方法:以及接下來(lái)會(huì)討論的同步復(fù)制。
討論:主動(dòng)一主動(dòng)訪(fǎng)問(wèn)模式的共享存儲(chǔ)怎么樣?
在一個(gè)SAN、NAS或者集群文件系統(tǒng)上以主動(dòng)一主動(dòng)模式運(yùn)行多個(gè)實(shí)例怎么樣?MySQL不能這么做。因?yàn)镸ySQL并沒(méi)有被設(shè)計(jì)成和其他MySQL實(shí)例同步對(duì)數(shù)據(jù)的訪(fǎng)問(wèn),所以無(wú)法在同一份數(shù)據(jù)上開(kāi)啟多個(gè)MySQL實(shí)例。(如果在一份只讀的靜態(tài)數(shù)據(jù)上使用MyISAM,技術(shù)上是可行的,但我們還沒(méi)有見(jiàn)過(guò)任何實(shí)際的應(yīng)用。)
MySQL的一個(gè)名為ScaleDB的存儲(chǔ)引擎在底層提供了操作共享存儲(chǔ)的API,但我們還沒(méi)有評(píng)估過(guò),也沒(méi)有見(jiàn)過(guò)任何生產(chǎn)環(huán)境使用。在mysql5.5發(fā)布時(shí)時(shí)它還是beta版。
4.2 MySQL同步復(fù)制
當(dāng)使用同步復(fù)制時(shí),主庫(kù)上的事務(wù)只有在至少一個(gè)備庫(kù)上提交后才能認(rèn)為其執(zhí)行完成。這實(shí)現(xiàn)了兩個(gè)目標(biāo):當(dāng)服務(wù)器崩潰時(shí)沒(méi)有提交的事務(wù)會(huì)丟失,并且至少有一個(gè)備庫(kù)擁有實(shí)時(shí)的數(shù)據(jù)副本。大多數(shù)同步復(fù)制架構(gòu)運(yùn)行在主動(dòng)-主動(dòng)模式。這意味著每個(gè)服務(wù)器在任何時(shí)候都是故障轉(zhuǎn)移的候選者,這使得通過(guò)冗余獲得高可用性更加容易。
1.MySQLCluster
MySQL中的同步復(fù)制首先出現(xiàn)在MySQLCluster(NDBCluster)。它在所有節(jié)點(diǎn)上進(jìn)行同步的主-主復(fù)制。這意味著可以在任何節(jié)點(diǎn)上寫(xiě)入;這些節(jié)點(diǎn)擁有等同的讀寫(xiě)能力。每一行都是冗余存儲(chǔ)的,這樣即使丟失了一個(gè)節(jié)點(diǎn),也不會(huì)丟失數(shù)據(jù),并且集群仍然能提供服務(wù)。盡管MySQLCluster還不是適用于所有應(yīng)用的完美解決方案,但正如我們?cè)谇耙徽绿岬降模谧罱陌姹局兴隽朔浅?焖俚母倪M(jìn),現(xiàn)在已經(jīng)擁有大量的新特性和功能:非索引數(shù)據(jù)的磁盤(pán)存儲(chǔ)、增加數(shù)據(jù)節(jié)點(diǎn)能夠在線(xiàn)擴(kuò)展、使用ndbinfo表來(lái)管理集群、配置和管理集群的腳本、多線(xiàn)程操作、下推(push-down)的關(guān)聯(lián)操作(現(xiàn)在稱(chēng)為自適應(yīng)查詢(xún)本地化)、能夠處理BLOB列和很多列的表、集中式的用戶(hù)管理,以及通過(guò)像memcached協(xié)議一樣的NDBAPI來(lái)實(shí)現(xiàn)NoSQL訪(fǎng)問(wèn)。在下一個(gè)版本中將包含最終一致運(yùn)行模式,包括為跨數(shù)據(jù)中心的主動(dòng)-主動(dòng)復(fù)制提供事務(wù)沖突檢測(cè)和跨WAN解決方案。簡(jiǎn)而言之,MySQLCluster是一項(xiàng)引人注目的技術(shù)。
現(xiàn)在至少有兩個(gè)為簡(jiǎn)化集群部署和管理提供附加產(chǎn)品的供應(yīng)商:Oracle針對(duì)MySQL Cluster的服務(wù)支持包含了MySQLClusterManager工具;Severalnines提供了ClusterControl工具,該工具還能夠幫助部署和管理復(fù)制集群。
2.PerconaXtraDBCluster
PerconaXtraDBCluster是一個(gè)相對(duì)比較新的技術(shù),基于已有的XtraDB(InnoDB)存儲(chǔ)
引擎增加了同步復(fù)制和集群特性,而不是通過(guò)一個(gè)新的存儲(chǔ)引擎或外部服務(wù)器來(lái)實(shí)現(xiàn)。它是基于Galera(支持在集群中跨節(jié)點(diǎn)復(fù)制寫(xiě)操作)實(shí)現(xiàn)的,這是一個(gè)在集群中不同節(jié)點(diǎn)復(fù)制寫(xiě)操作的庫(kù)。跟MySQLCluster類(lèi)似,PerconaXtraDBCluster提供同步多主庫(kù)復(fù)制,支持真正的任意節(jié)點(diǎn)寫(xiě)入能力,能夠在節(jié)點(diǎn)失效時(shí)保證數(shù)據(jù)零丟失(持久性,ACID中的D),另外還提供高可用性,在整個(gè)集群沒(méi)有失效的情況下,就算單個(gè)節(jié)點(diǎn)失效也沒(méi)有關(guān)系。
Galera作為底層技術(shù),使用一種被稱(chēng)為寫(xiě)入集合(write-set)復(fù)制的技術(shù)。寫(xiě)入集合實(shí)際上被作為基于行的二進(jìn)制日志事件進(jìn)行編碼,目的是在集群中的節(jié)點(diǎn)間傳輸并進(jìn)行更新,但是這不要求二進(jìn)制日志是打開(kāi)的。
PerconaXtraDBCluster的速度很快。跨節(jié)點(diǎn)復(fù)制實(shí)際上比沒(méi)有集群還要快,因?yàn)樵谕耆志眯阅J较拢瑢?xiě)入遠(yuǎn)程RAM比寫(xiě)入本地磁盤(pán)要快。如果你愿意,可以選擇通過(guò)降低每個(gè)節(jié)點(diǎn)的持久性來(lái)獲得更好的性能,并且可以依賴(lài)于多個(gè)節(jié)點(diǎn)上的數(shù)據(jù)副本來(lái)獲得持久性。NDB也是基于同樣的原理實(shí)現(xiàn)的。集群在整體上的持久性并沒(méi)有降低;僅僅是降低了本地節(jié)點(diǎn)的持久性。除此之外,還支持行級(jí)別的并發(fā)(多線(xiàn)程)復(fù)制,這樣就可以利用多個(gè)CPU核心來(lái)執(zhí)行寫(xiě)入集合。這些特性結(jié)合起來(lái)使得PerconaXtraDBCluster非常適合云計(jì)算環(huán)境,因?yàn)樵朴?jì)算環(huán)境中的CPU和磁盤(pán)通常比較慢。
在集群中通過(guò)設(shè)置auto_increment_offset和auto_increment_increment來(lái)實(shí)現(xiàn)自增鍵,以使節(jié)點(diǎn)間不會(huì)生成沖突的主鍵值。鎖機(jī)制和標(biāo)準(zhǔn)InnoDB完全相同,使用的是樂(lè)觀并發(fā)控制。當(dāng)事務(wù)提交時(shí),所有的更新是序列化的,并在節(jié)點(diǎn)間傳輸,同時(shí)還有一個(gè)檢測(cè)過(guò)程,以保證一旦發(fā)生更新沖突,其中一些更新操作需要丟棄。這樣如果許多節(jié)點(diǎn)同時(shí)修改同樣的數(shù)據(jù),可能產(chǎn)生大量的死鎖和回滾。
PerconaXtraDBCluster只要集群內(nèi)在線(xiàn)的節(jié)點(diǎn)數(shù)不少于“法定人數(shù)(quorum)”就能保證服務(wù)的高可用性。如果發(fā)現(xiàn)某個(gè)節(jié)點(diǎn)不屬于“法定人數(shù)”中的一員,就會(huì)從集群中將其踢出。被踢出的節(jié)點(diǎn)在再次加入集群前必須重新同步。因此集群也無(wú)法處理“腦裂綜合征”;如果出現(xiàn)腦裂則集群會(huì)停止服務(wù)。在一個(gè)只有兩個(gè)節(jié)點(diǎn)的集群中,如果其中一個(gè)節(jié)點(diǎn)失效,剩下的一個(gè)節(jié)點(diǎn)達(dá)不到“法定人數(shù)”,集群將停止服務(wù),所以實(shí)際上最少需要三個(gè)節(jié)點(diǎn)才能實(shí)現(xiàn)高可用的集群。
PerconaXtraDBCluster有許多優(yōu)點(diǎn):
提供了基于InnoDB的透明集群,所以無(wú)須轉(zhuǎn)換到另外的技術(shù),例如NDB這樣完全不同的技術(shù)需要很多學(xué)習(xí)成本和管理。
提供了真正的高可用性,所有節(jié)點(diǎn)等效,并在任何時(shí)候提供讀寫(xiě)服務(wù)。相比較而言,MySQL內(nèi)建的異步復(fù)制和半同步復(fù)制必須要有一個(gè)主庫(kù),并且不能保證數(shù)據(jù)被復(fù)制到備庫(kù),也無(wú)法保證備庫(kù)數(shù)據(jù)是最新的并能夠隨時(shí)提升為主庫(kù)。
節(jié)點(diǎn)失軟時(shí)保證數(shù)據(jù)不丟失。實(shí)際上,由于所有的節(jié)點(diǎn)都擁有全部數(shù)據(jù),因此可以丟失任意一個(gè)節(jié)點(diǎn)而不會(huì)丟失數(shù)據(jù)(即使集群出現(xiàn)腦裂并停止工作)。這和NDB不同,NDB通過(guò)節(jié)點(diǎn)組進(jìn)行分區(qū),當(dāng)在一個(gè)節(jié)點(diǎn)組中的所有服務(wù)器失效時(shí)就可能丟失數(shù)據(jù)。
備庫(kù)不會(huì)延遲,因?yàn)樵谑聞?wù)提交前,寫(xiě)入集合已經(jīng)在集群的所有節(jié)點(diǎn)上傳播并被確認(rèn)了。
因?yàn)槭鞘褂没谛械娜罩臼录趥鋷?kù)上進(jìn)行更新,所以執(zhí)行寫(xiě)入集合比直接執(zhí)行更新的開(kāi)銷(xiāo)要小很多,就和使用基于行的復(fù)制差不多。當(dāng)結(jié)合多線(xiàn)程應(yīng)用的寫(xiě)入集合時(shí),可以使其比MySQL本身的復(fù)制更具備可擴(kuò)展性。
當(dāng)然我們也需要提及Percona
XtraDB Cluster的一些缺點(diǎn):
它很新,因此還沒(méi)有足夠的經(jīng)驗(yàn)來(lái)證明其優(yōu)點(diǎn)和缺點(diǎn),也缺乏合適的使用案例。
整個(gè)集群的寫(xiě)入速度由最差的節(jié)點(diǎn)決定。因此所有的節(jié)點(diǎn)最好擁有相同的硬件配置,如果一個(gè)節(jié)點(diǎn)慢下來(lái)(例如,RAID卡做了一次battery-learn循環(huán)),所有的節(jié)點(diǎn)都會(huì)慢下來(lái)。如果一個(gè)節(jié)點(diǎn)接收寫(xiě)入操作變慢的可能性為P,那么有3個(gè)節(jié)點(diǎn)的集群變慢的可能性為3P。
沒(méi)有NDB那樣節(jié)省空間,因?yàn)槊總€(gè)節(jié)點(diǎn)都需要保存全部數(shù)據(jù),而不是僅僅一部分。但另一方面,它基于Percona XtraDB (InnoDB的增強(qiáng)版本),也就沒(méi)有NDB關(guān)于磁盤(pán)數(shù)據(jù)限制的擔(dān)憂(yōu)。
當(dāng)前不支持一些在異步復(fù)制中可以做的操作,例如在備庫(kù)上離線(xiàn)修改schema,然后將其提升為主庫(kù),然后在其他節(jié)點(diǎn)上重復(fù)離線(xiàn)修改操作。當(dāng)前可替代的選擇是使用諸如PerconaToolkit中的在線(xiàn)schema修改工具。不過(guò)滾動(dòng)式schema升級(jí)(rollingschemaupgrade)也發(fā)布。
當(dāng)向集群中增加一個(gè)新節(jié)點(diǎn)時(shí),需要復(fù)制所有的數(shù)據(jù),還需要跟上不斷進(jìn)行的寫(xiě)入操作,所以一個(gè)擁有大量寫(xiě)入的大型集群很難進(jìn)行擴(kuò)容。這實(shí)際上限制了集群的數(shù)據(jù)大小。我們無(wú)法確定具體的數(shù)據(jù)。但悲觀地估計(jì)可能低至100GB或更小,也可能會(huì)大得多。這一點(diǎn)需要時(shí)間和經(jīng)驗(yàn)來(lái)證明。
復(fù)制協(xié)議在寫(xiě)入時(shí)對(duì)網(wǎng)絡(luò)波動(dòng)比較敏感,這可能導(dǎo)致節(jié)點(diǎn)停止并從集群中踢出。所以我們推薦使用高性能網(wǎng)絡(luò),另外還需要很好的冗余。如果沒(méi)有可靠的網(wǎng)絡(luò),可能會(huì)導(dǎo)致需要頻繁地將節(jié)點(diǎn)加入到集群中。這需要重新同步數(shù)據(jù)。有一個(gè)幾乎接近可用的特性,即通過(guò)增量狀態(tài)傳輸來(lái)避免完全復(fù)制數(shù)據(jù)集,因此未來(lái)這并不是一個(gè)問(wèn)題。還可以配置Galera以容忍更大的網(wǎng)絡(luò)延遲(以延遲故障檢測(cè)為代價(jià)),另外更加可靠的算法也計(jì)劃在未來(lái)的版本中實(shí)現(xiàn)。
如果沒(méi)有仔細(xì)關(guān)注,集群可能會(huì)增長(zhǎng)得太大,以至于無(wú)法重啟失效節(jié)點(diǎn),就像在一個(gè)合理的時(shí)間范圍內(nèi),如果在日常工作中沒(méi)有定期做恢復(fù)演練,備份也會(huì)變得太過(guò)龐大而無(wú)法用于恢復(fù)。我們需要更多的實(shí)踐經(jīng)驗(yàn)來(lái)了解它事實(shí)上是如何工作的。
由于在事務(wù)提交時(shí)需要進(jìn)行跨節(jié)點(diǎn)通信,寫(xiě)入會(huì)更慢,隨著集群中增加的節(jié)點(diǎn)越來(lái)越多,死鎖和回滾也會(huì)更加頻繁。(參閱前一章了解為什么會(huì)發(fā)生這種情況。)
Percona XtraDB
Cluster和Galera都處于其生命周期的早期,正在被快速地修改和改進(jìn)。在mysql5.5發(fā)布時(shí),正在進(jìn)行或即將進(jìn)行的改進(jìn)包括群體行為、安全性、同步性、內(nèi)存管理、狀態(tài)轉(zhuǎn)移等。未來(lái)還可以為離線(xiàn)節(jié)點(diǎn)執(zhí)行諸如滾動(dòng)式schema變更的操作。
4.3 基于復(fù)制的冗余
復(fù)制管理器是使用標(biāo)準(zhǔn)MySQL復(fù)制來(lái)創(chuàng)建冗余的工具。盡管可以通過(guò)復(fù)制來(lái)改善可用性,但也有一些“玻璃天花板”會(huì)阻止MySQL當(dāng)前版本的異步復(fù)制和半同步復(fù)制獲得和真正的同步復(fù)制相同的結(jié)果。復(fù)制無(wú)法保證實(shí)時(shí)的故障轉(zhuǎn)移和數(shù)據(jù)零丟失,也無(wú)法將所有節(jié)點(diǎn)等同對(duì)待。
復(fù)制管理器通常監(jiān)控和管理三件事:應(yīng)用和MySQL間的通信、MySQL服務(wù)器的健康度,以及MySQL服務(wù)器間的復(fù)制關(guān)系。它們既可以修改負(fù)載均衡的配置,也可以在必要的時(shí)候轉(zhuǎn)移虛擬IP地址以使應(yīng)用連接到合適的服務(wù)器上,還能夠在一個(gè)偽集群中操縱復(fù)制以選擇一個(gè)服務(wù)器作為寫(xiě)入節(jié)點(diǎn)。大體上操作并不復(fù)雜:只需要確定寫(xiě)入不會(huì)發(fā)送到一個(gè)還沒(méi)有準(zhǔn)備好提供寫(xiě)服務(wù)的服務(wù)器上,并保證當(dāng)需要提升一臺(tái)備庫(kù)為主庫(kù)時(shí)記錄下正確的復(fù)制坐標(biāo)。
這聽(tīng)起來(lái)在理論上是可行的,但我們的經(jīng)驗(yàn)表明實(shí)際上并不總是能有效工作。事實(shí)上這非常糟糕,有些時(shí)候最好有一些輕量級(jí)的工具集來(lái)幫助從常見(jiàn)的故障中恢復(fù)并以很少的開(kāi)銷(xiāo)獲得較髙的可用性。不幸的是,在mysql5.5時(shí)還沒(méi)有聽(tīng)說(shuō)任何一個(gè)好的工具集可以可靠地完成這一點(diǎn)。稍后我們會(huì)介紹兩個(gè)復(fù)制管理器,其中一個(gè)很新,而另外一個(gè)則有很多問(wèn)題。
我們發(fā)現(xiàn)很多人試圖去寫(xiě)自己的復(fù)制管理器。他們常常會(huì)陷入很多人已經(jīng)遭遇過(guò)的陷阱。自己去寫(xiě)一個(gè)復(fù)制管理器并不是好主意。異步組件有大量的故障形式,很多你從未親身經(jīng)歷過(guò),其中一些甚至無(wú)法理解,并且程序也無(wú)法適當(dāng)處理,因此從這些異步組件中得到正確的行為相當(dāng)困難,并且可能遭遇數(shù)據(jù)丟失的危險(xiǎn)。事實(shí)上,機(jī)器剛開(kāi)始出現(xiàn)問(wèn)題時(shí),由一個(gè)經(jīng)驗(yàn)豐富的人來(lái)解決是很快的,但如果其他人做了一些錯(cuò)誤的修復(fù)操作則可能導(dǎo)致問(wèn)題更嚴(yán)重。
我們要提到的第一個(gè)復(fù)制管理器是MMM,本書(shū)的作者對(duì)于該工具集是否適用于生產(chǎn)環(huán)境部署的意見(jiàn)并不一致(盡管該工具的原作者也承認(rèn)它并不可靠)。我們中有些人認(rèn)為它在一些人工一故障轉(zhuǎn)移模式下的場(chǎng)景中比較有用,而有些人甚至從不便用這個(gè)工具。我們的許多客戶(hù)在自動(dòng)一故障轉(zhuǎn)移模式下使用該工具時(shí)確實(shí)遇到了許多嚴(yán)重的問(wèn)題。它會(huì)導(dǎo)致健康的服務(wù)器離線(xiàn),也可能將寫(xiě)入發(fā)送到錯(cuò)誤的地點(diǎn),并將備庫(kù)移動(dòng)到錯(cuò)誤的坐標(biāo)。有時(shí)混亂就接踵而至。
另外一個(gè)比較新一點(diǎn)的工具是YoshinoriMatsunobu的MHA工具集。它和MMM—樣是一組腳本,使用相同的通用技術(shù)來(lái)建立一個(gè)偽集群,但它不是一個(gè)完全的替換者,它不會(huì)去做太多的事情,并且依賴(lài)干Pacemaker來(lái)轉(zhuǎn)移虛擬IP地址。一個(gè)主要的不同是,MHA有一個(gè)很好的測(cè)試集,可以防止一些MMM遇到過(guò)的問(wèn)題。除此之外,我們對(duì)該工具集還沒(méi)有更多的認(rèn)識(shí),我們只和Yoshinori討論過(guò),但還沒(méi)有真正使用過(guò)。
基于復(fù)制的冗余最終來(lái)說(shuō)好壞參半。只有在可用性的重要性遠(yuǎn)比一致性或數(shù)據(jù)零丟失保
證更重要時(shí)才推薦使用。例如,一些人并不會(huì)真的從他們的網(wǎng)站功能中獲利,而是從它的可用性中賺錢(qián)。誰(shuí)會(huì)在乎是否出現(xiàn)了故障導(dǎo)致一張照片丟失了幾條評(píng)論或其他什么東西呢?只要廣告收益繼續(xù)滾滾而來(lái),可能并不值得花更多成本去實(shí)現(xiàn)真正的高可用性。但還是可以通過(guò)復(fù)制來(lái)建立“盡可能的”高可用性,當(dāng)遇到一些很難處理的嚴(yán)重宕機(jī)時(shí)可能會(huì)有所幫助。這是一個(gè)大賭注,并且可能對(duì)大多數(shù)人而言太過(guò)于冒險(xiǎn),除非是那些老成(或者專(zhuān)業(yè))的用戶(hù)。
問(wèn)題是許多用戶(hù)不知道如何去證明自己有資格并評(píng)估復(fù)制“輪盤(pán)賭”是否適合他們。這
有兩個(gè)方面的原因。第一,他們并沒(méi)有看到“玻璃天花板”,錯(cuò)誤地認(rèn)為一組虛擬IP地址、復(fù)制以及管理腳本能夠?qū)崿F(xiàn)真正的髙可用性。第二,他們低估了技術(shù)的復(fù)雜度,因此也低估了嚴(yán)重故障發(fā)生后從中恢復(fù)的難度。一些人認(rèn)為他們能夠使用基于復(fù)制的冗余技術(shù),但隨后他們可能會(huì)更希望選擇一個(gè)有更強(qiáng)保障的簡(jiǎn)單系統(tǒng)。
其他一些類(lèi)型的復(fù)制,例如DRBD或者SAN,也有它們的缺點(diǎn)——請(qǐng)不要認(rèn)為我們將這些技術(shù)說(shuō)得無(wú)所不能而把MySQL自身的復(fù)制貶得一團(tuán)糟,那不是我們的本意。你可以為DRBD寫(xiě)出低質(zhì)量的故障轉(zhuǎn)移腳本,這很簡(jiǎn)單,就像為MySQL復(fù)制編寫(xiě)腳本一樣。主要的區(qū)別是MySQL復(fù)制非常復(fù)雜,有很多非常細(xì)小的差別,并且不會(huì)阻止你干壞事。
5.故障轉(zhuǎn)移和故障恢復(fù)
冗余是很好的技術(shù),但實(shí)際上只有在遇到故障需要恢復(fù)時(shí)才會(huì)用到。(見(jiàn)鬼,這可以用備份來(lái)實(shí)現(xiàn))。冗余一點(diǎn)兒也不會(huì)增加可用性或減少宕機(jī)。在故障轉(zhuǎn)移的過(guò)程中,高可用性是建立在冗余的基礎(chǔ)上。當(dāng)有一個(gè)組件失效,但存在冗余時(shí),可以停止使用發(fā)生故障的組件,而使用冗余備件。冗余和故障轉(zhuǎn)移結(jié)合可以幫助更快地恢復(fù),如你所知,MTTR的減少將降低宕機(jī)時(shí)間并改善可用性。
在繼續(xù)這個(gè)話(huà)題之前,我們先來(lái)定義一些術(shù)語(yǔ)。我們統(tǒng)一使用“故障轉(zhuǎn)移(failover)”,有些人使用“回退”(fallback)表達(dá)同一意思。有時(shí)候也有人說(shuō)“切換(switchover)”,以表明一次計(jì)劃中的切換而不是故障后的應(yīng)對(duì)措施。我們也會(huì)使用“故障恢復(fù)”來(lái)表示故障轉(zhuǎn)移的反面。如果系統(tǒng)擁有故障恢復(fù)能力,故障轉(zhuǎn)移就是一個(gè)雙向過(guò)程:當(dāng)服務(wù)器A失效,服務(wù)器B代替它,在修復(fù)服務(wù)器A后可以再替換回來(lái)。
故障轉(zhuǎn)移比僅僅從故障中恢復(fù)更好。也可以針對(duì)一些情況制訂故障轉(zhuǎn)移計(jì)劃,例如升級(jí)、schema變更、應(yīng)用修改,或者定期維護(hù),當(dāng)發(fā)生故障時(shí)可以根據(jù)計(jì)劃進(jìn)行故障轉(zhuǎn)移來(lái)減少宏機(jī)時(shí)間(改善可用性)。
你需要確定故障轉(zhuǎn)移到底需要多快,也要知道在一次故障轉(zhuǎn)移后替換一個(gè)失效組件應(yīng)該多快。在你恢復(fù)系統(tǒng)耗盡的備件容量之前,會(huì)出現(xiàn)冗余不足,并面臨額外風(fēng)險(xiǎn)。因此,擁有一個(gè)備件并不能消除即時(shí)替換失效組件的需求。構(gòu)建一個(gè)新的備用服務(wù)器,安裝操作系統(tǒng),并復(fù)制數(shù)據(jù)的最新副本,可以多快呢?有足夠的備用機(jī)器嗎?你可能需要不止一臺(tái)以上。
故障轉(zhuǎn)移的緣由各不相同。我們已經(jīng)討論了其中的一些,因?yàn)樨?fù)載均衡和故障轉(zhuǎn)移在很多方面很相似,它們之間的分界線(xiàn)比較模糊。總的來(lái)說(shuō),我們認(rèn)為一個(gè)完全的故障轉(zhuǎn)移解決方案至少能夠監(jiān)控并自動(dòng)替換組件。它對(duì)應(yīng)用應(yīng)該是透明的。負(fù)載均衡不需要提供這些功能。
在UNIX領(lǐng)域,故障轉(zhuǎn)移常常使用HighAvailabilityLinux項(xiàng)目提供的工具來(lái)完成,該項(xiàng)目可在許多類(lèi)UNIX系統(tǒng)上運(yùn)行,而不僅僅是Linux。Linux-HA棧在最近幾年明顯多了很多新特性。現(xiàn)在大多數(shù)人認(rèn)為Pacemaker是棧中的一個(gè)主要組件。Pacemaker替代了老的心跳工具。還有其他一些工具實(shí)現(xiàn)了IP托管和負(fù)載均衡功能。可以將它們跟DRBD和/或者LVS結(jié)合起來(lái)使用。
故障轉(zhuǎn)移最重要的部分就是故障恢復(fù)。如果服務(wù)器間不能自如切換,故障轉(zhuǎn)移就是一個(gè)死胡同,只能是延緩宕機(jī)時(shí)間而已。這也是我們傾向于對(duì)稱(chēng)復(fù)制布局,例如雙主配置,而不會(huì)選擇使用三臺(tái)或更多的聯(lián)合主庫(kù)(co-master)來(lái)進(jìn)行環(huán)形復(fù)制的原因。如果配置是對(duì)等的,故障轉(zhuǎn)移和故障恢復(fù)就是在相反方向上的相同操作。(值得一提的是DRBD具有內(nèi)建的故障恢復(fù)功能。)
在一些應(yīng)用中,故障轉(zhuǎn)移和故障恢復(fù)需要盡量快速并具備原子性。即便這不是決定性的,不依靠那些不受你控制的東西也依然是個(gè)好主意,例如DNS變更或者應(yīng)用程序配置文件。一些問(wèn)題直到系統(tǒng)變得更加龐大時(shí)才會(huì)顯現(xiàn)出來(lái),例如當(dāng)應(yīng)用程序強(qiáng)制重啟以及原子性需求出現(xiàn)時(shí)。
由于負(fù)載均衡和故障轉(zhuǎn)移兩者聯(lián)系較緊密,有些硬件和軟件是同時(shí)為這兩個(gè)目的設(shè)計(jì)的,因此我們建議所選擇的任何負(fù)載均衡技術(shù)應(yīng)該都提供故障轉(zhuǎn)移功能。這也是我們建議避免使用DNS和修改代碼來(lái)做負(fù)載均衡的真實(shí)原因。如果為負(fù)載均衡采用了這些策略,就需要做一些額外的工作:當(dāng)需要高可用性時(shí),不得不重寫(xiě)受影響的代碼。
以下小節(jié)討論了一些比較普遍的故障轉(zhuǎn)移技術(shù)。可以手動(dòng)執(zhí)行或使用工具來(lái)實(shí)現(xiàn)。
5.1 提升備庫(kù)或切換角色
提升一臺(tái)備庫(kù)為主庫(kù),或者在一個(gè)主一主復(fù)制結(jié)構(gòu)中調(diào)換主動(dòng)和被動(dòng)角色,這些都是許多MySQL故障轉(zhuǎn)移策略很重要的一部分。正如本章之前提到的,我們不能認(rèn)定自動(dòng)化工具總能在所有的情況下做正確的事情——或者至少以我們的名譽(yù)擔(dān)保沒(méi)有這樣的工具。
你不應(yīng)該假定在發(fā)生故障時(shí)能夠立刻切換到被動(dòng)備庫(kù),這要看具體的工作負(fù)載。備庫(kù)會(huì)重放主庫(kù)的寫(xiě)入,但如果不用來(lái)提供讀操作,就無(wú)法進(jìn)行預(yù)熱來(lái)為生產(chǎn)環(huán)境負(fù)載提供服務(wù)。如果希望有一個(gè)隨時(shí)能承擔(dān)讀負(fù)載的備庫(kù),就要不斷地“訓(xùn)練”它,既可以將其用于分擔(dān)工作負(fù)載,也可以將生產(chǎn)環(huán)境的讀査詢(xún)鏡像到備庫(kù)上。我們有時(shí)候通過(guò)監(jiān)聽(tīng)TCP流量,截取出其中的SELECT査詢(xún),然后在備庫(kù)上重放來(lái)實(shí)現(xiàn)這個(gè)目的。PerconaToolkit中有一些工具可以做到這一點(diǎn)。
5.2 虛擬IP地址或IP接管
可以為需要提供特定服務(wù)的MySQL實(shí)例指定一個(gè)邏輯IP地址。當(dāng)MySQL實(shí)例失效時(shí),可以將IP地址轉(zhuǎn)移到另一臺(tái)MySQL服務(wù)器上。這和我們?cè)谇耙徽绿岬降乃枷氡举|(zhì)上是相同的,唯一的不同是現(xiàn)在是用于故障轉(zhuǎn)移,而不是負(fù)載均衡。
這種方法的好處是對(duì)應(yīng)用透明。它會(huì)中斷已有的連接,但不要求修改配置。有時(shí)候還可以原子地轉(zhuǎn)移IP地址,保證所有的應(yīng)用在同一時(shí)間看到這一變更。當(dāng)服務(wù)器在可用和不可用狀態(tài)間“搖擺”時(shí),這一點(diǎn)尤其重要。
以下是它的一些不足之處:
需要把所有的IP地址定義在同一網(wǎng)段,或者使用網(wǎng)絡(luò)橋接。
改變IP地址需要系統(tǒng)root權(quán)限。
有時(shí)候還需要更新ARP緩存。有些網(wǎng)絡(luò)設(shè)備可能會(huì)把ARP信息保存太久,以致無(wú)法即時(shí)將一個(gè)IP地址切換到另一個(gè)MAC地址上。我們看到過(guò)很多網(wǎng)絡(luò)設(shè)備或其他組件不配合切換的例子,結(jié)果系統(tǒng)的許多部分可能無(wú)法確定IP地址到底在哪里。
需要確定網(wǎng)絡(luò)硬件支持快速I(mǎi)P接管。有些硬件需要克隆MAC地址后才能工作。
有些服務(wù)器即使完全喪失功能也會(huì)保持持有IP地址,所以可能需要從物理上關(guān)閉或斷開(kāi)網(wǎng)絡(luò)連接。這就是為人所熟知的“擊中其他節(jié)點(diǎn)的頭部”(shoottheothernodeinthehead,簡(jiǎn)稱(chēng)STONITH)。它還有一個(gè)更加微妙并且比較官方的名字:擊劍(fencing) 。
浮動(dòng)IP地址和IP接管能夠很好地應(yīng)付彼此臨近(也就是在同一子網(wǎng)內(nèi))的機(jī)器之間的故障轉(zhuǎn)移。但是最后需要提醒的是,這種策略并不總是萬(wàn)無(wú)一失,還取決于網(wǎng)絡(luò)硬件等因素。
討論:等待更新擴(kuò)散
經(jīng)常有這種情況,在某一層定義了一個(gè)冗余后,需要等待低層執(zhí)行一些改變。在本章前面的篇幅里,我們指出通過(guò)DNS修改服務(wù)器是一個(gè)很脆弱的解決方案,因?yàn)镈NS的更新擴(kuò)散速度很慢,改變IP地址可給予你更多的控制,但在一個(gè)LAN中的IP地址同樣依賴(lài)于更低層——ARP——來(lái)擴(kuò)散更新。
5.3 中間件解決方案
可以使用代理、端口轉(zhuǎn)發(fā)、網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)或者硬件負(fù)載均衡來(lái)實(shí)現(xiàn)故障轉(zhuǎn)移和故障恢復(fù)。這些都是很好的解決方案,不像其他方法可能會(huì)引入一些不確定性(所有系統(tǒng)組件認(rèn)同哪一個(gè)是主庫(kù)嗎?它能夠及時(shí)并原子地更改嗎?),它們是控制應(yīng)用和服務(wù)器間連接的中樞。但是,它們自身也引入了單點(diǎn)失效,需要準(zhǔn)備冗余來(lái)避免這個(gè)問(wèn)題。
使用這樣的解決方案,你可以將一個(gè)遠(yuǎn)程數(shù)據(jù)中心設(shè)置成看起來(lái)好像和應(yīng)用在同一個(gè)網(wǎng)絡(luò)里。這樣就可以使用諸如浮動(dòng)IP地址這樣的技術(shù)讓?xiě)?yīng)用和一個(gè)完全不同的數(shù)據(jù)中心開(kāi)始通信。你可以配置每個(gè)數(shù)據(jù)中心的每臺(tái)應(yīng)用服務(wù)器,通過(guò)它自己的中間件連接,將流量路由到活躍數(shù)據(jù)中心的機(jī)器上。圖12-1描述了這種配置。
如果活躍數(shù)據(jù)中心安裝的MySQL徹底崩潰了,中間件可以路由流量到另外一個(gè)數(shù)據(jù)中心的服務(wù)器池中,應(yīng)用無(wú)須知道這個(gè)變化。
這種配置方法的主要缺點(diǎn)是在一個(gè)數(shù)據(jù)中心的Apache服務(wù)器和另外一個(gè)數(shù)據(jù)中心的MySQL服務(wù)器之間的延遲比較大。為了緩和這個(gè)問(wèn)題,可以把Web服務(wù)器設(shè)置為重定向模式。這樣通信都會(huì)被重定向到放置活躍MySQL服務(wù)器的數(shù)據(jù)中心。還可以使用HTTP代理來(lái)實(shí)現(xiàn)這一目標(biāo)。
圖12-1顯示了如何使用代理來(lái)連接MySQL服務(wù)器,也可以將這個(gè)方法和許多別的中間件架構(gòu)結(jié)合在一起,例如LVS和硬件負(fù)載均衡器。
5.4 在應(yīng)用中處理故障轉(zhuǎn)移
有時(shí)候讓?xiě)?yīng)用來(lái)處理故障轉(zhuǎn)移會(huì)更簡(jiǎn)單或者更加靈潔。例如,如果應(yīng)用遇到一個(gè)錯(cuò)誤,這個(gè)錯(cuò)誤外部觀察者正常情況下是無(wú)法察覺(jué)的,例如關(guān)于數(shù)據(jù)庫(kù)損壞的錯(cuò)誤日志信息,那么應(yīng)用可以自己來(lái)處理故障轉(zhuǎn)移過(guò)程。
雖然把故障轉(zhuǎn)移處理過(guò)程整合到應(yīng)用中看起來(lái)比較吸引人,但可能沒(méi)有想象中那么有效。大多數(shù)應(yīng)用有許多組件,例如cron任務(wù)、配置文件,以及用不同語(yǔ)言編寫(xiě)的腳本。將故障轉(zhuǎn)移整合到應(yīng)用中可能導(dǎo)致應(yīng)用變得太過(guò)笨拙,尤其是當(dāng)應(yīng)用增大并變得更加復(fù)雜時(shí)。
但是將監(jiān)控構(gòu)建到應(yīng)用中是一個(gè)好主意,當(dāng)需要時(shí),能夠立刻開(kāi)始故障轉(zhuǎn)移過(guò)程。應(yīng)用應(yīng)該也能夠管理用戶(hù)體驗(yàn),例如提供降級(jí)功能,并顯示給用戶(hù)合適的信息。
6.總結(jié)
可以通過(guò)減少宕機(jī)來(lái)獲得高可用性,這需要從以下兩個(gè)方面來(lái)思考:增加兩次故障之間的正常運(yùn)行時(shí)間(MTBF),或者減少?gòu)墓收现谢謴?fù)的時(shí)間(MTTR)。
要增加兩次故障之間的正常運(yùn)行時(shí)間,就要嘗試去防止故障發(fā)生。悲劇的是,在預(yù)防故障發(fā)生時(shí),它仍然會(huì)覺(jué)得你做的不夠多,所以預(yù)防故障的努力經(jīng)常會(huì)被忽視掉。我們已經(jīng)著重提到了如何在MySQL系統(tǒng)中預(yù)防宕機(jī);具體的細(xì)節(jié)可以參閱我們的白皮書(shū),從上可以獲得。試著從宏機(jī)中獲得經(jīng)驗(yàn)教訓(xùn),但也要謹(jǐn)防在故障根源分析和事后檢驗(yàn)時(shí)集中在某一點(diǎn)上而忽略其他因素。
縮短恢復(fù)時(shí)間可能更復(fù)雜并且代價(jià)很髙。從簡(jiǎn)單和容易的方面來(lái)說(shuō),可以通過(guò)監(jiān)控來(lái)更快地發(fā)現(xiàn)問(wèn)題,并記錄大量的度量值以幫助診斷問(wèn)題。作為回報(bào),有時(shí)候可以在發(fā)生宕機(jī)前就發(fā)現(xiàn)問(wèn)題。監(jiān)控并有選擇地報(bào)警以避免無(wú)用的信息,但也要及時(shí)記錄狀態(tài)和性能度量值。
另外一個(gè)減少恢復(fù)時(shí)間的策略是為系統(tǒng)建立冗余,并使系統(tǒng)具備故障轉(zhuǎn)移能力,這樣當(dāng)故障發(fā)生時(shí),可以在冗余組件間進(jìn)行切換。不幸的是,冗余會(huì)讓系統(tǒng)變得相當(dāng)復(fù)雜。現(xiàn)在應(yīng)用不再是集中化的,而是分布式的,這意味著協(xié)調(diào)、同步、CAP定理、拜占庭將軍問(wèn)題,以及所有其他各種雜亂的東西。這也是像NDBCluster這樣的系統(tǒng)很難創(chuàng)建并且很難提供足夠的通用性來(lái)為所有的工作負(fù)載提供服務(wù)的原因。
本章和前面兩章提及的話(huà)題常常被放在一起討論:復(fù)制、可擴(kuò)展性,以及高可用性。我們已經(jīng)盡量將它們獨(dú)立開(kāi)來(lái),因?yàn)檫@有助于理清這些話(huà)題的不同之處。那么這三章有哪些關(guān)聯(lián)之處呢?
在其應(yīng)用增長(zhǎng)時(shí),人們一般希望從他們的數(shù)據(jù)庫(kù)中知道三件事:
他們希望能夠增加容量來(lái)處理新增的負(fù)載而不會(huì)損失性能。
他們希望保證不丟失已提交的事務(wù)。
他們希望應(yīng)用能一直在線(xiàn)并處理事務(wù),這樣他們就能夠一直賺錢(qián)。
為了達(dá)到這些目的,人們常常首先增加冗余。結(jié)合故障轉(zhuǎn)移機(jī)制,通過(guò)最小化MTTR來(lái)提供高可用性。這些冗余還提供了空閑容量,可以為更多的負(fù)載提供服務(wù)。
當(dāng)然,除了必要的資源外,還必須要有一份數(shù)據(jù)副本。這有助于在損失服務(wù)器時(shí)避免丟失數(shù)據(jù),從而增強(qiáng)持久性。生成數(shù)據(jù)副本的唯一辦法是通過(guò)某種方法進(jìn)行復(fù)制。不幸的是,數(shù)據(jù)副本可能會(huì)引入不一致。處理這個(gè)問(wèn)題需要在節(jié)點(diǎn)間協(xié)調(diào)和通信。這給系統(tǒng)帶來(lái)了額外的負(fù)擔(dān);這也是系統(tǒng)或多或少存在擴(kuò)展性問(wèn)題的原因。
數(shù)據(jù)副本還需要更多的資源(例如更多的硬盤(pán)驅(qū)動(dòng)器,更多的RAM),這會(huì)增加開(kāi)銷(xiāo)。有一個(gè)辦法可以減少資源消耗和維護(hù)一致性的開(kāi)銷(xiāo),就是為數(shù)據(jù)分區(qū)(分片)并將每個(gè)分片分發(fā)到特定的系統(tǒng)中。這可以減少需要復(fù)制的重復(fù)數(shù)據(jù)的次數(shù),并從資源冗余中分離數(shù)據(jù)冗余。
所以,盡管一件事總會(huì)導(dǎo)致另外一件事,但我們是在討論一組相關(guān)的觀點(diǎn)和實(shí)踐來(lái)達(dá)成一系列目的。他們不僅僅是講述同一件事的不同方式。
最后,需要選擇一個(gè)對(duì)你和應(yīng)用有意義的策略。決定選擇一個(gè)完全的端到端(end-to-end)髙可用性策略并不能通過(guò)簡(jiǎn)單的經(jīng)驗(yàn)法則來(lái)處理,但我們給出的一些粗略的指引也許會(huì)有所幫助。
為了獲得很短的宕機(jī)時(shí)間,需要冗余服務(wù)器能夠及時(shí)地接管應(yīng)用的工作負(fù)載。它們必須在線(xiàn)并一直執(zhí)行查詢(xún),而不僅僅是備用,因此它們是“預(yù)熱”過(guò)的,處于隨時(shí)可用的狀態(tài)。
如果需要很強(qiáng)的可用性保證,就需要諸如MySQLCluster、PerconaXtraDBCluster,或者Clustrix這樣的集群產(chǎn)品。如果能容忍在故障轉(zhuǎn)移過(guò)程中稍微慢一些,標(biāo)準(zhǔn)的MySQL復(fù)制也是個(gè)很好的選擇。要謹(jǐn)慎使用自動(dòng)化故障轉(zhuǎn)移機(jī)制;如果沒(méi)有按照正確的方式工作,它們可能會(huì)破壞數(shù)據(jù)。
如果不是很在意故障轉(zhuǎn)移花費(fèi)的時(shí)間,但希望避免數(shù)據(jù)丟失,就需要一些強(qiáng)力保證數(shù)據(jù)
的冗余——例如,同步復(fù)制。在存儲(chǔ)層,這可以通過(guò)廉價(jià)的DRBD來(lái)實(shí)現(xiàn),或者使用兩個(gè)昂貴的SAN來(lái)進(jìn)行同步復(fù)制。也可以選擇在數(shù)據(jù)庫(kù)層復(fù)制數(shù)據(jù),可以使用的技術(shù)包括MySQLCluster、PerconaXtraDBCluster或者Clustrix。也可以使用一些中間件,例如TungstenReplicator。如果不需要強(qiáng)有力的保護(hù),并且希望盡量保證簡(jiǎn)單,那么正常的異步復(fù)制或半同步復(fù)制在開(kāi)銷(xiāo)合理時(shí)可能是很好的選擇。
或者也可以將應(yīng)用放到云中。為什么不呢?這樣難道不是能夠立刻獲得髙可用性和無(wú)限擴(kuò)展能力嗎?云廠商過(guò)多,這里就不做討論。
作者:小家電維修
出處:https://www.cnblogs.com/lizexiong/
轉(zhuǎn)世燕還故榻,為你銜來(lái)二月的花。
?
總結(jié)
以上是生活随笔為你收集整理的MySQL的高可用性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 关于web性能一些特性汇总
- 下一篇: EasyUI--messager