關於分布式系統的思考(二)

2021-09-17 08:32:44 字數 2674 閱讀 3183

一種是中心化的,由中心節點去儲存集群資訊並管理集群狀態,其它節點只需響應資料請求,而無需知道集群中其它節點的情況。

這種模式的核心便是選舉或者指定乙個節點作為集群的管理者,由管理者去協調跨節點的操作、備份資料和處理故障等。

一般的,對於跨節點的操作,為了保證事務的原子性,提出了兩步提交協議或三步提交協議,下面分別介紹。

兩步提交協議,顧名思義,就是將資料的提交分為兩步:投票和決策。

首先,在第一階段,

中心節點(在這裡我們稱之為協調者)發起事務操作請求,包含事務內容,詢問是否可以執行提交操作並等待響應;

其它節點(在這裡稱之為參與者)執行事務操作並記錄undo/redo log,最後返回是否同意提交。

然後,在第二階段,協調者根據所有參與者的投票結果,如果是都同意則通知所有參與者提交事務,否則回滾事務。

收到所有參與者回應後,完成事務。

接著,我們考慮下兩步提交過程中如果發生異常,會出現什麼樣的情況,會不會影響結果的一致性,並嘗試解決。

注意,以上的宕機如果替換為網路分割槽,也會是同樣的情況。

可以看出,2pc的優點是簡單直接,缺點是:

針對這些缺陷,出現了3pc。

三步提交協議,改進了2pc的一些缺陷,它增加了乙個詢問是否可提交階段。如圖所示:

第一階段時,協調者詢問各參與者是否可以執行事務提交,包含事務內容,並等待參與者的響應。

參與者收到請求後,如果認為可以成功執行事務,則返回同意,否則中止事務。

第二階段時,協調者根據第一階段參與者的返回訊息,決定是準備提交或是中止事務。如果都是同意,那麼傳送預提交請求。

參與者收到請求後,會執行事務操作,並記錄undo/redo log, 最後返回提交/中止事務。

第三階段時,協調者根據第二階段的響應,決定通知參與者提交/回滾事務,收到響應後完成事務。

3pc相比於2pc的優點在於:

缺點:比2pc多了乙個階段,意味著同等情況下,耗時要多一點。

另一種則是去中心化的,由節點之間互相通訊去協商一致。比較有名的演算法如paxos。

paxos演算法在分布式領域具有非常重要的地位,google chubby的作者mike burrows曾經說過,這個世界上只有一種一致性演算法,那就是paxos,其它的都是殘次品。

不過這個演算法實在是難理解,難實現;以後有機會我會專門總結一篇文章分享下,有興趣的道友可以先去看看《paxos made ******》,寫得很不錯。

此外,考慮到集群中的節點數量並不是一成不變的,所以如果使用的是一般的hash演算法,那麼在集群新增節點或刪除節點時,會導致節點間大量資料的遷移,進而影響可用性,故而提出了一致性hash演算法以減少資料的遷移量。

一般的hash演算法,如對key取模然後分散到不同的節點中:假設有3個節點,共有key分別為1~7的資料,分配結果如下圖

現在,如果新增乙個節點,那麼分配結果變為:

可以發現大部分的節點都被重新分配到了不同的節點上,即遷移資料是o(n)複雜度(n為資料總量),無法平滑地擴縮容。

接下來再來看下一致性hash,它的分配方式是對key和節點做相同的hash運算,然後將key分配到剛好大於或等於它hash值的節點上(若節點都比它hash值小,則分配到最小的節點上,即形成乙個「環」);

還是上面的那個例子,對key和節點都做對7取模的hash計算,然後分配。先是有三個節點:

新增乙個節點:

可以看出,增加乙個節點後只有少量資料從5節點移動到4節點,極大的減少了資料遷移量。

但是,一致性hash也有缺陷:查詢效率低。一般需要逐個去比較hash值直到找到剛好大於等於的節點,故查詢複雜度為o(k)(k為節點數量)。

可以通過在節點中冗餘乙份節點表來加快查詢。

保證一致性,要麼是通過共享儲存,要麼是通過訊息協調。

資料庫本身就是共享儲存。

不管是2pc、3pc還是paxos,都是通過節點間的交換訊息去達到一致的狀態,這也是分布式系統的常用做法。

了解了這些策略的原理後,不管是用zookeeper、rabbitmq、redis或其它訊息元件(甚至是基於socket通訊)去實現它,都是水到渠成的事情了。

超時是個好設計,因為它是不需詢問便可以察覺錯誤的方式(畢竟沒有錯誤就不會超時了),很多設計中都會將超時作為一種訊號,並嘗試容錯/修復等操作。

在執行過程的一些錯誤並不能通過底層的策略完全規避,需要根據具體業務在上層做相應的容錯措施。

冗餘是個好設計,幾乎在各種元件的設計都能見到,通過犧牲一點空間較大地提高檢索效率。

有機會的話,之後的篇章我會收集並比較幾種典型分布式元件的具體實現,對這些元件有個更加直觀和深入的理解,以便充實和改進自己的知識結構並分享出來。

最後為方便查詢,整理了下往期文章到github中:

作者資訊

本文係力譜宿雲leapcloud旗下maxleap團隊_基礎服務組成員:呂舜 【原創】

力譜宿雲leapcloud 首發:

微服務實戰:從架構到發布(一)

微服務實戰:從架構到發布(二)

移動雲平台的基礎架構之旅(一):雲應用

從應用到平台 – 雲服務架構的演進過程

作者往期佳作

rabbitmq在分布式系統的應用

關於分布式系統的思考

關於分布式檔案儲存系統問題的自我思考

1.前言 其實站在使用者的角度思考 其需求功能非常簡單,能成功快速增刪讀寫檔案就ok了,如同操作本地的單機檔案系統一樣簡單。例如如下 a.讀取檔案操作,read函式 ssize t read int fd,void buf,size t count b.寫入檔案操作,write函式 ssize t ...

分布式 分布式系統的設計

在計算機領域,當單機效能達到瓶頸時,一般有兩種方式解決效能問題 而分布式系統的設計說白了就是 如何合理將乙個系統拆分成多個子系統部署到不同機器上。講設計方法前,先介紹分布式系統的特性 1 分布性 空間中隨機分布。這些計算機可以分布在不同的機房,不同的城市,甚至不同的國家。2 對等性 分布式系統中的計...

排隊系統利用分布式設計的思考

從分布式系統設計來進行設計排隊系統。它有以下特點 目的只是控制流量,所以如果一定程度的資料不一致的最糟結果只是進入順序不一致,或者多進入10 的使用者,都是可以容忍的。雖然不追求毫秒級的響應,但是系統處理的速度越快,對系統的壓力也就越小。所以還是盡量低。要能承受巨大請求壓力。排隊的資料本身有一定的臨...