系統設計與實踐(二) GeekBand

分布式系統

分布式系統基礎重要要點
  1. 對外提供無狀態節點,內部實現具體有狀態或者無狀態節點邏輯,節點即可以是提供服務,也可以是存儲數據。
  2. 拜占庭問題,在分布式系統中的使用,目的是保證服務可用,而不是找出錯誤的節點,如果。
  3. 異常常見情況,機器宕機、網絡異常、消息丟失、消息亂序、數據錯誤、不可靠的TCP。可能是收到消息后宕機、也可能是處理完成以后機器宕機、處理完成任務后發送確認消息是網絡異常。也有可能是發出去的消息丟失,或者發送確認消息時丟失。可能先發送出去的數據后收到。
  4. 分布式狀態、成功、失敗、超時。超時的情況,不能判斷是否成功,原有同上。
  5. 數據存儲在機械硬盤上,隨時有可能發生異常,導致數據沒有能正確存儲。
  6. 無法歸類的異常,比如,系統的處理能力時高、時低,的詭異行為。
  7. 即使是小概率事件,在每天百萬、千萬、及以上的運算量時也會上升為大概率事件。
  8. 副本提高數據的冗余,提高系統的可用性,但是在使用副本代來好處的同時,也導致維護副本需要成本。如副本的一致性,多個副本一致性,多個副本直接可能到不一致。
  9. 一致性級別:強一致性、單調一致性,讀取最新數據、會話一致性,通過版本讀取統一值。最終一致性、弱一致性。
機器宕機

機器宕機是最常見的異常之一。在大型集群中每日宕機發生的概率為千分之一左右。在實踐中,一臺宕機的機器恢復的時間通常認為是24小時,一般需要人工介入重啟機器。宕機造成的后果通常為該機器上節點不能正常工作。假設節點的工作流程是三個獨立原子的步驟,宕機造成的后果是節點可能在處理完某個步驟后不再繼續處理后續步驟。

當發生宕機時,節點無法進入正常工作的狀態,稱之為“不可用”(unavailable)狀態。機器重啟后,機器上的節點可以重新啟動,但節點將失去所有的內存信息。在某些分布式系統中,節點可以通過讀取本地存儲設備中的信息或通過讀取其他節點數據的方式恢復內存信息,從而恢復到某一宕機前的狀態,進而重新進入正常工作狀態、即“可用”(available)狀態。而另一些分布式系統中的某些無狀態節點則無需讀取讀取任何信息就可以立刻重新“可用”。使得節點在宕機后從“不可用”到“可用”的過程稱為宕機恢復。

分布式系統的三態

由于網絡異常的存在,分布式系統中請求結果存在“三態”的概念。在單機系統中,我們調用一個函數實現一個功能,則這個函數要么成功、要么失敗,只要不發生宕機其執行的結果是確定的。然而在分布式系統中,如果某個節點向另一個節點發起RPC(Remote procedure call)調用,即某個節點A向另一個節點B發送一個消息,節點B根據收到的消息內容完成某些操作,并將操作的結果通過另一個消息返回給節點A,那么這個RPC執行的結果有三種狀態:“成功”、“失敗”、“超時(未知)”,稱之為分布式系統的三態。

如果請求RPC的節點A收到了執行RPC的節點B返回的消息,并且消息中說明執行成功,則該RPC的結果為“成功”。如果請求RPC的節點A收到了執行RPC的節點B返回的消息,并且消息中說明執行失敗,則該RPC的結果為“失敗”。但是,如果請求RPC的節點A在給定的時間內沒有收到執行RPC的節點B返回的消息,則認為該操作“超時”。對于超時的請求,我們無法獲知該請求是否被節點B成功執行了。這是因為,如果超時是由于節點A發向節點B的請求消息丟失造成的,則該操作肯定沒有被節點B成功執行;但如果節點A成功的向節點B發送了請求消息,且節點B也成功的執行了該請求,但節點B發向節點A的結果消息被網絡丟失了或者節點B在執行完該操作后立刻宕機沒有能夠發出結果消息,從而造成從節點A看來請求超時。所以一旦發生超時,請求方是無法獲知RPC的執行結果的。

