身爲二十一世紀的一名程序員,沒據說過度布式系統就顯得本身好像沒有女票同樣尷尬。不管是出去面試跟面試官吹水,仍是在工做中和同事吹水,分佈式系統永遠是你顯得高人一等的籌碼。分佈式系統已經誕生了好幾十年,提及來比咱們八零後程序員好要老成,隨着現代互聯網的崛起,對於系統在性能,可靠性上的要求大大提升。程序員
分佈式系統的定義其實很簡單,也很抽象:任何由處於不一樣物理位置的多個進程提供相同服務的系統均可以稱之爲分佈式系統,退一萬步講,同一臺服務器上的不一樣進程也能夠組成分佈式系統面試
分佈式系統的首要目標是提升系統的總體性能,但不只限於吞吐量,可靠性,響應時間,數據一致性等,其中提升性能指標是最重要的。若是最終設計出來的分佈式系統佔用了更多的資源卻還比不上單機的性能,那這個分佈式系統是失敗的,理論上沒有存在的價值算法
一個分佈式系統的總體性能提升並非單單依靠擴展來實現,提升單機的處理性能仍然很重要,一個把單機性能發揮到極致的分佈式系統,在同等性能的需求下,採用的資源要遠遠小於其餘系統。數據庫
一個好的分佈式系統在性能方面要遠超單機系統,可是在數據行爲方面要表現的和單機系統同樣優秀,其中包括數據的一致性,硬件的故障發生率,網絡的不穩定性等。安全
不管是單機系統仍是分佈式系統都存在沒法迴避而且沒法完全去除的風險,好比:硬盤發生故障,網絡發生癱瘓,光纖被挖.....分佈式系統隨着節點的增長,把這些故障的發生率也隨之增大,因此分佈式系統其中一個目標是要儘可能下降這些風險,也就是所謂的容錯性。服務器
既要快還要不出錯,這在「倫理」上是衝突的。就像咱們平時說的分佈式鎖,若是要保證對一個資源的修改不會發生線程安全問題,就要付出下降性能的代價。至於性能和容錯性怎樣選擇,還須要具體到每一個業務場景中,好比支付場景中,數據的正確性可能要比性能指標更重要,而那些日誌型數據,好比用戶的登陸日誌,這些數據的最大特色就是容許小部分丟失,在這樣的日誌系統設計中,可能性能指標要大於容錯性。網絡
目前爛大街的CAP原則的講解,是針對分佈式系統的一個抽象理論,包括以後BASE理論,也是針對分佈式系統的一種指導方案。架構
分佈式系統的特性就決定了它自出生之日起,就有多個節點如何協同工做的難題。就像一個團隊,若是讓這個團隊有條不紊的工做原本就是個難題。一堆節點爲了完成一樣的任務,註定須要一個規範方圓的規則。就目前已知的方案中,主要有中心化和去中心化兩種解決方案分佈式
中心化的分佈式設計理念是目前主流的方案,在中心化的設計方案中,節點是有角色區分的:Leader節點和Work節點,即:領導和幹活的。就和現實中相似,leader只負責分發任務和監督,Work節點只負責領取任務幹活,多說一句,這裏Work節點領取任務,固然從通訊的角度來講,又能夠分爲push和pull(推和拉)方式。推方式是指,leader節點主動將任務分發給Work節點,拉方式是指:Work節點主動去申請任務。至於push和pull的優缺點,不做爲今天的主題展開討論。性能
在任何系統中,都無可避免的須要考慮節點down掉的問題,分佈式系統也同樣。在中心化分佈式設計中,leader和Work也同樣都存在down掉的可能性。若是leader掉的話,整個系統都陷入癱瘓,按照最簡單的設計思路,leader節點須要一個從節點或者備用節點,在主節點down掉以後,從主節點或者備用主節點能夠手動或者自動實現leader節點服務。至於一個Work節點down掉,通常不會使整個系統陷入癱瘓,除非所有Work節點同時down掉。一個Work節點down掉,可是會影響這個節點當前正在執行的任務,因此在必要的條件下能夠設計成任務須要Ack纔好,即:一個任務的完成須要確認,若是長時間沒有確認,leader會發起從新分配任務的操做。
說到leader的問題,如今目前大多數分佈式系統都具有了自動選舉leader的功能,這還要感謝paxos,raft等選舉算法。在leader不可用的時候,這些系統會自動根據節點狀況選舉出新的leader節點來繼續提供服務,這大大提升了系統可用性。
在全部的中心化設計中,數據的寫操做都發生在leader節點,這在某種程度上相似於單機系統,因此這種中心化設計並不適合那些大量寫的操做。
在去中心化分佈式系統設計中,節點類型並不區分Leader和Work,全部節點都是相等的。因此任何一個節點down掉都不會致使整個系統癱瘓,這是它的優點。可是獲取系統中每一個節點的信息卻比中心化設計要難不少,在中心化設計中,leader節點存儲着系統中全部的節點信息,並能夠實時把這些信息同步到其餘節點,同時能夠利用相應算法來達到一致性的要求。去中心化的設計中,每一個節點只能依靠和其餘節點不斷通訊來獲取整個系統的節點信息,這在技術難度上要比中心化高出不少。
在網絡中,網絡是不可靠的。偏偏是這個緣由,又加大了每一個節點互相通訊的難度。在極限狀況下,去中心化的設計方案會出現多個小範圍的「團伙」,這就是所說的腦裂。好比:如今一個由10個節點組成的分佈式系統,有可能因爲網絡緣由會劃分爲兩個5節點互相通訊的兩個「團伙」
若是出現腦裂的狀況,目前主流的解決方案和數據庫死鎖的處理狀況相似,自爆一個對系統影響比較小的。
徹底中心化和去中心化的系統並不常見,反而如今慢慢出現的是兩者的搭配者,表面看似去中心化,設計理念倒是中心化的思路,在這種架構下,leader是程序根據某種算法選舉出來的,並且在系統leader發生故障的時候,系統會自動從新選舉leader節點。
對於每一個系統來講,可靠性是它要實現的主要目標之一,尤爲是分佈式系統。在網絡通訊,硬件設備等條件都非100%可靠的狀況下,如何提升分佈式系統的可用性是一個很深的話題。就算是國內頂尖的BAT等大廠,也沒有一個系統能達到100%的可用性,4個9的可用性已是很巔峯了。
分佈式系統本質上是多個節點經過網絡IO組成的,其中夾雜着一些不可抗拒的元素,因此請記住一句話:
分佈式系統是不可靠的,咱們只能儘可能減少故障發生率,卻根除不了,若是你的老闆要你設計一套100%可用性的系統,要麼他是二貨,要麼他是二B