分佈式系統特徵及解決方案

分佈式系統特徵及解決方案node

1、可擴展性
2、可用性
3、一致性
4、高性能算法


一個大型網站就是一個分佈式系統,包含諸多組件,這些組件是分佈式系統的組成部分;而我如今認爲,一個大型網站包含諸多組件,每個組件都是一個分佈式系統,好比分佈式存儲就是一個分佈式系統,消息隊列就是一個分佈式系統。mongodb

可擴展性、高性能、高可用、一致性。這幾個特性也是分佈式系統的衡量指標,正是爲了在不一樣的程度上知足這些特性(或者說達到這些指標),纔會設計出各類各樣的算法、協議,而後根據業務的需求在這些特性間平衡。緩存

爲何要知足這些特性,要知足這些特性須要解決什麼問題,有什麼好的解決方案。服務器

1、可擴展性
  可擴展性是指當系統的任務(work)增長的時候,經過增長資源來應對任務增加的能力。可擴展性是任何分佈式系統必備的特性,這是由分佈式系統的概念決定的:
分佈式系統是由一組經過網絡進行通訊、爲了完成共同的任務而協調工做的計算機節點組成的系統
  分佈式系統的出現是爲了解決單個計算機沒法完成的計算、存儲任務。那麼當任務規模增長的時候,必然就須要添加更多的節點,這就是可擴展性。
  擴展性的目標是使得系統中的節點都在一個較爲穩定的負載下工做,這就是負載均衡,固然,在動態增長節點的時候,須要進行任務(多是計算,多是數據存儲)的遷移,以達到動態均衡。網絡

  那麼首先要考慮的問題就是,如何對任務進行拆分,將任務的子集分配到每個節點,咱們稱這個過程問題Partition(Sharding)。關於Partition,其實我在《帶着問題學習分佈式系統之數據分片 》一文中有詳細介紹,這裏進行概括總結。併發

第一:分片分式,即按照什麼算法對任務進行拆分
  常見的算法包括:哈希(hash),一致性哈希(consistency hash),基於數據範圍(range based)。每一種算法有各自的優缺點,也就有各自的適用場景。負載均衡

第二:分片的鍵,partition key
  partition key是數據的特徵值,上面提到的任何分片方式都依賴於這個partition key,那麼該如何選擇呢
  partition key會影響到任務在分片之間的均衡,並且一些系統中(mongodb)幾乎是不能從新選擇partition key的,所以在設計的時候就得想清楚異步

第三:分片的額外好處
  提高性能和併發:不一樣的請求分發到不一樣的分片
  提升可用性:一個分片掛了不影響其餘的分片分佈式

第四:分片帶來的問題
  若是一個操做須要跨越多個分片,那麼效率就會很低下,好比數據中的join操做

第五:元數據管理
  元數據記錄了分片與節點的映射關係、節點狀態等核心信息,分佈式系統中,有專門的節點(節點集羣)來管理元數據,咱們稱之爲元數據服務器。元數據服務器有如下特色:
  高性能:cache
  高可用:冗餘 加 快速failover
  強一致性(同時只有一個節點對外提供服務)

第六:任務的動態均衡
  爲了達到動態均衡,須要進行數據的遷移,如何保證在遷移的過程當中保持對外提供服務,這也是一個須要精心設計的複雜問題。


2、可用性
可用性(Availability)是系統不間斷對外提供服務的能力,可用性是一個度的問題,最高目標就是7 * 24,即永遠在線。但事實上作不到的,通常是用幾個9來衡量系統的可用性,以下如所示:
  也就是若是要達到4個9的可用度(99.99%),那麼一年之中只能有52.6分鐘不可用,這是個巨大的挑戰
  爲何分佈式系統中必需要考慮可用性呢,這是由於分佈式系統中故障的機率很高。分佈式系統由大量異構的節點和網絡組成,節點可能會crash、斷電、磁盤損壞,網絡可能丟包、延遲、網絡分割。系統的規模放大了出故障的機率,所以分佈式系統中,故障是常態。那麼分佈式系統的其中一個設計目標就是容錯,在部分故障的狀況下仍然對外提供服務,這就是可用性。

