分佈式體系結構之非集中式結構

前言

上文介紹了分佈式體系結構中的集中式結構,目前很多雲上的管理都採用了集中式結構,但是這種結構對中心服務器性能要求很高,而且存在單點瓶頸和單點故障問題。爲了解決這個問題,分佈式領域中又出現了另一經典的系統結構,即非集中式結構,也叫作分佈式結構。

1、非集中式結構概述

在非集中式結構中,服務的執行和數據的存儲被分散到不同的服務器集羣,服務器集羣間通過消息傳遞進行通信和協調。
也就是說,在非集中式結構中,沒有中央服務器和節點服務器之分,所有的服務器地位都是平等(對等)的。相比於集中式結構,非集中式結構就降低了某一個或者某一簇計算機集羣的壓力,在解決了單點瓶頸和單點故障問題的同時,還提升了系統的併發度,比較適合大規模集羣的管理。
所以近幾年來,Google、 Amazon、Facebook、阿里巴巴、騰訊等互聯網公司在一些業務中也相繼採用了非集中式結構。

2、典型非集中式結構

下面重點介紹 3 種典型的非集中式架構系統,包括: Akka 集羣Redis 集羣Cassandra 集羣,來進一步的理解非集中式架構。

2.1 Akka 集羣

2.1.1 Actor 模型

首先來了解一下Akka 框架,它是基於 Actor 模型,提供了一個用於構建可擴展的、彈性的、快速響應的應用程序的平臺。
其中,Actor 是一個封裝了狀態和行爲的對象,它接收消息並基於該消息執行計算。Actor 之間互相隔離,不共享內存,但 Actor 之間可通過交換消息(mail)進行通信(每個 Actor 都有自己的 MailBox)
比如,在分佈式系統中,一個服務器或一個節點可以視爲一個 Actor,Actor 與 Actor 之間採用 mail 進行通信,如下圖所示:
在這裏插入圖片描述
如上圖所示,Actor 發送的 Mail 消息會存儲在接收方的 MailBox 中。默認情況下,接收方按照 mail 到達的先後順序,從 MailBox 中提取 mail 消息,並進行相應的計算處理。
Actor 模型爲系統併發度提供了非常好的解決方案,且是一個異步的、非阻塞的、高性能的事件驅動編程模型。Akka 集羣充分利用了 Actor 模型的優勢,提供了一個非集中式架構的集羣管理模塊,用來構建可擴展的、彈性的分佈式應用程序。
Akka 集羣負責 Actor 模型底層的節點管理,包括故障檢測、節點加入 / 退出集羣等。也就是說,Akka 集羣爲 Actor 模型提供了一個可容錯、去中心化的節點集羣管理系統,來保證 Actor 的運行和 Actor 之間的通信。

2.1.2 Akka 集羣架構

如下圖所示,Akka 集羣是一個完全去中心化的分佈式集羣管理系統。一個集羣由多個節點組成,每個節點都可以進行數據處理和任務執行,節點之間均可進行通信。節點有 Leader 節點和非 Leader 節點之分。與非 Leader 節點相比,Leader 節點只是增加了負責節點的加入和移除集羣的功能,所以並不會影響非集中式結構中節點的平等關係。
在這裏插入圖片描述Akka 集羣的兩個重點是:數據傳輸和集羣組建及管理,所以接下來將從這兩個方面介紹 Akka 集羣。

2.1.3 Akka 集羣數據傳輸和組件及管理

2.1.3.1 Akka 集羣數據傳輸

在 Akka 集羣中,節點是對等的,也就是說每個節點是可以併發處理的,因此必然存在數據傳輸和一致性的問題。
比如,我們要針對數據進行操作,將 X=1 修改爲 X=2。現在集羣中節點 1 進行了修改使得 X=2,但其他節點上還是 X=1,因此節點 1 需要將 X=2 的消息告知其他節點,以保證最終集羣中所有節點上均爲 X=2。
其實,這個問題就是分佈式共識問題,在之前的文章中也集中介紹了: PoWPoSDPoS 三種達成共識的方法。
==Akka 集羣主要採用的辦法是誰的時間戳最新(也就是數據最新),就以誰爲準的原則
還是以上面的例子說明,如何將 X=2 這個消息傳輸給集羣中的每個節點。Akka 集羣採用了 Gossip 協議,該協議是最終一致性協議。它的原理是:

  • 每個節點週期性地從自己維護的集羣節點列表中,隨機選擇 k 個節點,將自己存儲的數據信息發給這 k個節點;
  • 接收到該信息的節點根據共識原則,對收到的數據和本地數據進行合併;
  • 通過幾個週期迭代後,集羣中所有節點上的數據信息就一致了。
    其實這就是我們平常說的“一傳十十傳百”的道理是一樣的。
2.1.3.2 Akka 集羣組建及管理

Akka 在創建集羣時,節點被分爲三種類型,即:

  • 種子節點:使用靜態配置文件方式或者系統運行時指定方式,可以生成種子節點;種子節點是普通節點加入集羣的聯繫點,可以自動接收新加入集羣的節點的信息。
  • 首種子節點:首種子節點是配置文件中的第一個種子節點,其功能是集羣第一次啓動時,首種子節點啓動起來,集羣才能組建成功,保證集羣第一次創建時只有一個集羣。如下圖A 節點,就是 Akka 集羣的首種子節點
  • 普通節點:可以向種子節點或集羣中的任意節點發送 Join 消息,請求加入集羣。如下圖的 B 和 C 節點,通過向 A 節點發送 Join 消息,從而加入到 Akka 集羣
    在這裏插入圖片描述
    Akka 集羣的每個節點啓動後,讀取配置文件獲取種子節點列表,然後開始組建集羣:
  • 如果本節點爲首種子節點,則把自己加入到集羣列表中,即以自己爲中心構建集羣;
  • 如果本節點爲種子節點,則向首種子節點請求加入集羣,當首種子節點回復同意消息後,可以加入集羣,否則不可加入集羣;
  • 如果本節點爲普通節點,則可以向任一種子節點(包括首種子節點)請求加入集羣,收到同意後,則加入集羣,否則不可加入集羣。

