中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

淺談“完美無瑕”的分布式系統(tǒng)

2019-08-29    來源:raincent

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

本文最初發(fā)布于 Lena Hall 個人博客,譯者:劉志勇 來源:InfoQ

導讀: 本文基于 Lena Hall 的 O’Reilly Velocity 2019 主題演講,進行了解讀。分布式系統(tǒng)是建立在網絡之上的軟件系統(tǒng)。正是因為軟件的特性,所以分布式系統(tǒng)具有高度的內聚性和透明性。因此,網絡和分布式系統(tǒng)之間的區(qū)別更多的在于高層軟件(特別是操作系統(tǒng)),而不是硬件。內聚性是指每一個數據庫分布節(jié)點高度自治,有本地的數據庫管理系統(tǒng)。透明性是指每一個數據庫分布節(jié)點對用戶的應用來說都是透明的,看不出是本地還是遠程。在分布式數據庫系統(tǒng)中,用戶感覺不到數據是分布的,即用戶不須知道關系是否分割、有無副本、數據存于哪個站點以及事務在哪個站點上執(zhí)行等。說了這么多,但實際上,分布式系統(tǒng)一點都不復雜,簡單的說就是:將整個個軟件視為一個系統(tǒng)(不管它有多復雜),然后將整個系統(tǒng)分割為一系列的進程,每個進程完成一定的功能。再將這些進程分散到不同的機器上,分散后,選擇若干種通信協(xié)議將它們連接起來。這就完成了分布式系統(tǒng)的構建。人們常常把分布式系統(tǒng)自然而然的和并行計算聯(lián)系起來。然而這并不正確。實際上,分布式系統(tǒng)并不一定是并行的。Lena Hall 給我們詳細闡述了“完美無瑕”的分布式系統(tǒng)應該是什么樣的,以及我們應該如何朝著這一目標做哪些工作。

 

 

本文闡述了我們所做工作帶來的影響,我們所面臨的復雜性和障礙,以及對于構建更好的分布式系統(tǒng)的重要因素,尤其是當其他關鍵領域依賴并建立我們所創(chuàng)造的基礎之上時。

目前可用的系統(tǒng)已經提供了許多解決方案,封裝了許多分布式算法,實現了自動化并抽象出一些復雜性。使用這些系統(tǒng)的工程師并不一定非要擁有開發(fā)它們所需的大量知識不可。盡管對于工程師新手來說,了解這些系統(tǒng)所依賴的基礎知識越來越沒有什么必要了,但在某些情況下,了解幕后工作對于做出正確的決策并解決出現的困難問題還是必不可少的。

基礎知識仍然很重要嗎?

為什么說重視基礎知識很重要?今天,我們正處于這樣的一個階段,分布式系統(tǒng)在醫(yī)療系統(tǒng)、自主設備、傳輸自動化和其他生命攸關系統(tǒng)中的應用越來越廣泛,在這些場景中,錯誤的代價越來越高,而正確性變得日益重要起來。

錯誤的代價并不是指你的系統(tǒng)今天不可用的時間長短。它是關于你的系統(tǒng)發(fā)生宕機或故障時,給用戶或他們的用戶帶來的代價。我們應該負起責任,并永遠記住我們?yōu)槭裁催@樣做,我們真正要解決的問題是什么。

 

 

每個行業(yè)都希望通過結合他們和我們的研究和解決方案來取得更大的進步。而我們的工作能夠幫助其他領域更好地實現他們的目標。對我們來說,了解如何放寬某些限制或者微調某些權衡也是非常有用的。

了解核心的內容,是一個強大的工具,可以讓我們從容駕馭不斷變化的選項和工具的復雜性,并幫助我們構建正確的解決方案,以改進我們現有的選項。

但事實證明,要做到這一點并不是那么容易。在我們前進的道路上,荊棘載途,艱難險阻。

理論和實踐存在巨大的差距

理解“正確”對我們的系統(tǒng)意味著什么,對我們來說,不啻為一個挑戰(zhàn)。大多數理論材料都很不“接地氣”,眾所周知,它們很難被理解并掌握。不止如此,它往往還不包括那些將這一理論付諸實踐所需的信息。要想應用到生產系統(tǒng)中,就必須修改理論算法,并對它們進行調整以適應實際環(huán)境。其中許多并沒有透露對實際解決方案很重要的具體細節(jié)。甚至對協(xié)議細節(jié)稍有誤解,也會破壞協(xié)議的正確性。因此,我們需要做更多的額外工作,以保證實踐時,協(xié)議仍然是正確的。

 

 

正確性難以驗證和維持