冗餘是提升可用性、可靠性的法寶。
  冗餘就是說多個節點負責相同的任務,在須要狀態維護的場景,好比分佈式存儲中使用很是普遍。在分佈式計算,如MapReduce中,當一個worker運行異常緩慢時,master會將這個worker上的任務從新調度到其它worker,以提升系統的吞吐,這也算一種冗餘。但存儲的冗餘相比計算而言要複雜許多,所以主要考慮存儲的冗餘。
  維護同一份數據的多個節點稱之爲多個副本。咱們考慮一個問題,當向這個副本集寫入數據的時候,怎麼保證併發狀況下數據的一致性,是否有一個節點有決定更新的順序,這就是中心化、去中心話副本協議的區別。

中心化與去中心化
  中心化就是有一個主節點(primary master)負責調度數據的更新,其優勢是協議簡單,將併發操做轉變爲順序操做,缺點是primar可能成爲瓶頸,且在primary故障的時候從新選舉會有一段時間的不可用。
  去中心化就是全部節點地位平等,都可以發起數據的更新,優勢是高可用,缺點是協議複雜,要保證一致性很難。
  提到去中心化,比較有名的是dynamo,cassandra,使用了quorum、vector clock等算法來儘可能保證去中心化環境下的一致性。對於去中心化這一塊,目前還沒怎麼學習,因此下面主要討論中心化副本集。對於中心化副本協議,我在《帶着問題學習分佈式之中心化複製集》一文中也有詳細介紹,這裏簡單概括總結。

節點更新策略
  primary節點到secondary節點的數據時同步仍是異步,即客戶端是否須要等待數據落地到副本集中的全部節點。
  同步的優勢在於強一致性,可是可用性和性能(響應延遲)比較差;異步則相反。

數據流向
  即數據是如何從Primary節點到secondary節點的,有鏈式和主從模式。
  鏈式的優勢時充分利用網絡帶寬,減輕primary壓力,但缺點是寫入延遲會大一些。GFS,MongoDB(默認狀況下)都是鏈式。

部分節點寫入異常
  理論上,副本集中的多個節點的數據應該保持一致,所以多個數據的寫入理論上應該是一個事務:要麼都發生,要麼都不發生。可是分佈式事務(如2pc)是一個複雜的、低效的過程,所以副本集的更新通常都是best effort 1pc,若是失敗,則重試,或者告訴應用自行處理。

primary的選舉
  在中心化副本協議中,primary節點是如何選舉出來的,當primary節點掛掉以後,又是如何選擇出新的primary節點呢,有兩種方式:自治系統,依賴其餘組件的系統。(ps,這兩個名字是我杜撰的 。。。)
  所謂的自治系統,就是節點內部自行投票選擇,好比mongodb,tfs,zookeeper
  依賴其餘組件的系統,是指primary由副本集以後的組件來任命,好比GFS中的primary由master(GFS的元數據服務器)任命,hdfs的元數據namenode由zookeeper心跳選出。

secondary是否對外提供服務(讀服務)
 中心化複製集中,secondary是否對外提供讀服務,取決於系統對一致性的要求。
  好比前面介紹到節點更新策略時,多是異步的,那麼secondary上的數據相比primary會有必定延遲,從secondary上讀數據的話沒法知足強一致性要求。
  好比元數據,須要強一致性保證,因此通常都只會從primary讀數據。並且,通常稱主節點爲active(master),從節點爲standby(slave)。在這種狀況下,是經過冗餘 加上 快速的failover來保證可用性。

3、一致性
爲了高可用性,引入了冗餘(副本)機制,而副本機制就帶來了一致性問題。固然,若是沒有冗餘機制,或者不是數據(狀態)的冗餘,那麼不會出現一致性問題,好比MapReduce。

  一致性與可用性在分佈式系統中的關係,已經有足夠的研究,造成了CAP理論。CAP理論就是說分佈式數據存儲,最多隻能同時知足一致性(C,Consistency)、可用性(A, Availability)、分區容錯性(P,Partition Tolerance)中的二者。但一致性和可用性都是一個度的問題,是0到1,而不是隻有0和1兩個極端。
  一致性從系統的角度和用戶的角度有不一樣的等級。

系統角度的一致性
  強一致性、弱一致性、最終一致性

用戶角度的一致性
  單調讀一致性,單調寫一致性,讀後寫一致性,寫後讀一致性

4、高性能
正式由於單個節點的scale up不能完成任務,所以咱們才須要scale out,用大量的節點來完成任務,分佈式系統的理想目標是任務與節點按必定的比例線性增加。

衡量指標
  高併發
  高吞吐
  低延遲
  不一樣的系統關注的核心指標不同,好比MapReduce,自己就是離線計算,無需低延遲

可行的辦法  單個節點的scaleup  分片(partition)  緩存:好比元數據  短事務

相關文章
相關標籤/搜索