近幾章主要介紹系統(tǒng)如何處理錯(cuò)誤。例如,我們討論了副本故障轉(zhuǎn)移,復(fù)制滯后和事務(wù)的并發(fā)控制。當(dāng)我們理解實(shí)際系統(tǒng)中可能出現(xiàn)的各種邊界情況時(shí),我們就能更好地處理它們。
前幾章雖然談?wù)摿撕芏嚓P(guān)于錯(cuò)誤的問(wèn)題,但是還是太樂(lè)觀了。在本章中,我們將最悲觀地假設(shè)“任何可能出故障的,最終都會(huì)出故障”。
分布式系統(tǒng)編程與在單機(jī)上編寫軟件有本質(zhì)區(qū)別——主要區(qū)別在于分布式系統(tǒng)中有很多新奇的可能出故障的方式。 本章中,我們將了解在實(shí)踐中出現(xiàn)的問(wèn)題,并了解哪些我們可以依賴,哪些不行。
最后,作為工程師,我們的任務(wù)是構(gòu)建能夠完成工作的系統(tǒng)(即滿足用戶所期望的保證),盡管各個(gè)部件都出錯(cuò)了。 在第9章中,我們將看看可以在分布式系統(tǒng)中提供這種保證的算法的一些示例。 但首先,在本章中,我們必須了解我們面臨的挑戰(zhàn)。
本章是對(duì)分布式系統(tǒng)中可能出現(xiàn)的問(wèn)題的悲觀和沮喪的概述。 我們將研究網(wǎng)絡(luò)問(wèn)題(第277頁(yè)的“不可靠的網(wǎng)絡(luò)”); 時(shí)鐘和時(shí)序問(wèn)題(第287頁(yè)上的“不可靠的時(shí)鐘”); 我們將討論它們可以避免的程度。 所有這些問(wèn)題造成的后果都會(huì)讓人迷惑,因此我們將探討如何思考分布式系統(tǒng)的狀態(tài)以及如何推理已發(fā)生的事情(第300頁(yè)的“知識(shí),真相和謊言”)。
錯(cuò)誤和部分故障
當(dāng)你在單機(jī)上寫程序時(shí),它通常會(huì)以一種可預(yù)測(cè)的方式運(yùn)行:要么正常工作,要么無(wú)法工作。有bug的軟件可能會(huì)讓人覺(jué)得電腦出問(wèn)題了(通常重新啟動(dòng)就能解決問(wèn)題),但大部分還是軟件寫得不好的后果。
沒(méi)有什么根本原因能讓單機(jī)上的軟件表現(xiàn)得奇怪:當(dāng)硬件正常工作時(shí),相同的操作總是產(chǎn)生相同的結(jié)果(這是確定性的)。如果存在硬件問(wèn)題(例如,內(nèi)存損壞或連接器松動(dòng)),其后果通常是整個(gè)系統(tǒng)失效(例如“藍(lán)屏死機(jī)”,無(wú)法啟動(dòng))。具有良好軟件的單機(jī)通常功能完好或完全損壞,而不在兩者之間。
這是計(jì)算機(jī)設(shè)計(jì)中的一個(gè)慎重選擇:如果發(fā)生內(nèi)部故障,我們寧愿計(jì)算機(jī)完全崩潰,而不是返回錯(cuò)誤的結(jié)果,因?yàn)殄e(cuò)誤的結(jié)果很難處理,并且令人困惑。因此,計(jì)算機(jī)隱藏了它們實(shí)現(xiàn)所依賴的模糊物理現(xiàn)實(shí),并提出了一個(gè)理想化的系統(tǒng)模型,它可以與數(shù)學(xué)完美結(jié)合起來(lái)。CPU指令總是做同樣的事情; 如果你將一些數(shù)據(jù)寫入內(nèi)存或磁盤,則該數(shù)據(jù)保持完好并且不會(huì)隨機(jī)損壞。 這種始終正確計(jì)算的設(shè)計(jì)目標(biāo)可以追溯到第一臺(tái)數(shù)字計(jì)算機(jī)。
當(dāng)你編寫運(yùn)行在多臺(tái)計(jì)算機(jī)上并通過(guò)網(wǎng)絡(luò)連接的軟件時(shí),情況完全不同。 在分布式系統(tǒng)中,我們不再處于理想系統(tǒng)模型中 - 我們別無(wú)選擇,只能面對(duì)物理世界的混亂現(xiàn)實(shí)。 而在現(xiàn)實(shí)世界中,正如這個(gè)軼事所示,各種各樣的事情可能會(huì)出錯(cuò):
在我有限的經(jīng)驗(yàn)中,我處理過(guò)單個(gè)數(shù)據(jù)中心(DC)中的長(zhǎng)時(shí)間網(wǎng)絡(luò)分區(qū),PDU(配電單元)故障,交換機(jī)故障,整個(gè)機(jī)架的意外電源故障,全DC主干故障,全DC 電力故障和一位低血糖駕駛員將他的福特皮卡撞進(jìn)空調(diào)系統(tǒng)。我甚至不是一個(gè)運(yùn)維人員。——Coda Hale
在分布式系統(tǒng)中,可能出現(xiàn)這樣的情況,盡管系統(tǒng)的其他部分工作正常,但系統(tǒng)的某些部分可能會(huì)以某種不可預(yù)知的方式出故障。這就叫做部分故障。該問(wèn)題的難點(diǎn)在于部分故障是不確定的:如果你試圖做任何包含多個(gè)節(jié)點(diǎn)和網(wǎng)絡(luò)的事情,它可能有時(shí)工作正常,有時(shí)出現(xiàn)不可預(yù)知的故障。正如我們將要看到的,你可能甚至不知道某件事是否成功,因?yàn)橄⒃诰W(wǎng)絡(luò)中傳播所花費(fèi)的時(shí)間也是不確定的!
這種不確定性和部分故障的可能性是分布式系統(tǒng)難以處理的原因。
云計(jì)算和超級(jí)計(jì)算
關(guān)于如何構(gòu)建大型計(jì)算系統(tǒng)有一系列哲學(xué):
規(guī)模的一端是高性能計(jì)算(HPC)領(lǐng)域。擁有數(shù)千個(gè)CPU的超級(jí)計(jì)算機(jī)通常用于計(jì)算密集型科學(xué)計(jì)算任務(wù),站群服務(wù)器,如天氣預(yù)報(bào)或分子動(dòng)力學(xué)(模擬原子和分子的運(yùn)動(dòng))。
另一端是云計(jì)算,云計(jì)算沒(méi)有非常明確的定義,但通常與多租戶數(shù)據(jù)中心,連接IP網(wǎng)絡(luò)的商品計(jì)算機(jī)(通常是以太網(wǎng)),彈性/按需資源分配以及按時(shí)計(jì)費(fèi)聯(lián)系在一起。
有了這些哲學(xué),處理錯(cuò)誤的方法就非常不同了。在超級(jí)計(jì)算機(jī)中,作業(yè)通常會(huì)對(duì)其計(jì)算狀態(tài)不時(shí)地做檢查點(diǎn)到持久存儲(chǔ)上。如果一個(gè)節(jié)點(diǎn)發(fā)生故障,通常的解決方案是簡(jiǎn)單地停止整個(gè)集群工作負(fù)載。故障節(jié)點(diǎn)修復(fù)后,從上一個(gè)檢查點(diǎn)重新開始計(jì)算。因此,超級(jí)計(jì)算機(jī)更像是一臺(tái)單節(jié)點(diǎn)計(jì)算機(jī)而不是分布式系統(tǒng):它通過(guò)升級(jí)為完全故障來(lái)處理部分故障 - 當(dāng)系統(tǒng)的任何部分發(fā)生故障,簡(jiǎn)單地讓整個(gè)系統(tǒng)崩潰(就像單機(jī)上的內(nèi)核恐慌一樣)。
在本書中,我們重點(diǎn)介紹實(shí)現(xiàn)互聯(lián)網(wǎng)服務(wù)的系統(tǒng),這些系統(tǒng)通常看起來(lái)與超級(jí)計(jì)算機(jī)有很大不同: