在分佈式系統中,常常會碰到的技術名詞通常有Replication、Partition、Consensus、Transaction等等,這些技術在分佈式系統設計中都是很是重要的,本文經過對分佈式系統的Reliability、Scalability和Maintainability特性的討論,描述這些技術解決的問題。算法
Reliability,指的是在任何狀況下,系統正常工做的能力。若是一個系統在發生任何異常時,都能正常的工做,那麼系統是徹底可靠的。現實中,異常種類不少,有的每每難以事先避免,所以,瞭解可能的異常並分析如何在異常發生時快速恢復是很是重要的。通常地,異常包括硬件異常,軟件異常和人爲異常。服務器
硬件異常種類不少,硬盤,電源等任意一個部件的損壞,均可能致使服務器不能正常的工做。一般這類異常難以免,可是,咱們能夠經過一些技術手段來實現異常發生後的快速恢復,不論是從軟件角度仍是硬件角度,基本的解決思路都是冗餘。從硬件角度來說,咱們能夠經過單機冗餘多份硬件,當其中某個硬件發生異常時,能夠快速地用好的硬件替換掉故障的硬件,這種方式的硬件冗餘對於數據中心級的故障是沒有做用的;從軟件角度來說,咱們能夠經過多副本(Replication)來實現快速恢復,當某臺服務器硬件異常時,能夠在軟件層面將流量導入到新的副本上(實際上也有硬件冗餘,但這種方式更爲靈活),除了Replication以外,有時候爲了減小單臺服務器故障對全部用戶的影響,能夠對用戶數據作Partition,單臺服務器只存某一部分用戶的數據,這樣單機故障就只會影響一部分用戶了。引入Replication後,如何保證多副本的數據的一致性又成了一個問題(Consensus),Paxos和Raft算法就是爲了解決這類問題。微信
軟件異常通常指的是系統的bug,這裏面不只包括本身寫的系統的bug,也包括依賴的服務系統的bug。軟件異常一樣也是不能徹底避免的,所以,在發生軟件異常時,也須要有快速恢復的手段,一般有三種方法:架構
在沒有發生致命性問題時,通常採用方法1或2來恢復,當發生的問題比較嚴重,而且沒有已知的方法能繞過期,通常才使用方法3,方法3自己風險也是比較大的,由於修復bug的同時可能會產生新的bug。負載均衡
不論是軟件自己,仍是軟件所運行的服務器,都是由人來管理的,但人是會犯錯誤的,有時候會執行錯誤的命令致使系統不能正常工做,其中比較致命的錯誤可能就是刪掉某臺服務器的數據了,在這種狀況下爲了能快速地恢復,一般也是採用Replication的思路,來避免問題。運維
系統的工做負載一般不是一成不變的,當工做負載增長時,每每能夠經過增長機器資源來保持性能不變,而須要增長機器數量的多少是由系統的擴展性來決定的,擴展性越好的系統,須要增長的機器資源越少。最完美的擴展性是線性擴展性,即工做負載擴大爲原來N倍的時候,只須要加N倍的機器,就可以保持性能不變,最差的擴展性則是沒有擴展性,即工做負載擴大爲原來N倍時,即便加再多的機器,也沒法保持性能和原來同樣。分佈式
對於不一樣的系統,負載所表明的含義一般是不同的,對於基礎架構系統,一般每秒讀和每秒寫的次數,對於業務系統,一般有本身的指標,例如每秒交易建立的筆數。一樣地,對於不一樣的系統,其使用的性能指標一般也是不相同的,對於批處理系統,一般強調的是吞吐量,即每秒完成的任務數量,而對於在線處理系統,一般強調的是響應時間。性能
在明確一個系統的工做負載指標和性能指標以後,咱們才能討論在該系統下如何實現擴展。擴展一般是兩種思路,一是垂直擴展,即便用更好的機器替換現有的機器,二是水平擴展,即便用更多的機器。學習
對於垂直擴展,其優勢是對業務是無影響的,缺點是更好的機器是很貴的,一般是一分錢一分貨,而十分錢只能買到兩分貨,且現實中總有單機裝不下的數據量,此時垂直擴展天然就沒法實施了。設計
對於水平擴展,一般須要軟件層面的配合,對於無狀態的系統,一般只要在新加的機器上部署上須要擴展的系統,而對於有狀態的系統,通常指的是存儲系統,一般會將數據分紅Partition(分區),這樣新加的機器才能經過遷移Partition的方式,從老的機器上遷移數據以及對應的工做負載出來。水平擴展的優勢是使用的都是相對廉價的服務器,能節約成本,但在軟件層面須要作大量的工做,包括Partition的管理,遷移,負載均衡等等。
可維護性的好壞決定了系統是否可以長久的發展,一個可維護性很差的系統,會給運維和開發人員帶來不少不便。對於運維人員來說,可維護性指的是系統是否支持經常使用的運維手段,良好的文檔等等。而對於開發人員來說,主要分爲內核開發以及使用該系統的業務開發,對於業務開發,維護性指的是系統是否有良好的接口,方便業務使用,例如,Transaction就是底層系統提供給業務的一種接口,它保證了在一個事務中執行的語句具備ACID性質,從而業務只須要關注業務邏輯的開發,而不須要關心底層的具體實現;對於內核開發,維護性指的是系統的代碼質量,主要包括代碼的可閱讀性和是否易於修改,主要和系統內核開發人員的代碼設計能力相關。
爲了能達到較好的可靠性(Reliability)、可擴展性(Scalability)和可維護性(Maintainability),分佈式系統設計中一般會使用多副本(Replication)、數據分區(Partition)、一致性算法(Consensus)、事務(Transaction)等技術,理解它們要解決的問題,深刻了解每種技術背後可能的實現方案,有助於評價某個系統的設計好壞,這對於多個競品系統的選型和深刻學習系統原理都是很是有必要的。
本博客更新會在第一時間推送到微信公衆號,歡迎你們關注。