在實際環(huán)境中驗證并維持分布式系統(tǒng)的正確性,是一項具有挑戰(zhàn)性的工作。它可能聽上去很完美,但在實踐中,卻可能是低效的、或者難以實現的。這在理論上聽起來不切實際,但在實踐中卻是完全可以接受的。須知在算法邏輯及其實現中,很多地方都有可能出錯,而且還難以檢測。

正確性并不總是優(yōu)先考慮的事

另一方面,正確性并不總是優(yōu)先考慮的事。還有截止期限、競爭和客戶都需要更快的解決方案。終端系統(tǒng)還可能會出現倉促而不能正確修復的情況。這意味著團隊可能沒有足夠的時間來做這件事:正確地討論并系統(tǒng)地解決罕見的“間歇性”錯誤背后的真正原因,這些錯誤在未來還會再次發(fā)生,導致出現更多的錯誤。

我們該如何改進?

我們可以從多個方面改進。其中之一就是:強調并集中精力提高正確性,以確保我們能夠構建并維護系統(tǒng),使其始終按照我們所希望的那樣運行。

另一個就是,提高對它們如何工作的理解,因為這有助于我們減少復雜性和可能出現的錯誤,并使我們更有準備迎接即將到來的挑戰(zhàn)。

當我們不直接實現分布式算法和概念時,我們肯定會依賴基于那些構建的系統(tǒng)。在我們構建的內容與其他領域相互交叉時,理解基本概念和權衡就變得極為重要了。

如果向你承諾了一些性能和一致性,那么你該如何確保這些承諾就是在你需要的確切水平上提供的呢?

簡單問題復雜化

當幾臺計算機相互通信時,瑣碎的問題就變成了棘手的問題,而且它們還會累積起來。分布式系統(tǒng)難以理解,也難以實現,而且在實踐中很難保持它們的正確性。

我認為有很多方法可以說明其原因。最近,我有機會為生物信息學領域的人解釋,他們想知道為什么需要在分布式環(huán)境中的重要屬性之間進行權衡。

排序

我想到的第一件事就是對事件進行排序。在一臺機器上進行排序很容易,但當消息通過網絡發(fā)送時,就變得很難了!我們不能依賴物理時間戳,因為不同機器上的物理時鐘往往有所偏移。對于分布式系統(tǒng)中的排序,我們經常應用邏輯時鐘,或者簡單地說,在節(jié)點之間傳遞的計數器。

由于分布式系統(tǒng)的異步特性,我們并不能很容易地為所有事件建立競爭順序,因為其中一些事件是并發(fā)的!我們所能做的就是找出哪些事件是并發(fā)的,哪些事件在彼此之前發(fā)生。即使是這樣一個簡單的任務,我們也需要做出一些決定。

例如,如果系統(tǒng)告訴我們事件是有序的,但實際上它們是并發(fā)的,那么,這種情況我們是否可以接受呢?

 

 

或者,我們是否需要確切地知道,當我們可以對事件進行排序時,事件真的不是同時發(fā)生的嗎?

 

 

協(xié)議

我們不能簡單地對并發(fā)事件進行排序,有時候,我們仍然需要決定操作的順序、值、值序列或其他任何東西。

事實證明,讓幾臺機器選擇相同的東西是另一種情況。在這種情況下,我們必須要問自己的問題,并決定什么對我們是合適的。

 

 

例如,二階段提交(Two Phase Commit)的是一種解決方案,在這種解決方案中,我們的節(jié)點可以就某些方面達成一致。

譯注:在計算機網絡以及數據庫領域內,二階段提交(Two-phase Commit)是指,為了使基于分布式系統(tǒng)架構下的所有節(jié)點在進行事務提交時保持一致性而設計的一種算法。通常,二階段提交也被稱為是一種協(xié)議。在分布式系統(tǒng)中,每個節(jié)點雖然可以知曉自己的操作時成功或者失敗,卻無法知道其他節(jié)點的操作的成功或失敗。當一個事務跨越多個節(jié)點時,為了保持事務的 ACID 特性,需要引入一個作為協(xié)調者的組件來統(tǒng)一掌控所有節(jié)點(稱作參與者) 的操作結果并最終指示這些節(jié)點是否要把操作結果進行真正的提交(比如將更新后的數據寫入磁盤等等)。因此,二階段提交的算法思路可以概括為: 參與者將操作成敗通知協(xié)調者,再由協(xié)調者根據所有參與者的反饋情報決定各參與者是否要提交操作還是中止操作。

 

 

只要我們的節(jié)點不出故障,它就可以進行工作。

