我們一起聊聊復(fù)雜度來(lái)源:高可用
高可用性定義為系統(tǒng)持續(xù)不間斷地執(zhí)行其功能的能力,是衡量系統(tǒng)可用性的重要指標(biāo)之一。這一概念的核心在于實(shí)現(xiàn)“無(wú)中斷”運(yùn)行,但這正是其實(shí)現(xiàn)過(guò)程中的主要挑戰(zhàn)。由于無(wú)論硬件還是軟件都難以避免出現(xiàn)故障——硬件可能會(huì)遭遇故障和老化,軟件可能存在bug且隨著時(shí)間推移變得更加復(fù)雜和龐大。此外,外部因素如斷電、自然災(zāi)害等也可能導(dǎo)致系統(tǒng)服務(wù)中斷,這些因素往往不可預(yù)測(cè)且難以控制。
因此,實(shí)現(xiàn)系統(tǒng)的高可用性通常依賴于“冗余”的概念。簡(jiǎn)而言之,如果一臺(tái)服務(wù)器不足以保障服務(wù)的持續(xù)性,那么就使用兩臺(tái),如果兩臺(tái)還不夠,那么就增加到四臺(tái),以此類推。對(duì)于可能出現(xiàn)的斷電情況,可以在多個(gè)地理位置部署服務(wù)器。如果擔(dān)心網(wǎng)絡(luò)通道的不穩(wěn)定,可以同時(shí)使用多個(gè)網(wǎng)絡(luò)服務(wù)提供商。雖然從表面上看,無(wú)論是為了提升性能還是實(shí)現(xiàn)高可用性,解決方案似乎都是增加更多的機(jī)器,但二者的目的完全不同:提升性能的目的是“擴(kuò)展”系統(tǒng)的處理能力,而實(shí)現(xiàn)高可用性的目的則是通過(guò)增加“冗余”單元來(lái)確保服務(wù)的連續(xù)性和穩(wěn)定性。
計(jì)算高可用
這里的“計(jì)算”指的是業(yè)務(wù)的邏輯處理。計(jì)算有一個(gè)特點(diǎn)就是無(wú)論在哪臺(tái)機(jī)器上進(jìn)行計(jì)算,同樣的算法和輸入數(shù)據(jù),產(chǎn)出的結(jié)果都是一樣的,所以將計(jì)算從一臺(tái)機(jī)器遷移到另外一臺(tái)機(jī)器,對(duì)業(yè)務(wù)并沒有什么影響。既然如此,計(jì)算高可用的復(fù)雜度體現(xiàn)在哪里呢?我以最簡(jiǎn)單的單機(jī)變雙機(jī)為例進(jìn)行分析。先來(lái)看一個(gè)單機(jī)變雙機(jī)的簡(jiǎn)單架構(gòu)示意圖:
圖片
你可能會(huì)注意到,提到的雙機(jī)架構(gòu)與我們之前在“高性能”主題中討論的架構(gòu)非常相似,因此它們的復(fù)雜性也有所類似。具體來(lái)說(shuō):
盡管上述討論的只是一個(gè)基礎(chǔ)的雙機(jī)架構(gòu),我們還可以進(jìn)一步探討更為復(fù)雜的高可用集群架構(gòu)。與簡(jiǎn)單的雙機(jī)設(shè)置相比,高可用集群在分配算法上更為復(fù)雜,配置形式包括但不限于1主3備、2主2備、3主1備、到4主0備等不同組合。選擇哪種配置方案,需根據(jù)實(shí)際業(yè)務(wù)需求進(jìn)行分析和判斷,因?yàn)椴]有一種算法能夠絕對(duì)勝出。例如,ZooKeeper就采用了1主多備的模式,而Memcached則是采用了全主0備的策略。
存儲(chǔ)高可用
在設(shè)計(jì)需要數(shù)據(jù)存儲(chǔ)的系統(tǒng)時(shí),確保存儲(chǔ)的高可用性成為整個(gè)系統(tǒng)設(shè)計(jì)的關(guān)鍵和挑戰(zhàn)所在。與計(jì)算任務(wù)不同,存儲(chǔ)任務(wù)的一個(gè)基本區(qū)別在于數(shù)據(jù)需要通過(guò)網(wǎng)絡(luò)線路從一臺(tái)機(jī)器傳輸?shù)搅硪慌_(tái)機(jī)器。這種傳輸?shù)乃俣仁艿轿锢硐拗?,即便是在同一個(gè)機(jī)房?jī)?nèi),傳輸速度也可能只有幾毫秒,而跨越不同地域的機(jī)房,傳輸延時(shí)則可能增至數(shù)十甚至上百毫秒。例如,從廣州到北京的機(jī)房之間,穩(wěn)定時(shí)的網(wǎng)絡(luò)延遲大約是50毫秒,但在不穩(wěn)定的網(wǎng)絡(luò)環(huán)境下,延遲可能會(huì)增加到1秒甚至更長(zhǎng)。
為了解決這一問(wèn)題,系統(tǒng)設(shè)計(jì)中通常會(huì)加入任務(wù)分配器,其選擇依賴于多種因素,包括性能、成本、可維護(hù)性和可用性等。任務(wù)分配器不僅需要處理與業(yè)務(wù)服務(wù)器之間的連接和交互,還需選取適宜的連接方式,并妥善管理這些連接,如連接的建立、檢測(cè)和斷開后的處理策略。
此外,任務(wù)分配器還需配備高效的分配算法,如主備、雙主等模式,其中主備模式又可以細(xì)分為冷備、溫備和熱備等。盡管對(duì)于人類來(lái)說(shuō),毫秒級(jí)的時(shí)間差異幾乎感覺不到,但對(duì)于追求高可用的系統(tǒng)而言,這種時(shí)間差意味著數(shù)據(jù)的瞬時(shí)不一致性,這對(duì)系統(tǒng)的整體業(yè)務(wù)有著根本性的影響。
舉個(gè)例子,銀行儲(chǔ)蓄業(yè)務(wù)中,如果客戶在北京機(jī)房存入金額,而此時(shí)數(shù)據(jù)尚未同步至上海機(jī)房,當(dāng)客戶查詢余額時(shí)可能會(huì)發(fā)現(xiàn)新存入的金額未能顯示,造成用戶疑慮,這種體驗(yàn)對(duì)客戶而言極為不佳。他們可能會(huì)擔(dān)心自己的資金安全,甚至可能導(dǎo)致客戶投訴或報(bào)警。即使最終確認(rèn)問(wèn)題僅因?yàn)閿?shù)據(jù)同步的延遲,對(duì)用戶而言,這段經(jīng)歷的體驗(yàn)仍是負(fù)面的。
圖片
除了物理傳輸速度的限制,網(wǎng)絡(luò)線路的可靠性也是一個(gè)重要考慮因素。線路可能會(huì)遇到中斷、擁堵或異常情況(如數(shù)據(jù)錯(cuò)誤、丟失),并且這些問(wèn)題的修復(fù)時(shí)間可能長(zhǎng)達(dá)數(shù)小時(shí)。以往的事故中,如2015年支付寶因光纜被挖斷而業(yè)務(wù)受影響超過(guò)4小時(shí),2016年中美之間的海底光纜斷裂導(dǎo)致通訊中斷3小時(shí),都是典型例子。這些線路問(wèn)題意味著數(shù)據(jù)同步可能會(huì)被暫時(shí)中斷,從而導(dǎo)致系統(tǒng)在一段時(shí)間內(nèi)數(shù)據(jù)不一致。
從更廣的視角來(lái)看,不論是在正常情況下的傳輸延遲,還是異常狀況下的傳輸中斷,都可能導(dǎo)致系統(tǒng)在某一時(shí)間點(diǎn)或時(shí)間段內(nèi)數(shù)據(jù)不一致,進(jìn)而引發(fā)業(yè)務(wù)問(wèn)題。然而,如果不進(jìn)行數(shù)據(jù)的冗余備份,又無(wú)法保證系統(tǒng)的高可用性。因此,設(shè)計(jì)存儲(chǔ)高可用系統(tǒng)的挑戰(zhàn)不在于數(shù)據(jù)的備份本身,而在于如何減少或規(guī)避數(shù)據(jù)不一致對(duì)業(yè)務(wù)的影響。
在分布式系統(tǒng)領(lǐng)域,有一個(gè)著名的CAP定理,理論上證明了存儲(chǔ)高可用的復(fù)雜性。CAP定理指出,一個(gè)分布式系統(tǒng)不可能同時(shí)滿足一致性(Consistency)、可用性(Availability)和分區(qū)容錯(cuò)性(Partition tolerance)這三個(gè)需求,最多只能滿足其中兩項(xiàng)。這就意味著在架構(gòu)設(shè)計(jì)時(shí),需要根據(jù)業(yè)務(wù)需求做出相應(yīng)的權(quán)衡和選擇。
高可用狀態(tài)決策
無(wú)論是實(shí)現(xiàn)計(jì)算的高可用還是存儲(chǔ)的高可用,其核心都在于“狀態(tài)決策”——系統(tǒng)必須能夠識(shí)別當(dāng)前狀態(tài)是正常還是有故障的,并且在檢測(cè)到故障時(shí)采取措施以保持高可用。然而,如果狀態(tài)的決策過(guò)程存在誤差或錯(cuò)誤,那么接下來(lái)的所有優(yōu)化措施都將失去效果和價(jià)值。在實(shí)際操作中,存在一個(gè)根本的挑戰(zhàn):依賴冗余機(jī)制來(lái)提高系統(tǒng)可用性的同時(shí),幾乎無(wú)法實(shí)現(xiàn)絕對(duì)準(zhǔn)確的狀態(tài)決策。接下來(lái),我們將通過(guò)分析幾種常用的決策方法來(lái)深入探討這一問(wèn)題。
1.獨(dú)裁式
在討論如何確保計(jì)算和存儲(chǔ)的高可用性時(shí),我們不得不關(guān)注“狀態(tài)決策”的重要性——即系統(tǒng)能否正確判斷其當(dāng)前狀態(tài)為正?;虍惓?,并在發(fā)現(xiàn)異常時(shí)采取相應(yīng)措施以維持高可用性。問(wèn)題在于,如果狀態(tài)判斷過(guò)程本身存在誤差或錯(cuò)誤,則之后的所有優(yōu)化和處理措施均會(huì)失去其意義。在實(shí)踐中,這里面隱藏著一個(gè)基本的矛盾:盡管通過(guò)增加冗余來(lái)提高系統(tǒng)的可用性,但在狀態(tài)決策方面卻難以保證其絕對(duì)的準(zhǔn)確性。為了進(jìn)一步理解這一挑戰(zhàn),我們將對(duì)幾種主要的決策方式進(jìn)行詳盡的分析。
圖片
2.協(xié)商式
協(xié)商式?jīng)Q策指的是兩個(gè)獨(dú)立的個(gè)體通過(guò)交流信息,然后根據(jù)規(guī)則進(jìn)行決策,最常用的協(xié)商式?jīng)Q策就是主備決策。
這個(gè)架構(gòu)的基本協(xié)商規(guī)則可以設(shè)計(jì)成:
圖片
協(xié)商式?jīng)Q策的架構(gòu)不復(fù)雜,規(guī)則也不復(fù)雜,其難點(diǎn)在于,如果兩者的信息交換出現(xiàn)問(wèn)題(比如主備連接中斷),此時(shí)狀態(tài)決策應(yīng)該怎么做。
綜合分析,協(xié)商式狀態(tài)決策在某些場(chǎng)景總是存在一些問(wèn)題的。
2 臺(tái)服務(wù)器啟動(dòng)時(shí)都是備機(jī)。
2 臺(tái)服務(wù)器建立連接。
2 臺(tái)服務(wù)器交換狀態(tài)信息。
某 1 臺(tái)服務(wù)器做出決策,成為主機(jī);另一臺(tái)服務(wù)器繼續(xù)保持備機(jī)身份。
如果備機(jī)在連接中斷的情況下認(rèn)為主機(jī)故障,那么備機(jī)需要升級(jí)為主機(jī),但實(shí)際上此時(shí)主機(jī)并沒有故障,那么系統(tǒng)就出現(xiàn)了兩個(gè)主機(jī),這與設(shè)計(jì)初衷(1 主 1 備)是不符合的。
圖片
如果備機(jī)在連接中斷的情況下認(rèn)為主機(jī)故障,那么備機(jī)需要升級(jí)為主機(jī),但實(shí)際上此時(shí)主機(jī)并沒有故障,那么系統(tǒng)就出現(xiàn)了兩個(gè)主機(jī),這與設(shè)計(jì)初衷(1 主 1 備)是不符合的。
圖片
為了緩解連接中斷對(duì)狀態(tài)決策的負(fù)面影響,一種方法是增加多條連接,比如使用雙連接或三連接策略。這種做法確實(shí)可以減少單一連接故障時(shí)對(duì)系統(tǒng)狀態(tài)判斷的影響,但是,它并不能完全消除問(wèn)題,而且引入了新的挑戰(zhàn):當(dāng)不同連接傳遞的信息出現(xiàn)差異時(shí),系統(tǒng)應(yīng)該依據(jù)哪條連接的信息進(jìn)行決策呢?實(shí)際上,這個(gè)問(wèn)題并沒有一個(gè)一刀切的解決方案。選擇任一連接作為決策依據(jù),在某些特定情況下總會(huì)遇到困難和挑戰(zhàn)。
圖片
綜合分析,協(xié)商式狀態(tài)決策在某些場(chǎng)景總是存在一些問(wèn)題的。
3.民主式
民主式?jīng)Q策過(guò)程涉及到多個(gè)獨(dú)立實(shí)體通過(guò)投票機(jī)制共同進(jìn)行狀態(tài)的判斷。這種方式在ZooKeeper集群中選舉領(lǐng)導(dǎo)者時(shí)得到了應(yīng)用。
圖片
通過(guò)這種方法,集群中的每個(gè)成員都參與到領(lǐng)導(dǎo)者的選舉中,最終根據(jù)投票結(jié)果決定領(lǐng)導(dǎo)者。
盡管這種決策機(jī)制在算法上較為復(fù)雜,它自身也帶有一個(gè)本質(zhì)上的問(wèn)題,即“腦裂”現(xiàn)象。這一術(shù)語(yǔ)源自于醫(yī)學(xué)領(lǐng)域,描述的是左右大腦半球連接斷裂,導(dǎo)致無(wú)法互相交換信息,從而分別控制身體做出不同或相互矛盾的行為。在分布式系統(tǒng)中,腦裂指的是原本統(tǒng)一的集群因網(wǎng)絡(luò)分割成兩個(gè)獨(dú)立的子集群,每個(gè)子集群都會(huì)獨(dú)立進(jìn)行領(lǐng)導(dǎo)者選舉,結(jié)果可能出現(xiàn)兩個(gè)不同的領(lǐng)導(dǎo)者,類似于一個(gè)體系內(nèi)存在兩個(gè)“大腦”。民主式?jīng)Q策指的是多個(gè)獨(dú)立的個(gè)體通過(guò)投票的方式來(lái)進(jìn)行狀態(tài)決策。例如,ZooKeeper 集。
圖片
在一個(gè)理想的分布式系統(tǒng)設(shè)置中,通常會(huì)有一個(gè)節(jié)點(diǎn)被選舉為主節(jié)點(diǎn),而其他節(jié)點(diǎn)則充當(dāng)備份角色。假設(shè)在一個(gè)正常運(yùn)行的環(huán)境里,節(jié)點(diǎn)5是主節(jié)點(diǎn),其他節(jié)點(diǎn)則作為備份。但當(dāng)網(wǎng)絡(luò)故障導(dǎo)致節(jié)點(diǎn)間連接斷開時(shí),可能會(huì)出現(xiàn)節(jié)點(diǎn)1、2、3形成一個(gè)獨(dú)立的子集群,而節(jié)點(diǎn)4和5形成另一個(gè)子集群,這兩個(gè)子集群因?yàn)檫B接斷開而無(wú)法相互通信。根據(jù)民主式?jīng)Q策機(jī)制,這兩個(gè)子集群可能會(huì)分別選舉出自己的主節(jié)點(diǎn),比如節(jié)點(diǎn)2和節(jié)點(diǎn)5,這樣系統(tǒng)就會(huì)同時(shí)存在兩個(gè)主節(jié)點(diǎn)。
這種多主節(jié)點(diǎn)的狀態(tài)與系統(tǒng)的設(shè)計(jì)初衷相違背,因?yàn)槊總€(gè)主節(jié)點(diǎn)都會(huì)獨(dú)立作出決策,導(dǎo)致系統(tǒng)狀態(tài)變得混亂。為了防止這種腦裂現(xiàn)象的發(fā)生,采用民主式?jīng)Q策的系統(tǒng)通常實(shí)施一項(xiàng)規(guī)則:參與投票的節(jié)點(diǎn)數(shù)必須超過(guò)系統(tǒng)總節(jié)點(diǎn)數(shù)的一半。在上述示例中,由于節(jié)點(diǎn)4和節(jié)點(diǎn)5組成的子集群總節(jié)點(diǎn)數(shù)不足系統(tǒng)總數(shù)的一半,因此不會(huì)進(jìn)行選舉,從而避免了腦裂問(wèn)題。然而,這種做法雖然能夠預(yù)防腦裂,卻也可能降低系統(tǒng)的整體可用性。例如,如果節(jié)點(diǎn)1、2、3的故障并非由腦裂引起,而是真實(shí)的故障,這時(shí)即便節(jié)點(diǎn)4和5仍然健康,系統(tǒng)也無(wú)法選舉出新的主節(jié)點(diǎn),相當(dāng)于整個(gè)系統(tǒng)停止服務(wù),盡管有部分節(jié)點(diǎn)依然處于正常狀態(tài)。