異常

被大量工程實踐所檢驗過的異常處理黃金原則是:任何在設計階段考慮到的異常情況一定會在系統實際運行中發生,但在系統實際運行遇到的異常卻很有可能在設計時未能考慮,所以,除非需求指標允許,在系統設計時不能放過任何異常情況。

工程中常常容易出問題的一種思路是認為某種異常出現的概率非常小以至于可以忽略不計。這種思路的錯誤在于只注意到了單次異常事件發生的概率,而忽略了樣本的大小。即使單次異常概率非常小,由于系統規模和運行時間的作用,事件樣本將是一個非常大的值,從而使得異常事件實際發生的概率變大。

副本

副本(replica/copy)指在分布式系統中為數據或服務提供的冗余。對于數據副本指在不同的節點上持久化同一份數據,當出現某一個節點的存儲的數據丟失時,可以從副本上讀到數據。數據副本是分布式系統解決數據丟失異常的唯一手段。另一類副本是服務副本,指數個節點提供某種相同的服務,這種服務一般并不依賴于節點的本地存儲,其所需數據一般來自其他節點。
例如,GFS系統的同一個chunk的數個副本就是典型的數據副本,而Map Reduce系統的Job Worker則是典型的服務副本。

副本一致性

分布式系統通過副本控制協議,使得從系統外部讀取系統內部各個副本的數據在一定的約束條件下相同,稱之為副本一致性(consistency)。副本一致性是針對分布式系統而言的,不是針對某一個副本而言。

例1.3:某系統有3副本,某次更新數據完成了其中2個副本的更新,第3個副本由于異常而更新失敗,此時僅有2個副本的數據是一致的,但該系統通過副本協議使得外部用戶始終只讀更新成功的第1、2個副本,不讀第3個副本,從而對于外部用戶而言,其獨到的數據始終是一致的。

依據一致性的強弱即約束條件的不同苛刻程度,副本一致性分為若干變種或者級別:

  • 強一致性(strong consistency):任何時刻任何用戶或節點都可以讀到最近一次成功更新的副本數據。強一致性是程度最高的一致性要求,也是實踐中最難以實現的一致性。

  • 單調一致性(monotonic consistency):任何時刻,任何用戶一旦讀到某個數據在某次更新后的值,這個用戶不會再讀到比這個值更舊的值。單調一致性是弱于強一致性卻非常實用的一種一致性級別。因為通常來說,用戶只關心從己方視角觀察到的一致性,而不會關注其他用戶的一致性情況。

  • 會話一致性(session consistency):任何用戶在某一次會話內一旦讀到某個數據在某次更新后的值,這個用戶在這次會話過程中不會再讀到比這個值更舊的值。會話一致性通過引入會話的概念,在單調一致性的基礎上進一步放松約束,會話一致性只保證單個用戶單次會話內數據的單調修改,對于不同用戶間的一致性和同一用戶不同會話間的一致性沒有保障。實踐中有許多機制正好對應會話的概念,例如php中的session概念。可以將數據版本號等信息保存在session中,讀取數據時驗證副本的版本號,只讀取版本號大于等于session中版本號的副本,從而實現會話一致性。

  • 最終一致性(eventual consistency):最終一致性要求一旦更新成功,各個副本上的數據最終將達到完全一致的狀態,但達到完全一致狀態所需要的時間不能保障。對于最終一致性系統而言,一個用戶只要始終讀取某一個副本的數據,則可以實現類似單調一致性的效果,但一旦用戶更換讀取的副本,則無法保障任何一致性。

  • 弱一致性(week consistency):一旦某個更新成功,用戶無法在一個確定時間內讀到這次更新的值,且即使在某個副本上讀到了新的值,也不能保證在其他副本上可以讀到新的值。弱一致性系統一般很難在實際中使用,使用弱一致性系統需要應用方做更多的工作從而使得系統可用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容