如果一些節(jié)點發(fā)生崩潰,為了防止出現數據不一致的可能性,系統(tǒng)就會阻塞,直到崩潰的節(jié)點返回,這種情況也有可能永遠不會發(fā)生;或者需要非常、非常長的時間。

所以,這個算法是安全的,但它不是實時的。

如果這還不是我們所能接受的,那么我們是不是真的需要一個系統(tǒng)來回應呢?

 

 

在這種情況下,我們可能有另一種潛在的解決方案:三階段提交(Three Phase Commit),當節(jié)點出現故障時,它就不會發(fā)生阻塞。

譯注: 三階段提交(Three-phase commit),是在計算機網絡及數據庫的范疇下,使得一個分布式系統(tǒng)內的所有節(jié)點能夠執(zhí)行事務的提交的一種分布式算法。三階段提交是為解決兩階段提交協(xié)議的缺點而設計的。與二階段提交不同的是,三階段提交是 “非阻塞” 協(xié)議。三階段提交在二階段提交的第一階段與第二階段之間插入了一個準備階段,使得原先在二階段提交中,參與者在投票之后,由于協(xié)調者發(fā)生崩潰或錯誤,而導致參與者處于無法知曉是否提交或者中止的 “不確定狀態(tài)” 所產生的可能相當長的延時的問題得以解決。

 

 

但是,當有網絡分區(qū)時,情況又會怎么樣呢?

 

 

網絡的兩個相互隔離的分區(qū)在超時后可能會做出兩個不同的決定,系統(tǒng)最終將會處于不一致的狀態(tài)。

所以,這時候我們得到的是相反的結果:系統(tǒng)是實時響應的,但并不安全,因為不同的節(jié)點可以決定不同的值。

 

 

如果我們對這兩個選項中的任何一個都能接受,那就太好了!

如果我們希望數據始終保持一致性,并且系統(tǒng)還要能夠響應,那么我們應該做什么呢?

不可能結果

不可能結果 證明,實際上,在完全異步的環(huán)境中,總是終止并最終作出決定的確定性算法是不存在的,甚至可能出現一次故障。

譯注: 不可能結果(Impossibility result)是分布式領域的專業(yè)術語,在一個完全異步的消息傳遞分布式系統(tǒng)中,如果一個進程有故障,那么一致性問題是無法得到解決的。簡單來說,就是在一定的限制條件下問題能否被解決,那么任務的不可能結果就只有兩種情況:能和不能。

 

 

從這個結果中,我們可以學到的主要內容是:如果我們想在實踐中解決協(xié)議,我們就必須重新考慮我們的假設,以反映更為現實的期望!例如,我們可以設定最大消息延遲的上限,并確定系統(tǒng)可接受的失敗次數。

如果我們改變假設,那么我們就可以用多種方式來解決分布式協(xié)議!

 

 

Paxos 算法

最著名的解決方案是 Paxos 算法,眾所周知,這個算法晦澀難懂,而且難以正確實施。

它實際上是可行的,但只有在大多數節(jié)點都必須啟動,且最大消息延遲是有限的情況下才可行。

在 Paxos 中,任何節(jié)點都可以提出一個值,在經過“準備”和“建議”階段后,所有節(jié)點都應該就相同的值達成一致。

大多數節(jié)點都需要啟動,因為如果在每個階段中 Quorums 相交,總有有至少一個節(jié)點記得最近的建議是什么,這就阻止了對舊值達成一致。

 

 

為了提高算法的效率,在實際應用中,對出事算法進行了許多優(yōu)化。基于它們所選擇的權衡,共識算法也有許多可能的變體。

例如,Leader 完成了多少工作。擁有一個強大的 Leader 可能是好事,但也有可能是壞事。這要取決于失敗的頻率和重新選舉的難度。另一種權衡是,我們可以容忍多少節(jié)點出故障,以及 Quorum 數量應該有多少。

有些被低估的標準是算法在實踐中的可理解性和可實施性。Raft 之所以廣受歡迎,是因為它更容易理解,現在已經應用于許多廣泛使用的項目中。

譯注: Paxos 算法是 Leslie Lamport(就是 LaTeX 中的 “La”,此人現在在微軟研究院)于 1990 年提出的一種基于消息傳遞的一致性算法。這個算法被認為是類似算法中最有效的。Paxos 算法解決的問題是一個分布式系統(tǒng)如何就某個值(決議)達成一致。一個典型的場景是,在一個分布式數據庫系統(tǒng)中,如果各節(jié)點的初始狀態(tài)一致,每個節(jié)點執(zhí)行相同的操作序列,那么他們最后能得到一個一致的狀態(tài)。為保證每個節(jié)點執(zhí)行相同的命令序列,需要在每一條指令上執(zhí)行一個 “一致性算法” 以保證每個節(jié)點看到的指令一致。