***加入首種子節點或種子節點的節點信息,會通過 Gossip 協議的傳播方式傳播給當前已加入的所有節點,以完成集羣組建。當集羣組建完成後,就不存在種子節點與普通節點之分了,每個節點均可執行 Actor 應用程序。***

2.1.4 Akka 集羣小結

  • Akka 集羣是一個完全去中心化的集羣管理系統,當集羣組建完成後,每個節點均可執行 Actor 應用程序,因此支持併發操作。
  • Akka集羣採用了 Gossip 協議進行數據同步,通過誰的時間戳最新就以誰爲準,來解決一致性問題。

2.2 Redis 集羣

2.2.1 分佈式存儲集羣管理-Redis

除了面向應用程序平臺的分佈式集羣管理之外,分佈式數據存儲也是一個非常重要的話題。下文以開源數據庫 Redis 的集羣管理系統爲例來介紹分佈式數據存儲中的集羣管理。
Redis 是一個開源的高性能分佈式 key-value 數據庫,應用廣泛,其特徵主要表現爲:

  • 支持數據的持久化,可以將內存中的數據保存在磁盤中,重啓時可以再次加載並使用;
  • 支持多種數據結構,不僅支持簡單的 key-value類型的數據,同時還提供 list、set、hash 等數據結構的存儲;
  • 支持數據的備份,即 Master/Slave 模式的數據備份。
    Redis 的這些特徵均是爲數據存儲進行服務的,數據可分片存儲在不同的 Redis 節點上,多個 Redis 節點間可共享數據,而提供這項能力的就是 Redis 集羣。
    Redis 集羣中不存在中央節點,是典型的去中心化結構,每個節點均可與其他節點通信。所有節點均可負責存儲數據、記錄集羣的狀態(包括鍵值到正確節點的映射),客戶端可以訪問或連接到任一節點上。集羣節點同樣能自動發現其他節點,檢測故障的節點,並在需要的時候在從節點中推選出主節點。Redis 集羣的架構圖如下所示。
    當然,節點之間的數據傳輸仍採用了 Gossip 協議,來保證集羣中數據的最終一致性。
    在這裏插入圖片描述
    Redis 集羣中的節點用於數據存儲,所以在設計時,需要考慮數據的可靠性分片存儲問題:
  • 可靠性問題:集羣中每個節點均存在主備,也就是說每臺服務器上都運行兩個 Redis 服務,分別爲主備,主故障後,備升主。
  • 數據的分片存儲:Redis 集羣引入了哈希槽的概念。Redis 集羣內置了 16384 個哈希槽,每個節點負責一部分哈希槽。(比如:A 包含 0 到 5500 號哈希槽、節點 B 包含 5501 到 11000 號哈希槽、節點 C 包含 11001 到 16383 號哈希槽)當客戶端要存儲一個數據或對象時,對該對象的 key 通過 CRC16 校驗後對 16384 取模,也就是 HASH_SLOT = CRC16(key) mod 16384 來決定哈希槽,從而確定存儲在哪個節點上。

Redis 集羣採用集羣分片方式實現了數據的分片存儲,從而將 Redis 的寫操作分攤到了多個節點上,提高了寫併發能力。

2.2.2 Redis 小結

Redis 集羣是一個非集中式集羣管理系統,沒有中心節點,不會因爲某個節點造成性能瓶頸,每個節點均支持數據存儲,且採用分片存儲方式,提高了寫的併發能力。同時,每個節點的設計採用主備設計,提高了數據的可靠性。
鑑於這些優點,Redis 已被 Twitter、Uber、GitHub、Instagaram 等公司採用。

2.3 Cassandra 集羣

Cassandra 也支持數據的分佈式存儲和操作,與 Redis 集羣類似。
如下圖所示,Cassandra 集羣的系統架構是基於一致性哈希的完全 P2P 結構,沒有 Master 的概念,所有節點都是同樣的角色,徹底避免了因爲單點問題導致的系統不穩定。Cassandra 集羣節點間的狀態同步,也是通過 Gossip 協議來進行 P2P 通信的。
在這裏插入圖片描述
集羣中的每個節點,都可以存儲數據,並接收來自客戶端的請求。
Cassandra 集羣數據存儲與 Redis 的不同之處是

  • Redis 集羣每個節點代表一部分哈希槽,一個哈希槽代表一個哈希值區間,而 Cassandra 集羣中每個節點代表一個哈希值。
  • 在 Cassandra 集羣中,每次客戶端隨機選擇集羣中的一個節點來請求數據,對應接收請求的節點將對應的 key 在一致性哈希環上定位出是哪些節點應該存儲這個數據,然後將請求轉發到對應的節點上,並將對應若干節點的查詢反饋返回給客戶端。
    目前,Cassandra 集羣因爲完全去中心化的結構模式,已經被 Apple、Comcast、Instagram、Spotify、eBay、Netflix 等公司使用。

2.3.1 Cassandra 集羣小結

  • Cassandra 採用去中心化的架構,解決了集中式結構的單點故障問題,同時因爲數據基於哈希值分區存儲,提高了讀寫數據的併發能力。
  • 在Cassandra 集羣中,沒有 Master 的概念,每個節點代表一個哈希值,通過哈希映射的方式決定數據存儲的位置。
  • 集羣間的狀態同步通過 Gossip 協議來進行 P2P 的通信。

3、總結

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章