分佈式系統是由一組經過網絡進行通訊、爲了完成共同的任務而協調工做的計算機節點組成的系統。分佈式系統的出現是爲了用廉價的、普通的機器完成單個計算機沒法完成的計算、存儲任務。其目的是利用更多的機器,處理更多的數據。html
首先須要明確的是,只有當單個節點的處理能力沒法知足日益增加的計算、存儲任務的時候,且硬件的提高(加內存、加磁盤、使用更好的CPU)高昂到得不償失的時候,應用程序也不能進一步優化的時候,咱們才須要考慮分佈式系統。由於,分佈式系統要解決的問題自己就是和單機系統同樣的,而因爲分佈式系統多節點、經過網絡通訊的拓撲結構,會引入不少單機系統沒有的問題,爲了解決這些問題又會引入更多的機制、協議,帶來更多的問題。。。java
在不少文章中,主要講分佈式系統分爲分佈式計算(computation)與分佈式存儲(storage)。計算與存儲是相輔相成的,計算須要數據,要麼來自實時數據(流數據),要麼來自存儲的數據;而計算的結果也是須要存儲的。在操做系統中,對計算與存儲有很是詳盡的討論,分佈式系統只不過將這些理論推廣到多個節點罷了。網絡
那麼分佈式系統怎麼將任務分發到這些計算機節點呢,很簡單的思想,分而治之,即分片(partition)。對於計算,那麼就是對計算任務進行切換,每一個節點算一些,最終彙總就好了,這就是MapReduce的思想;對於存儲,更好理解一下,每一個節點存一部分數據就好了。當數據規模變大的時候,Partition是惟一的選擇,同時也會帶來一些好處:
(1)提高性能和併發,操做被分發到不一樣的分片,相互獨立
(2)提高系統的可用性,即便部分分片不能用,其餘分片不會受到影響架構
理想的狀況下,有分片就好了,但事實的狀況卻不大理想。緣由在於,分佈式系統中有大量的節點,且經過網絡通訊。單個節點的故障(進程crash、斷電、磁盤損壞)是個小几率事件,但整個系統的故障率會隨節點的增長而指數級增長,網絡通訊也可能出現斷網、高延遲的狀況。在這種必定會出現的「異常」狀況下,分佈式系統仍是須要繼續穩定的對外提供服務,即須要較強的容錯性。最簡單的辦法,就是冗餘或者複製集(Replication),即多個節點負責同一個任務,最爲常見的就是分佈式存儲中,多個節點複雜存儲同一份數據,以此加強可用性與可靠性。同時,Replication也會帶來性能的提高,好比數據的locality能夠減小用戶的等待時間。併發
下面這種來自Distributed systems for fun and profit 的圖形象生動說明了Partition與Replication是如何協做的。
分佈式
Partition和Replication是解決分佈式系統問題的一記組合拳,不少具體的問題均可以用這個思路去解決。但這並非銀彈,每每是爲了解決一個問題,會引入更多的問題,好比爲了可用性與可靠性保證,引用了冗餘(複製集)。有了冗餘,各個副本間的一致性問題就變得很頭疼,一致性在系統的角度和用戶的角度又有不一樣的等級劃分。若是要保證強一致性,那麼會影響可用性與性能,在一些應用(好比電商、搜索)是難以接受的。若是是最終一致性,那麼就須要處理數據衝突的狀況。CAP、FLP這些理論告訴咱們,在分佈式系統中,沒有最佳的選擇,都是須要權衡,作出最合適的選擇。性能
分佈式系統須要大量機器協做,面臨諸多的挑戰:
學習
分佈式系統中的機器,配置不同,其上運行的服務也可能由不一樣的語言、架構實現,所以處理能力也不同;節點間經過網絡鏈接,而不一樣網絡運營商提供的網絡的帶寬、延時、丟包率又不同。怎麼保證你們齊頭並進,共同完成目標,這四個不小的挑戰。
優化
雖然單個節點的故障機率較低,但節點數目達到必定規模,出故障的機率就變高了。分佈式系統須要保證故障發生的時候,系統仍然是可用的,這就須要監控節點的狀態,在節點故障的狀況下將該節點負責的計算、存儲任務轉移到其餘節點
spa
節點間經過網絡通訊,而網絡是不可靠的。可能的網絡問題包括:網絡分割、延時、丟包、亂序。
相比單機過程調用,網絡通訊最讓人頭疼的是超時:節點A向節點B發出請求,在約定的時間內沒有收到節點B的響應,那麼B是否處理了請求,這個是不肯定的,這個不肯定會帶來諸多問題,最簡單的,是否要重試請求,節點B會不會屢次處理同一個請求。
總而言之,分佈式的挑戰來自不肯定性,不肯定計算機何時crash、斷電,不肯定磁盤何時損壞,不肯定每次網絡通訊要延遲多久,也不肯定通訊對端是否處理了發送的消息。而分佈式的規模放大了這個不肯定性,不肯定性是使人討厭的,因此有諸多的分佈式理論、協議來保證在這種不肯定性的狀況下,系統還能繼續正常工做。
分佈式系統並不是靈丹妙藥,解決問題的關鍵仍是看你對問題自己的瞭解。一般咱們須要使用分佈式的常見理由是:
爲了性能擴展——系統負載高,單臺機器沒法承載,但願經過使用多臺機器來提升系統的負載能力
爲了加強可靠性——軟件不是完美的,網絡不是完美的,甚至機器自己也不多是完美的,隨時可能會出錯,爲了不故障,須要將業務分散開保留必定的冗餘度。在以提供 Service 爲主的服務端軟件開發過程當中經常遇到這些問題。
籠統的討論分佈式沒有太大的意義,就如我剛纔所談的,實際上分佈式很容易實現。真正難的地方在於如何選擇正確的分佈方案。
例如,當你想要創建一個分佈式的數據管理系統的時候,你就必須得面對「一致性」問題。若是你對數據一致性要求很高,你就不得不容忍一些缺陷例如規模伸縮困難;而若是你放棄它,你能夠輕鬆伸縮規模,但你必須解決好由此帶來的一系列數據不一致致使的問題。(CAP 問題)
因而你會意識到,有許多種分佈方案,爲了正確解決你的問題,你須要對每個方案都進行了解,並評估,選擇不一樣的方案有時候區別不大,有時候卻會深入的影響整個系統中其餘部分的工做方式,甚至影響用戶界面中用戶操做時的流程。這是咱們學習分佈式系統的重點所在。
如我前面所講,分佈式入門不難。主要包含以下知識點:
Process(進程)。在分佈式系統中,進程是基本單元。
通訊協議。Process 間須要相互配合才能完成工做,所以通訊協議是最基本要解決的問題。這部分其實挺複雜,牽涉面光,不過核心仍是抓住兩方面,一是存在哪些需求,二是各個協議如何知足這些需求命名法。兩個 Process 要通訊,必須相互知道對方的名字,名字能夠是數字,也能夠是結構化的字符串。例如衆所周知域名系統就是一種命名方案,可是方案還有不少,各有特色協做。
上面都在談 Process 之間的通訊,但是爲何要通訊?由於要協做。協做是個複雜的主題,其中最基本最基本的一個問題就是同步問題。而聊同步問題必然要聊「鎖」……知識點就這麼展開了。
上面幾點是最基礎的知識。瞭解了這些其實就算入門了。但是如何進階呢?那麼必然要開始學習下面的問題:
一致性。數據存儲時,最基本的問題。其實也是實際設計系統時經常須要反覆考慮的問題
容錯。冗餘是容錯的基礎,但並非所有,分佈式自己爲實現容錯提供了一些便利,這也是實際設計系統時經常須要考慮的問題
以上都是分佈式系統的理論基礎,上海尚學堂Java學科在年前作了重大改進更新,加入了分佈式系統課程,詳情能夠點擊 上海java培訓 查看上海尚學堂Java課程大綱和詳情。獲取免費資料或者試聽資格能夠聯繫客服諮詢。
本文參考:xybaby https://www.cnblogs.com/xybab...