新的權衡仍在不斷發(fā)現

但更有趣的是,盡管共識和協(xié)議的話題并不新鮮,但我們仍然發(fā)現了許多新的優(yōu)化和權衡。

在經典的 Paxos 算法中,大多數節(jié)點都需要啟動以確保所有的 Quorum 相交。但事實證明,我們可以重新考慮并簡化大多數 Quorum 要求。事實證明,只有準備階段和建議階段的 Quorum 相交就足矣,這為我們提供了更多的靈活性來對每個階段的 Quorum 大小和性能進行實驗!

 

 

重點是,揭示迄今為止的新性能和可用性權衡,有助于我們在實踐中擴大選擇范圍。共識只是一個構件塊,但它可以用來解決許多常見問題,如原子廣播(atomic broadcast)、分布式鎖(distributed locks)、強一致性復制等等。

請查看 Heidi Howard 博士的論文 “Distributed Consensus Revised”,該篇論文是這方面最好的論文之一。

一致性復制?

復制(Replication)是當今任何分布式系統(tǒng)的重要組成部分。

我們實際上可以用共識來實現強一致性復制,但它的缺點之一就是性能。另一方面當然是一致性復制,這種復制速度非?,但在客戶端卻可以看到不一致的數據。在實踐中,我們通常會希望獲得更好的性能,同時還要保持更強的一致性,這可能有些棘手。

因此,在某些情況下,我們可以提出比共識更快的解決方案,而且比最終的一致性更加一致。

其中一個有趣的例子是 Aurora,它避免了對 I/O 和其他一些操作達成共識。它們使用 Quorum 進行寫入,但不用它們來閱讀。實際上,副本可能會存儲不同的值,但當客戶端執(zhí)行讀取操作時,由于數據庫維護一致性點,因此它可以直接查看已知數據一致的節(jié)點,并將正確的數據返回給客戶端。

 

 

無沖突可復制數據類型

另一個有趣的例子是無沖突可復制數據類型(Conflict Free Replicated Data Type,CRDT)。它們可以提供強大的最終一致性:快速讀寫操作,甚至在網絡分區(qū)期間仍然保持可用,而無需使用共識或同步。然而,只有在我們能夠有解決任何并發(fā)沖突的規(guī)則時才有可能。

換句話說,如果可以使用某些函數合并并發(fā)更新,這些可以按任意順序應用它們,并且還可以按照我們想要的任意次數應用它們,而不會破壞結果,那么我們就只能使用這種技術。

這是一個完全可以接受的示例,其中所有更新都是附加的,因此它們完全滿足這一要求。

 

 

另一方面,這一點并不明顯,因為我們沒有明確的規(guī)則來解決這種同時更新的沖突。

 

 

Azure Cosmos DB 使用 CRDT 在并發(fā)多主多區(qū)域寫入的后臺來解決沖突。Redis 和 Riak 也使用 CRDT。

 

 

故障檢測

如果我們在分布式系統(tǒng)中進入另一個主題,我們總會發(fā)現需要進行更多的權衡。

故障檢測器 是分布式系統(tǒng)中發(fā)現節(jié)點崩潰的關鍵技術之一。它們可以應用于協(xié)議問題、Leader 選舉、組員協(xié)議和其他領域。

我們可以通過故障檢測器的“完備性”、“正確度”來衡量它們的效率。

完備性顯示了系統(tǒng)中的一些或所有節(jié)點是否發(fā)現所有故障。正確度度量故障檢測器在懷疑另一個節(jié)點故障可能出現的錯誤級別。

事實證明,即使是不可靠的故障檢測器在實際系統(tǒng)中也是非常有用的,因為我們可以通過添加一種故障知識傳播到所有節(jié)點的“八卦”機制,來提高它們的完備性。

為什么所有這一切都很重要?

權衡可能是多種多樣的,如果我們知道如何使用它們,知道在哪里尋找它們,那么我們就可以變得非常靈活。

 

 

許多產品都是圍繞算法和權衡而構建的。這些產品為我們做出了某些選擇,我們通過使用某些產品來做出選擇。未受教育的選擇可能會導致延遲和數據丟失。對于某些系統(tǒng)來說,這點可能會導致客戶流失和巨額資金。對于其他系統(tǒng)來說,它可能導致反應緩慢,或者操作順序錯誤,從而構成了實際的生命威脅。理解你的權衡對于做出正確的選擇、了解正確的含義以及在現實中驗證系統(tǒng)的正確性非常重要。

驗證與維護現實中的正確性

在我們明確了抉擇和權衡之后,我們該如何在實際系統(tǒng)中維護正確性呢?

