分散式系統中常見技術解決的問題是什麼?

Charles0429發表於2018-03-26

引言

在分散式系統中,經常會碰到的技術名詞一般有Replication、Partition、Consensus、Transaction等等,這些技術在分散式系統設計中都是非常重要的,本文通過對分散式系統的Reliability、Scalability和Maintainability特性的討論,描述這些技術解決的問題。

Reliability

Reliability,指的是在任何情況下,系統正常工作的能力。如果一個系統在發生任何異常時,都能正常的工作,那麼系統是完全可靠的。現實中,異常種類很多,有的往往難以事先避免,因此,瞭解可能的異常並分析如何在異常發生時快速恢復是非常重要的。一般地,異常包括硬體異常,軟體異常和人為異常。

硬體異常

硬體異常種類很多,硬碟,電源等任意一個部件的損壞,都可能導致伺服器不能正常的工作。通常這類異常難以避免,但是,我們可以通過一些技術手段來實現異常發生後的快速恢復,不管是從軟體角度還是硬體角度,基本的解決思路都是冗餘。從硬體角度來講,我們可以通過單機冗餘多份硬體,當其中某個硬體發生異常時,可以快速地用好的硬體替換掉故障的硬體,這種方式的硬體冗餘對於資料中心級的故障是沒有作用的;從軟體角度來講,我們可以通過多副本(Replication)來實現快速恢復,當某臺伺服器硬體異常時,可以在軟體層面將流量匯入到新的副本上(實際上也有硬體冗餘,但這種方式更為靈活),除了Replication之外,有時候為了減少單臺伺服器故障對所有使用者的影響,可以對使用者資料做Partition,單臺伺服器只存某一部分使用者的資料,這樣單機故障就只會影響一部分使用者了。引入Replication後,如何保證多副本的資料的一致性又成了一個問題(Consensus),Paxos和Raft演算法就是為了解決這類問題。

軟體異常

軟體異常一般指的是系統的bug,這裡面不僅包括自己寫的系統的bug,也包括依賴的服務系統的bug。軟體異常同樣也是不能完全避免的,因此,在發生軟體異常時,也需要有快速恢復的手段,通常有三種方法:

  1. 通過調整軟體已有的配置引數,規避問題
  2. 重啟軟體或者依賴的服務,消除異常狀態
  3. 直接修復bug,並升級版本

在沒有發生致命性問題時,一般採用方法1或2來恢復,當發生的問題比較嚴重,並且沒有已知的方法能繞過時,一般才使用方法3,方法3本身風險也是比較大的,因為修復bug的同時可能會產生新的bug。

人為異常

不管是軟體本身,還是軟體所執行的伺服器,都是由人來管理的,但人是會犯錯誤的,有時候會執行錯誤的命令導致系統不能正常工作,其中比較致命的錯誤可能就是刪掉某臺伺服器的資料了,在這種情況下為了能快速地恢復,通常也是採用Replication的思路,來避免問題。

Scalability

系統的工作負載通常不是一成不變的,當工作負載增加時,往往可以通過增加機器資源來保持效能不變,而需要增加機器數量的多少是由系統的擴充套件性來決定的,擴充套件性越好的系統,需要增加的機器資源越少。最完美的擴充套件性是線性擴充套件性,即工作負載擴大為原來N倍的時候,只需要加N倍的機器,就能夠保持效能不變,最差的擴充套件性則是沒有擴充套件性,即工作負載擴大為原來N倍時,即使加再多的機器,也無法保持效能和原來一樣。

對於不同的系統,負載所代表的含義通常是不一樣的,對於基礎架構系統,通常每秒讀和每秒寫的次數,對於業務系統,通常有自己的指標,例如每秒交易建立的筆數。同樣地,對於不同的系統,其使用的效能指標通常也是不相同的,對於批處理系統,通常強調的是吞吐量,即每秒完成的任務數量,而對於線上處理系統,通常強調的是響應時間。

在明確一個系統的工作負載指標和效能指標之後,我們才能討論在該系統下如何實現擴充套件。擴充套件通常是兩種思路,一是垂直擴充套件,即使用更好的機器替換現有的機器,二是水平擴充套件,即使用更多的機器。

對於垂直擴充套件,其優點是對業務是無影響的,缺點是更好的機器是很貴的,通常是一分錢一分貨,而十分錢只能買到兩分貨,且現實中總有單機裝不下的資料量,此時垂直擴充套件自然就無法實施了。

對於水平擴充套件,通常需要軟體層面的配合,對於無狀態的系統,通常只要在新加的機器上部署上需要擴充套件的系統,而對於有狀態的系統,一般指的是儲存系統,通常會將資料分成Partition(分割槽),這樣新加的機器才能通過遷移Partition的方式,從老的機器上遷移資料以及對應的工作負載出來。水平擴充套件的優點是使用的都是相對廉價的伺服器,能節約成本,但在軟體層面需要做大量的工作,包括Partition的管理,遷移,負載均衡等等。

Maintainability

可維護性的好壞決定了系統是否能夠長久的發展,一個可維護性不好的系統,會給運維和開發人員帶來很多不便。對於運維人員來講,可維護性指的是系統是否支援常用的運維手段,良好的文件等等。而對於開發人員來講,主要分為核心開發以及使用該系統的業務開發,對於業務開發,維護性指的是系統是否有良好的介面,方便業務使用,例如,Transaction就是底層系統提供給業務的一種介面,它保證了在一個事務中執行的語句具有ACID性質,從而業務只需要關注業務邏輯的開發,而不需要關心底層的具體實現;對於核心開發,維護性指的是系統的程式碼質量,主要包括程式碼的可閱讀性和是否易於修改,主要和系統核心開發人員的程式碼設計能力相關。

總結

為了能達到較好的可靠性(Reliability)、可擴充套件性(Scalability)和可維護性(Maintainability),分散式系統設計中通常會使用多副本(Replication)、資料分割槽(Partition)、一致性演算法(Consensus)、事務(Transaction)等技術,理解它們要解決的問題,深入瞭解每種技術背後可能的實現方案,有助於評價某個系統的設計好壞,這對於多個競品系統的選型和深入學習系統原理都是非常有必要的。

本部落格更新會在第一時間推送到微信公眾號,歡迎大家關注。

qocde_wechat

參考文獻

  • Design Data Intensive Applications

相關文章