系統(tǒng)模型檢查是驗證分布式邏輯的安全性和活性(尤其是安全性)的常用選項之一。模型檢查很有用,因為它探索了系統(tǒng)最終可能出現的所有狀態(tài),F在有相當多的工具,如 TLA+ 就非常有名,除此之外還有更多的新興技術,如語義感知模型檢查。

為了驗證分布式系統(tǒng)的實際運行實現的正確性,僅靠模型檢查是不夠的。

很少有項目會發(fā)布關于如何維護其系統(tǒng)的正確性并對其進行驗證的相關信息。但其中一些項目做到了。

例如,Kafka 的各種系統(tǒng)測試 每天都在運行,世界上的任何人都可以檢查并查看 哪些工作符合預期,哪些工作不正常。

 

 

Cassandra 對他們的綜合測試方法寫了一篇很棒的文章。

 

 

我真的希望,會有更多的產品、項目和系統(tǒng)能夠對他們投入測試和正確性驗證方面的工作更加開放。

如果我們看一下準備運行生產機分布式系統(tǒng)需要做些什么,就會發(fā)現有很多事情需要去做。

當然,對于小范圍場景并確保多個服務協(xié)同工作良好,單元測試和集成測試是必不可少的。但這些還不夠!我們可以使用更多的技術。模糊測試和基于屬性的測試為你的系統(tǒng)提供了隨機生成的輸入,以確;緦傩曰谄湟(guī)范是正確的。實際上,我在 Microsoft 從事過一個關于模糊測試的項目,總體來說,這是一個非常吸引人的話題。性能測試對收集各種組件的延遲和吞吐量的數據非常有用。故障注入有助于檢查系統(tǒng)在故障情況下是否可用,以及預期的系統(tǒng)屬性是否仍然保持正確。

綜上所述,導致最嚴重錯誤的背后的大量原因,仍然是異常處理邏輯。

 

 

有些事情,我們無法完全解決。我們需要接受這樣一個事實:在我們編寫完所有的測試和檢查之后,無論如何,錯誤都會存在。我們是人類,再加上上下文切換,因此我們不可能知曉每一件事,有太多的活動部分了。我們永遠沒有探索過新的領域,如果我們害怕離開所熟悉的領域,那么我們就永遠不會取得進展。但是,我們絕對可以為處理意外錯誤做出更好的準備,找到模式,并試圖解決導致錯誤的原因。這就是為什么檢測代碼很重要,可觀察性也很重要。當我們意識到這種可能性并為解決生產錯誤奠定基礎時,就不那么可怕了。

題外話

產品變化很快,描述它們的一致性、彈性和性能的術語極其繁多;靖拍詈蜋嗪馊匀淮嬖,并不斷積累。它們在孤立的情況下并沒有什么用處,但是了解它們,對于做出正確的選擇和在實踐中保持正確性是必不可少的。當我們的系統(tǒng)在特定級別的響應性和安全性有強烈要求的場景中受到信任時,正確性尤為重要。

如果你正在構建某些內容時,請捫心自問:這會被誤解嗎?復雜性就像項目周圍的一堵防彈墻一樣,它使解釋、構建、使用和改進變得困難。試著讓你構建的系統(tǒng)能夠被其他人理解,因為理解有助于正確性的提高。

正確性并不容易,也不是免費的。你必須致力于此,并將其作為優(yōu)先事項。不僅僅是一個愿意這樣做的工程師的水平上,而是整個組織的水平。不要相信你的系統(tǒng)知識工作:測試它,驗證它,并在事情失敗時做好準備,向你的用戶和客戶展示你在演示系統(tǒng)方面投入了哪些技術和努力。

 

 

想想那些與你工作相關但沒有得到足夠重視的重要領域吧,如果你有機會和其他領域工作的其他人聊天,那就去做,了解他們在工作中所面臨的挑戰(zhàn),以及他們正在做出的權衡。虛心求教,與他們分享你的工作。這會幫助你成長為一個更優(yōu)秀的工程師。

 

 

作者介紹:

Lena Hall,Microsoft 高級軟件工程師,從事大數據和分布式系統(tǒng)方向。曾在 Microsoft 研究院工作。同時也是一名技術演講者、機器學習 ML4ALL 的組織者、Kafka 峰會的董事。

原文鏈接:Eventually Perfect Distributed Systems

標簽: 分布式系統(tǒng) d

版權申明:本站文章部分自網絡,如有侵權,請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:大數據需求使用的六個Hadoop發(fā)行版

下一篇:聯(lián)通大數據 5000 臺規(guī)模集群故障自愈實踐