国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【分布式】分布式存儲架構

這篇具有很好參考價值的文章主要介紹了【分布式】分布式存儲架構。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、集中存儲結構

說到分布式存儲,我們先來看一下傳統(tǒng)的存儲是怎么個樣子。

傳統(tǒng)的存儲也稱為集中式存儲, 從概念上可以看出來是具有集中性的,也就是整個存儲是集中在一個系統(tǒng)中的,但集中式存儲并不是一個單獨的設備,是集中在一套系統(tǒng)當中的多個設備,比如下圖中的 EMC 存儲就需要幾個機柜來存放。
【分布式】分布式存儲架構

在這個存儲系統(tǒng)中包含很多組件,除了核心的機頭(控制器)、磁盤陣列( JBOD )和交換機等設備外,還有管理設備等輔助設備。

結構中包含一個機頭,這個是存儲系統(tǒng)中最為核心的部件。通常在機頭中有包含兩個控制器,互為備用, 避免硬件故障導致整個存儲系統(tǒng)的不可用。機頭中通常包含前端端口和后端端口,前端端口用戶為服務器提供存儲服務,而后端端口用于擴充存儲系統(tǒng)的容量。通過后端端口機頭可以連接更多的存儲設備,從而形成一個非常大的存儲資源池。

在整個結構中,機頭中是整個存儲系統(tǒng)的核心部件,整個存儲系統(tǒng)的高級功能都在其中實現(xiàn)??刂破髦械能浖崿F(xiàn)對磁盤的管理,將磁盤抽象化為存儲資源池,然后劃分為 LUN 提供給服務器使用。這里的 LUN 其實就是在服務器上看到的磁盤 。當然,一些集中式存儲本身也是文件服務器,可以提供共享文件服務。無論如何,從上面我們可以看出集中式存儲 最大的特點是有一個統(tǒng)一的入口,所有數(shù)據(jù)都要經過這個入口 ,這個入口就是存儲系統(tǒng)的機頭。這也就是集中式存儲區(qū)別于分布式存儲最顯著的特點。如下圖所示:
【分布式】分布式存儲架構

二、分布式存儲

分布式存儲最早是由谷歌提出的,其目的是通過廉價的服務器來提供使用與大規(guī)模,高并發(fā)場景下的 Web 訪問問題。它采用可擴展的系統(tǒng)結構,利用多臺存儲服務器分擔存儲負荷,利用位置服務器定位存儲信息,它不但提高了系統(tǒng)的可靠性、可用性和存取效率,還易于擴展。

2.1 、分布式存儲的興起

分布式存儲的興起與互聯(lián)網(wǎng)的發(fā)展密不可分,互聯(lián)網(wǎng)公司由于其數(shù)據(jù)量大而資本積累少,而通常都使用大規(guī)模分布式存儲系統(tǒng)。

與傳統(tǒng)的高端服務器、高端存儲器和高端處理器不同的是,互聯(lián)網(wǎng)公司的分布式存儲系統(tǒng)由數(shù)量眾多的、低成本和高性價比的普通 PC 服務器通過網(wǎng)絡連接而成。其主要原因有以下三點

  1. 互聯(lián)網(wǎng)的業(yè)務發(fā)展很快,而且注意成本消耗,這就使得存儲系統(tǒng)不能依靠傳統(tǒng)的縱向擴展的方式,即先買小型機,不夠時再買中型機,甚至大型機。互聯(lián)網(wǎng)后端的分布式系統(tǒng)要求支持橫向擴展,即通過增加普通 PC 服務器來提高系統(tǒng)的整體處理能力。

  2. 普通 PC 服務器性價比高,故障率也高,需要在軟件層面實現(xiàn)自動容錯,保證數(shù)據(jù)的一致性。

  3. 另外,隨著服務器的不斷加入,需要能夠在軟件層面實現(xiàn)自動負載均衡,使得系統(tǒng)的處理能力得到線性擴展。

2.2 、分布式存儲的重要性

從單機單用戶到單機多用戶,再到現(xiàn)在的網(wǎng)絡時代,應用系統(tǒng)發(fā)生了很多的變化。而分布式系統(tǒng)依然是目前很熱門的討論話題,那么,分布式系統(tǒng)給我們帶來了什么,或者說是為什么要有分布式系統(tǒng)呢?

  • 升級單機處理能力的性價比越來越低;

    企業(yè)發(fā)現(xiàn)通過更換硬件做垂直擴展的方式來提升性能會越來越不劃算;

  • 單機處理能力存在瓶頸;

    某個固定時間點,單顆處理器有自己的性能瓶頸,也就說即使愿意花更多的錢去買計算能力也買不到了;

  • 出于穩(wěn)定性和可用性的考慮

    如果采用單擊系統(tǒng),那么在這臺機器正常的時候一切 OK ,一旦出問題,那么系統(tǒng)就完全不能用了。當然,可以考慮做容災備份等方案,而這些方案就會讓系統(tǒng)演變?yōu)榉植际较到y(tǒng)了;

  • 云存儲和大數(shù)據(jù)發(fā)展的必然要求

    云存儲和大數(shù)據(jù)是構建在分布式存儲之上的應用。移動終端的計算能力和存儲空間有限,而且有在多個設備之間共享資源的強烈的需求,這就使得網(wǎng)盤、相冊等云存儲應用很快流行起來。然而,萬變不離其宗,云存儲的核心還是后端的大規(guī)模分布式存儲系統(tǒng)。大數(shù)據(jù)則更近一步,不僅需要存儲海量數(shù)據(jù),還需要通過合適的計算框架或者工具對這些數(shù)據(jù)進行分析,抽取其中有價值的部分。如果沒有分布式存儲,便談不上對大數(shù)據(jù)進行分析。仔細分析還會發(fā)現(xiàn),分布式存儲技術是互聯(lián)網(wǎng)后端架構的神器,掌握了這項技能,以后理解其他技術的本質會變得非常容易。

2.3 、分布式存儲的種類和比較

分布式存儲包含的種類繁多,除了傳統(tǒng)意義上的分布式文件系統(tǒng)、分布式塊存儲和分布式對象存儲外,還包括分布式數(shù)據(jù)庫和分布式緩存等,但其中架構無外乎于三種

  • 中間控制節(jié)點架構
    以 HDFS ( Hadoop Distribution File System )為代表的架構是典型的代表。在這種架構中,一部分節(jié)點 NameNode 是存放管理數(shù)據(jù)(元數(shù)據(jù)),另一部分節(jié)點 DataNode 存放業(yè)務數(shù)據(jù),這種類型的服務器負責管理具體數(shù)據(jù)。這種架構就像公司的層次組織架構, namenode 就如同老板,只管理下屬的經理( datanode ),而下屬的經理,而經理們來管理節(jié)點下本地盤上的數(shù)據(jù)。

    【分布式】分布式存儲架構

    在上圖中, 如果客戶端需要從某個文件讀取數(shù)據(jù),首先從 NameNode 獲取該文件的位置(具體在哪個 DataNode ),然后從該 NameNode 獲取具體的數(shù)據(jù)。在該架構中 NameNode 通常是主備部署( Secondary NameNode ),而 DataNode 則是由大量節(jié)點構成一個集群。由于元數(shù)據(jù)的訪問頻度和訪問量相對數(shù)據(jù)都要小很多,因此 NameNode 通常不會成為性能瓶頸,而 DataNode 集群中的數(shù)據(jù)可以有副本,既可以保證高可用性,可以分散客戶端的請求。因此,通過這種分布式存儲架構可以通過橫向擴展 datanode 的數(shù)量來增加承載能力,也即實現(xiàn)了動態(tài)橫向擴展的能力。

  • 完全無中心架構 – 計算模式
    以 Ceph 為代表的架構是其典型的代表。在該架構中與 HDFS 不同的地方在于該架構中沒有中心節(jié)點??蛻舳耸峭ㄟ^一個設備映射關系 計算出來 其寫入數(shù)據(jù)的位置,這樣客戶端可以直接與存儲節(jié)點通信,從而避免中心節(jié)點的性能瓶頸。

    【分布式】分布式存儲架構

    如上圖所示, 在 Ceph 存儲系統(tǒng)架構中核心組件有 MON 服務、 OSD 服務和 MDS 服務等。

    • MON 服務用于維護存儲系統(tǒng)的硬件邏輯關系,主要是服務器和硬盤等在線信息。MON 服務通過集群的方式保證其服務的可用性。

    • OSD 服務用于實現(xiàn)對磁盤的管理,實現(xiàn)真正的數(shù)據(jù)讀寫,通常一個磁盤對應一個 OSD 服務。

    • MDS 只為 CephFS 文件存儲系統(tǒng)跟蹤文件的層次機構和存儲元數(shù)據(jù)。Ceph 塊設備和 RADOS 并不需要元數(shù)據(jù),因此也不需要 Ceph MDS 守護進程

    • RADOS :RADOS 就是包含上述三種服務的 ceph 存儲集群。在 Ceph 中所有的數(shù)據(jù)都以對象形式存在的,并且無論哪種數(shù)據(jù)類型 RADOS 對象存儲都將負責保存這些對象。RADOS 層可以確保數(shù)據(jù)始終保持一致性。要做到這一點必須執(zhí)行數(shù)據(jù)復制、故障檢測和恢復,以及數(shù)據(jù)遷移和所在集群節(jié)點實現(xiàn)在平衡

    • RBD (塊設備):原名 RADOS 塊設備,提供可靠的分布式和高性能塊存儲磁盤給客戶端。

    • CephFS :Ceph 文件系統(tǒng)提供了一個使用 Ceph 存儲集群存儲用戶數(shù)據(jù)的與 POSIX 兼容的文件系統(tǒng)

    • Librados :libRADOS 庫為 PHP 、 RUBY 、 Java 、 Python 、 C++ 等語言提供 了方便的訪問 RADOS 接口的方式

    • RADOS GW :RGW 提供對象存儲服務,它允許應用程序和 Ceph 對象存儲建立連接, RGW 提供了與 Amazon S3 和 openstack Swift 兼容的 RUSTFUL API

    客戶端訪問存儲的大致流程是,客戶端在啟動后會首先通過 RADOS GW 進入,從 MON 服務拉取存儲資源布局信息,然后根據(jù)該布局信息和寫入數(shù)據(jù)的名稱等信息計算出期望數(shù)據(jù)的位置(包含具體的物理服務器信息和磁盤信息),然后和該位置信息對應的 CephFS 對應的位置直接通信,讀取或者寫入數(shù)據(jù)

  • 完全無中心架構 – 一致性哈希
    以 swift 為代表的架構是其典型的代表。與 Ceph 的通過計算方式獲得數(shù)據(jù)位置的方式不同,另外一種方式是通過一致性哈希的方式獲得數(shù)據(jù)位置。一致性哈希的方式就是將設備做成一個哈希環(huán),然后根據(jù)數(shù)據(jù)名稱計算出的哈希值映射到哈希環(huán)的某個位置,從而實現(xiàn)數(shù)據(jù)的定位。

    Swift 中存在兩種映射關系,對于一個文件,通過哈希算法( MD5 )找到對應的虛節(jié)點(一對一的映射關系),虛節(jié)點再通過映射關系( ring 文件中二維數(shù)組)找到對應的設備(多對多的映射關系),這樣就完成了一個文件存儲在設備上的映射。

    【分布式】分布式存儲架構

  • 分布式存儲的比較
    那么現(xiàn)在問題來了,如果我們要選擇分布式存儲,選擇哪種好呢?其實它們各有各的優(yōu)勢和使用場景,具體要看需求。

    • HDFS

      主要用于大數(shù)據(jù)的存儲場景,是 Hadoop 大數(shù)據(jù)架構中的存儲組件。HDFS 在開始設計的時候,就已經明確的它的應用場景,就是大數(shù)據(jù)服務。主要的應用場景有:

      • 對大文件存儲的性能比較高,例如幾百兆,幾個 G 的大文件。因為 HDFS 采用的是以元數(shù)據(jù)的方式進行文件管理,而元數(shù)據(jù)的相關目錄和塊等信息保存在 NameNode 的內存中, 文件數(shù)量的增加會占用大量的 NameNode 內存。如果存在大量的小文件,會占用大量內存空間,引起整個分布式存儲性能下降,所以盡量使用 HDFS 存儲大文件比較合適。

      • 適合低寫入,多次讀取的業(yè)務。就大數(shù)據(jù)分析業(yè)務而言,其處理模式就是一次寫入、多次讀取,然后進行數(shù)據(jù)分析工作, HDFS 的數(shù)據(jù)傳輸吞吐量比較高,但是數(shù)據(jù)讀取延時比較差,不適合頻繁的數(shù)據(jù)寫入。

      • HDFS 采用多副本數(shù)據(jù)保護機制,使用普通的 X86 服務器就可以保障數(shù)據(jù)的可靠性,不推薦在虛擬化環(huán)境中使用。

    • Ceph

      目前應用最廣泛的開源分布式存儲系統(tǒng),已得到眾多廠商的支持,許多超融合系統(tǒng)的分布式存儲都是基于 Ceph 深度定制。而且 Ceph 已經成為 LINUX 系統(tǒng)和 OpenStack 的 “ 標配 ” ,用于支持各自的存儲系統(tǒng)。Ceph 可以提供對象存儲、塊設備存儲和文件系統(tǒng)存儲服務。同時支持三種不同類型的存儲服務的特性,在分布式存儲系統(tǒng)中,是很少見的。

      • Ceph 沒有采用 HDFS 的元數(shù)據(jù)尋址的方案,而且采用 CRUSH 算法,數(shù)據(jù)分布均衡,并行度高。而且在支持塊存儲特性上,數(shù)據(jù)可以具有強一致性,可以獲得傳統(tǒng)集中式存儲的使用體驗。

      • 對象存儲服務, Ceph 支持 Swift 和 S3 的 API 接口。在塊存儲方面,支持精簡配置、快照、克隆。在文件系統(tǒng)存儲服務方面,支持 Posix 接口,支持快照。但是目前 Ceph 支持文件的性能相當其他分布式存儲系統(tǒng),部署稍顯復雜,性能也稍弱,一般都將 Ceph 應用于塊和對象存儲。

      • Ceph 是去中心化的分布式解決方案,需要提前做好規(guī)劃設計,對技術團隊的要求能力比較高。特別是在 Ceph 擴容時,由于其數(shù)據(jù)分布均衡的特性,會導致整個存儲系統(tǒng)性能的下降

    • Swift

      主要面向的是對象存儲。和 Ceph 提供的對象存儲服務類似。主要用于解決非結構化數(shù)據(jù)存儲問題。它和 Ceph 的對象存儲服務的主要區(qū)別是。

      • 客戶端在訪問對象存儲系統(tǒng)服務時, Swift 要求客戶端必須訪問 Swift 網(wǎng)關才能獲得數(shù)據(jù)。而 Ceph 使用一個運行在每個存儲節(jié)點上的 OSD (對象存儲設備)獲取數(shù)據(jù)信息,沒有一個單獨的入口點,比 Swift 更靈活一些。

      • 數(shù)據(jù)一致性方面, Swift 的數(shù)據(jù)是最終一致,在海量數(shù)據(jù)的處理效率上要高一些,但是主要面向對數(shù)據(jù)一致性要求不高,但是對數(shù)據(jù)處理效率要求比較高的對象存儲業(yè)務。而 Ceph 是始終跨集群強一致性。主要的應用場景,在 OpenStack 中,對象存儲服務使用的就是 Swift ,而不是 Ceph 。

三、分布式理論淺析

3.1 、一致性和可用性

由于異常的存在,分布式存儲系統(tǒng)設計時往往會將數(shù)據(jù)冗余存儲多份,每一份稱為一個副本)。這樣,當某一個節(jié)點出現(xiàn)故障時,可以從其他副本上讀到數(shù)據(jù)??梢赃@么認為,副本是分布式存儲系統(tǒng)容錯技術的唯一手段。由于多個副本的存在,如何保證副本之間的一致性是整個分布式系統(tǒng)的理論核心。

數(shù)據(jù)一致性這個單詞在平常開發(fā)中,或者各種文章中都能經??匆姡覀兂3B犚娛裁礀|西數(shù)據(jù)不一致了,造成了一定的損失,趕快修復一下。那有幾種一致性呢?

  • 時間一致性:要求所有數(shù)據(jù)組件的數(shù)據(jù)在任意時刻都是完全一致的;

  • 事物一致性:事務一致性只能存在在事務開始前的和事務完成之后,在事務過程中數(shù)據(jù)有可能不一致,比如 A 轉 100 元給 B , A 扣減 100 , B 加上 100 ,在事務開始前和事務完成之后都能保證他們的帳是對上的,那么這就是事務一致性。但是在事務過程中有可能會出現(xiàn) A 扣減了 100 元, B 沒有加上 100 元的情況,這就是不一致

  • 在應用程序中涉及多個不同的單機事務,只有在所有的單機事務完成之前和完成之后,數(shù)據(jù)是完全一致的。

僅僅靠這三種一致性在實際的一些復雜場合是很難描述清楚的,所以,我們引出了一致性模型,這里我們由強到弱簡單的介紹幾種常見的一致性模型。

  • 線性一致性
    又稱強一致性, 可以看做只有一個單核處理器,或者可以看做只有一個數(shù)據(jù)副本,并且所有操作都是原子的。

    【分布式】分布式存儲架構

    如上圖所示,對于事件 e1 和 e2 來說,如果事件 e1 的 response 是在事件 e2 的 invoke 之前,我們就說 e1 happen before e2 。

    對于同一個線程來說,前面的事件一定 happen before 后面的事件。但是對于不同線程上的兩個事件來說,它們之間只有在在時間線上沒有交叉的情況下,才會存在 happen before 關系。對于有交叉的那些事件,比如下圖中的 event2 和 event3 ,它們兩個就不存在 happen before 關系,對于我們要尋找的合法順序執(zhí)行過程來說,它們兩個的順序可以是任意的。

  • 順序一致性
    順序一致性弱于嚴格一致性。對變量的寫操作不一定要在瞬間看到,但是,不同處理器對變量的寫操作必須在所有處理器上以相同的順序看到,這里處理器再分布式系統(tǒng)中可以換成不同的節(jié)點。

    【分布式】分布式存儲架構

    假設有兩個線程 A 和 B 并發(fā)執(zhí)行。其中 A 線程由 3 個操作構成,它們在程序中的順序是:A1->A2->A3. B 線程也有 3 個操作,它們在程序中的順序是:B1->B2->B3. 假設如果在順序一致的模型中的效果就是如上兩個圖所示。

  • 因果一致性
    因果一致性是弱于順序一致性的一致性模型,順序一致性要求所有的操作的順序都必須按照某個單個處理器 ( 節(jié)點 ) 的順序,而因果一致性只需要滿足有因果關系的操作是順序一致性即可。

    【分布式】分布式存儲架構

    簡單來說如果有人問你一個問題,那么你給出答案,這兩個就是因果關系,但如果你給出答案再問題之前,那么這個就違反了因果關系。舉個簡單的例子如果節(jié)點 1 更新了數(shù)據(jù) A ,節(jié)點 2 讀取數(shù)據(jù) A ,并更新數(shù)據(jù) B ,這里的數(shù)據(jù) B 有可能是根據(jù)數(shù)據(jù) A 計算出來的,所有具備因果關系,但是如果節(jié)點 3 看到的是先更新的 B ,再更新的 A 那么就破壞了因果一致性。

  • 最終一致性
    其實除了強一致以外,其他的一致性都可以看作為最終一致性,只是根據(jù)一致性不同模型的不同要求又衍生出了很多具體一致性模型。當然最簡單的最終一致性,是不需要關注中間變化的順序,只需要保證在某個時間點一致即可。只是這個某個時間點需要根據(jù)不同的系統(tǒng),不同業(yè)務再去衡量。再最終一致性完成之前,有可能返回任何的值,不會對這些值做任何順序保證。

  • 可用性
    可用性指“ Reads and writes always succeed” ,即服務一直可用,而且是正常響應時間。對于一個可用性的分布式系統(tǒng),每一個非故障的節(jié)點必須對每一個請求作出響應。所以,一般我們在衡量一個系統(tǒng)的可用性的時候,都是通過停機時間來計算的。

    可用性分類 可用水平(%) 年可容忍停機時間
    容錯可用性 99.9999 <1 min
    極高可用性 99.999 <5 min
    具有故障自動恢復能力的可用性 99.99 <53 min
    高可用性 99.9 <8.8h
    商品可用性 99 <43.8 min

    通常我們描述一個系統(tǒng)的可用性時,我們說淘寶的系統(tǒng)可用性可以達到 5 個 9 ,意思就是說他的可用水平是 99.999% ,即全年停機時間不超過 (1-0.99999)36524*60 = 5.256 min ,這是一個極高的要求。

    好的可用性主要是指系統(tǒng)能夠很好的為用戶服務,不出現(xiàn)用戶操作失敗或者訪問超時等用戶體驗不好的情況。一個分布式系統(tǒng),上下游設計很多系統(tǒng)如負載均衡、 WEB 服務器、應用代碼、數(shù)據(jù)庫服務器等,任何一個節(jié)點的不穩(wěn)定都可以影響可用性

  • 分布式系統(tǒng)的一致性
    2000 年 7 月,加州大學伯克利分校的 Eric Brewer 教授在 ACM PODC 會議上提出 CAP 猜想。2 年后,麻省理工學院的 Seth Gilbert 和 Nancy Lynch 從理論上證明了 CAP 。之后, CAP 理論正式成為分布式計算領域的公認定理。

    CAP 理論概述:一個分布式系統(tǒng)最多只能同時滿足一致性( Consistency )、可用性( Availability )和分區(qū)容錯性( Partition tolerance )這三項中的兩項。

    【分布式】分布式存儲架構

    需要特別指出的 CAP 中的一致性是 all nodes see the same data at the same time ,也就是線性一致性。

一致性必須從兩個維度看:

  • 從客戶端角度,多進程并發(fā)訪問時,非分布式數(shù)據(jù)庫要求更新過的數(shù)據(jù)能被后續(xù)的訪問都能看到,所有都是強一致的;

  • 從服務端角度,如何盡快將更新后的數(shù)據(jù)分布到整個系統(tǒng),降低達到最終一致性的時間窗口,是提高系統(tǒng)的可用度和用戶體驗非常重要的方面。

參考以下公式:

N — 數(shù)據(jù)復制的份數(shù)

W — 更新數(shù)據(jù)時需要保證寫完成的節(jié)點數(shù)

R — 讀取數(shù)據(jù)的時候需要讀取的節(jié)點數(shù)

(1) 如果 W+R>N ,寫的節(jié)點和讀的節(jié)點重疊,則是強一致性。例如對于典型的一主一備同步復制的關系型數(shù)據(jù)庫, N=2,W=2,R=1 ,則不管讀的是主庫還是備庫的數(shù)據(jù),都是一致的。

(2) 如果 W+R<=N ,則是弱一致性。例如對于一主一備異步復制的關系型數(shù)據(jù)庫, N=2,W=1,R=1 ,則如果讀的是備庫,就可能無法讀取主庫已經更新過的數(shù)據(jù),所以是弱一致性。

對于一個分布式系統(tǒng)來說。P 是一個基本要求, CAP 三者中,只能在 CA 兩者之間做權衡,并且要想盡辦法提升 P 。

包含兩種系統(tǒng):CP without A**、 AP without C**

我們在上文所提到的 Hdfs 、 Ceph 、 Swift, 均是屬于CP without A的這個大類,只是并不是完全沒有 A ,為了實現(xiàn)一定的可用性,一般設置副本的個數(shù)為 N>=3 。不同的 N,W,R 組合,是在可用性和一致性之間取一個平衡,以適應不同的應用場景。

那么,實際生活中,也有一些是AP without C的案例,如 CAP 圖中所示,大部分是 Nosql 、 CoachDB 、 Cassandra 數(shù)據(jù)庫,那場景是哪些呢?

其實就是不要求正確性的場合,如某米的搶購手機場景或 12306 搶購火車票的場景,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品準備下單的時候,系統(tǒng)提示你下單失敗,商品已售完。這其實就是先在 A(可用性)方面保證系統(tǒng)可以正常的服務,然后在數(shù)據(jù)的一致性方面做了些犧牲。

3.2 、數(shù)據(jù)分布

分布式系統(tǒng)區(qū)別于傳統(tǒng)單機系統(tǒng)在于能夠將數(shù)據(jù)分布到多個節(jié)點,并在多個節(jié)點之間實現(xiàn)負載均衡。數(shù)據(jù)分布的方式主要有兩種,一種是哈希分布,如一致性哈希,代表系統(tǒng)為

Amazon 的 Dynamo 系統(tǒng), Openstack 的 Swift 系統(tǒng);另外一種方法是順序分布,即每張表格上的數(shù)據(jù)按照主鍵整體有序,代表系統(tǒng)為 Google 的 Bigtable 系統(tǒng)。Bigtable 將一張大表根據(jù)主鍵切分為有序的范圍,每個有序范圍是一個子表。

哈希分布( Swift )

哈希函數(shù)的散列特性很好,哈希方式可以將數(shù)據(jù)比較均勻地分布到集群中去。而且,哈希方式需要記錄的元信息也非常簡單,每個節(jié)點只需要知道哈希函數(shù)的計算方式以及模的服務器的個數(shù)就可以計算出處理的數(shù)據(jù)應該屬于哪臺機器。

然而,找出一個散列特性很好的哈希函數(shù)是很難的。這是因為,如果按照主鍵散列,那么同一個用戶 id 下的數(shù)據(jù)可能被分散到多臺服務器,這會使得一次操作同一個用戶 id 下的多條記錄變得困難;如果按照用戶 id 散列,容易出現(xiàn) “ 數(shù)據(jù)傾斜 ” ( data skew )問題,即某些大用戶的數(shù)據(jù)量很大,無論集群的規(guī)模有多大,這些用戶始終由一臺服務器處理。

處理大用戶問題一般有兩種方式,一種方式是手動拆分,即線下標記系統(tǒng)中的大用戶(例如運行一次 MapReduce 作業(yè)),并根據(jù)這些大用戶的數(shù)據(jù)量將其拆分到多臺服務器上。這就相當于在哈希分布的基礎上針對這些大用戶特殊處理;

另一種方式是自動拆分,即數(shù)據(jù)分布算法能夠動態(tài)調整,自動將大用戶的數(shù)據(jù)拆分到多臺服務器上。其中包含兩種算法。

一種是傳統(tǒng)的哈希算法,訪問數(shù)據(jù)時,首先計算哈希值,再查詢元數(shù)據(jù)服務器,獲得該哈希值對應的服務器。在這種算法下,服務器的上線和下線將導致大量的數(shù)據(jù)遷移,不適合于生產。

另一致性哈希( Distributed Hash Table,DHT )算法。算法思想如下:給系統(tǒng)中每個節(jié)點分配一個隨機 token ,這些 token 構成一個哈希環(huán)。執(zhí)行數(shù)據(jù)存放操作時,先計算 Key (主鍵)的哈希值,然后存放到順時針方向第一個大于或者等于該哈希值的 token 所在的節(jié)點。一致性哈希的優(yōu)點在于節(jié)點加入 / 刪除時只會影響到在哈希環(huán)中相鄰的節(jié)點,而對其他節(jié)點沒影響。
【分布式】分布式存儲架構

如上圖所示,算法本身的特性可以使得 磁盤劃分為比較多的較為均勻的虛擬分區(qū),每個虛擬分區(qū)是哈希環(huán)上的一個節(jié)點,整個環(huán)是從 0 到 32 位最大值的一個區(qū)間,并且首尾相連,當計算出數(shù)據(jù)(或者數(shù)據(jù)名稱)的哈希值后,必然落到哈希環(huán)的某個區(qū)間,然后以順時針,必然能夠找到一個節(jié)點。那么這個節(jié)點就是存儲數(shù)據(jù)的位置??梢娙绻挥幸粋€節(jié)點,最大到 32 還未找到節(jié)點,那么數(shù)據(jù)就在第一個唯一節(jié)點上。

整個的數(shù)據(jù)定位就是基于上述的一致算法,實現(xiàn)將請求重新定向到該設備進行處理

(1) 在對象存儲上,通過賬戶名 / 容器名 / 對象名三個名稱組成一個位置的標識,通過該唯一標識可以計算出一個整型數(shù);

(2) 存儲設備方面, Swift 構建一個虛擬分區(qū)表,表的大小在創(chuàng)建集群是確定(通常為幾十萬),這個表其實就是一個數(shù)組;

(3) 整數(shù)值和這個數(shù)組,通過一致性哈希算法就可以確定該整數(shù)在數(shù)組的位置。

【分布式】分布式存儲架構

一致性算法原理上可以保證數(shù)據(jù)的均衡性、單調性,避免數(shù)據(jù)的分散性,有效的保證數(shù)據(jù)的一致性,使得負載盡可能的被映射到一個特定的緩存區(qū)。

因為 一致性哈希算法在服務節(jié)點太少時,容易因為節(jié)點分部不均勻而造成數(shù)據(jù)傾斜問題。所以在實際應用中,通常將虛擬節(jié)點數(shù)設置為比 32 更大的值,因此即使很少的服務節(jié)點也能做到相對均勻的數(shù)據(jù)分布。

順序分布( Bigtable )

哈希散列破壞了數(shù)據(jù)的有序性,只支持隨機讀取操作,不能夠支持順序掃描。某些系統(tǒng)可以在應用層做折衷,比如互聯(lián)網(wǎng)應用經常按照用戶來進行數(shù)據(jù)拆分,并通過哈希方法進行數(shù)據(jù)分布,同一個用戶的數(shù)據(jù)分布到相同的存儲節(jié)點,允許對同一個用戶的數(shù)據(jù)執(zhí)行順序掃描,由應用層解決跨多個用戶的操作問題。另外,這種方式可能出現(xiàn)某些用戶的數(shù)據(jù)量太大的問題,由于用戶的數(shù)據(jù)限定在一個存儲節(jié)點,無法發(fā)揮分布式存儲系統(tǒng)的多機并行處理能力。

順序分布在分布式表格系統(tǒng)( Bigtable )中比較常見,一般的做法是將大表順序劃分為連續(xù)的范圍,每個范圍稱為一個子表,總控服務器負責將這些子表按照一定的策略分配到存儲節(jié)點上。

【分布式】分布式存儲架構

如圖所示,用戶表( User 表)的主鍵范圍為 1 ~ 7000 ,在分布式存儲系統(tǒng)中劃分為多個子表,分別對應數(shù)據(jù)范圍 1 ~ 1000 , 1001 ~ 2000 , ……6001 ~ 7000 。其中 Meta 表是為了支持更大的集群規(guī)模,它將原來的一層索引結分成兩層,使用 Meta 表來維護 User 子表所在的節(jié)點,從而減輕 Root 節(jié)點的負擔。

順序分布與 B+ 樹數(shù)據(jù)結構比較類似,每個子表相當于葉子節(jié)點,隨著數(shù)據(jù)的插入和刪除,某些子表可能變得很大,某些變得很小,數(shù)據(jù)分布不均勻。如果采用順序分布,系統(tǒng)設計時需要考慮子表的分裂與合并,這將極大地增加系統(tǒng)復雜度。

CRUSH 分布

CRUSH 算法,全稱叫 Controlled, Scalable, Decentralized Placement of Replicated Data. 嚴格說起來 Crush 算法,其實也是以 Hash 算法為基礎的。只不過映射的方法和一致性哈希不同。我們用 Ceph 分布的過程來加以說明。

Ceph 分布數(shù)據(jù)的過程:首先計算數(shù)據(jù) x 的 Hash 值并將結果和 PG 數(shù)目取余,以得到數(shù)據(jù) x 對應的 PG 編號。然后,通過 CRUSH 算法將 PG 映射到一組 OSD 中。最后把數(shù)據(jù) x 存放到 PG 對應的 OSD 中。注明:PG 全稱是 Placement Group (放置組)。

這個過程中包含了兩次映射,第一次是數(shù)據(jù) x 到 PG 的映射。如果把 PG 當作存儲節(jié)點,那么傳統(tǒng) Hash 算法一樣。不同的是, PG 是抽象的存儲節(jié)點,它不會隨著物理節(jié)點的加入或則離開而增加或減少,因此數(shù)據(jù)到 PG 的映射是穩(wěn)定的。

【分布式】分布式存儲架構

以 Dynamo 為例,在這個過程中, PG 起到了兩個作用:第一個作用是劃分數(shù)據(jù)分區(qū)。每個 PG 管理的數(shù)據(jù)區(qū)間相同,因而數(shù)據(jù)能夠均勻地分布到 PG 上;第二個作用是充當 Dynamo 中 Token 的角色,即決定分區(qū)位置。實際上,這和 Dynamo 中固定分區(qū)數(shù)目,以及維持分區(qū)數(shù)目和虛擬節(jié)點數(shù)目相等的原則是同一回事。

以 Ceph 為例, CRUSH 算法通過兩次映射計算數(shù)據(jù)存儲位置來確定如何存儲和檢索數(shù)據(jù)。CRUSH 使 Ceph 客戶機能夠直接與 OSDs 通信,而不是通過集中的服務器或代理。

通過算法確定的數(shù)據(jù)存儲和檢索方法, Ceph 避免了單點故障、性能瓶頸和對其可伸縮性的物理限制。CRUSH 需要集群的映射,并使用 CRUSH 映射在 OSDs 中偽隨機存儲和檢索數(shù)據(jù),數(shù)據(jù)在集群中均勻分布。

3.3 、復制

為了保證分布式存儲系統(tǒng)的高可靠和高可用,數(shù)據(jù)在系統(tǒng)中一般存儲多個副本。當某個副本所在的存儲節(jié)點出現(xiàn)故障時,分布式存儲系統(tǒng)能夠自動將服務切換到其他的副本,從而實現(xiàn)自動容錯。分布式存儲系統(tǒng)通過復制協(xié)議將數(shù)據(jù)同步到多個存儲節(jié)點,并確保多個副本之間的數(shù)據(jù)一致性。

強同步復制

客戶端將寫請求發(fā)送給主副本,主副本將寫請求復制到其他備副本,常見的做法是同步操作日志( Commit Log )。主副本首先將操作日志同步到備副本,備副本回放操作日志,完成后通知主副本。接著,主副本修改本機,等到所有的操作都完成后再通知客戶端寫成功。下圖中的復制協(xié)議要求主備同步成功才可以返回客戶端寫成功,這種協(xié)議稱為強同步協(xié)議。

【分布式】分布式存儲架構

假設所有副本的個數(shù)為 N ,且 N > 2 ,即備副本個數(shù)大于 1 。那么,實現(xiàn)強同步協(xié)議時,主副本可以將操作日志并發(fā)地發(fā)給所有備副本并等待回復,只要至少 1 個備副本返回成功就可以回復客戶端操作成功。強同步的好處在于如果主副本出現(xiàn)故障,至少有 1 個備副本擁有完整的數(shù)據(jù),分布式存儲系統(tǒng)可以自動地將服務切換到最新的備副本而不用擔心數(shù)據(jù)丟失的情況。

異步復制

與強同步對應的復制方式是異步復制。在異步模式下,主副本不需要等待備副本的回應,只需要本地修改成功就可以告知客戶端寫操作成功。另外,主副本通過異步機制,比如單獨的復制線程將客戶端修改操作推送到其他副本。異步復制的好處在于系統(tǒng)可用性較好,但是一致性較差,如果主副本發(fā)生不可恢復故障,可能丟失最后一部分更新操作。

NWR 復制

分布式存儲系統(tǒng)中還可能使用基于寫多個存儲節(jié)點的復制協(xié)議( Replicated-write protocol )。比如 Dynamo 系統(tǒng)中的 NWR 復制協(xié)議,其中, N 為副本數(shù)量, W 為寫操作的副本數(shù), R 為讀操作的副本數(shù)。

NWR 協(xié)議中多個副本不再區(qū)分主和備,客戶端根據(jù)一定的策略往其中的 W 個副本寫入數(shù)據(jù),讀取其中的 R 個副本。只要 W+R > N ,可以保證讀到的副本中至少有一個包含了最新的更新。然而,這種協(xié)議的問題在于不同副本的操作順序可能不一致,從多個副本讀取時可能出現(xiàn)沖突。這種方式在實際系統(tǒng)中比較少見,不建議使用。

3.4 、分布式協(xié)議

分布式協(xié)議有很多,其中以兩階段提交和 Paxos 協(xié)議最具代表性。兩階段提交協(xié)議( 2PC )或三階段提交( 3PC )用于保證跨多個節(jié)點操作的原子性,也就是說,跨多個節(jié)點的操作要么在所有節(jié)點上全部執(zhí)行成功,要么全部失敗。Paxos 協(xié)議用于確保多個節(jié)點對某個投票(例如哪個節(jié)點為主節(jié)點)達成一致。

兩階段提交

二階段提交的算法思路可以概括為 : 參與者將操作成敗通知協(xié)調者,再由協(xié)調者根據(jù)所有參與者的反饋情報決定各參與者是否要提交操作還是中止操作。

  1. 請求階段 ( 表決 ) :

事務協(xié)調者協(xié)調者通知事務參與者準備提交或者取消事務,然后進入表決過程。在表決過程中,參與者將告知協(xié)調者自己的決策:同意(事務參與者本地執(zhí)行成功)或者取消(事務參與者本地執(zhí)行失?。?/p>

  1. 提交階段 ( 執(zhí)行 ):

在該階段,協(xié)調者將基于第一個階段的投票結果進行決策 : 提交或取消,當且僅當所有的參與者同意提交事務,協(xié)調者才通知所有的參與者提交事務,否則協(xié)調者將通知所有的參與者取消事務參與者在接收到協(xié)調者發(fā)來的消息后將執(zhí)行響應的操作。

【分布式】分布式存儲架構

  1. 兩階段提交無法解決的問題

    • 如果一個參與者遲遲不投票,那整個階段都會處于等待狀態(tài),但這可以通過超時機制解決

    • 當協(xié)調者出錯,同時參與者也出錯時,兩階段無法保證事務執(zhí)行的完整性。

考慮協(xié)調者在發(fā)出 commit 消息之后宕機,而唯一接收到這條消息的參與者同時也宕機了。

那么即使協(xié)調者通過選舉協(xié)議產生了新的協(xié)調者,這條事務的狀態(tài)也是不確定的,沒人知道事務是否被已經提交。

三階段提交

三階段提交擁有 CanCommit 、 PreCommit 、 DoCommit 三個階段

  1. 其中 CanCommit 階段近似等同于兩階段的請求階段;DoCommit 近似等同于兩階段的提交階段。而準備階段 PreCommit 是一個緩沖,保證了在最后提交階段之前各參與節(jié)點的狀態(tài)是一致的。

  2. 三階段提交在兩階段提交的第一階段與第二階段之間插入了一個準備階段( PreCommit ),使得原先在兩階段提交中,參與者在投票之后,由于協(xié)調者發(fā)生崩潰或錯誤,而導致參與者處于無法知曉是否提交或者中止的“不確定狀態(tài)”所產生的可能相當長的延時的問題得以解決。

【分布式】分布式存儲架構

  1. 三階段提交無法解決的問題

如果進入 PreCommit 后,協(xié)調者發(fā)出的是 commit 請求,假設只有一個參與者收到并進行了 commit 操作,而其他參與者對于網(wǎng)絡中斷沒有收到,會根據(jù) 3PC 選擇 abort 操作,此時系統(tǒng)狀態(tài)發(fā)生不一致性。

Paxos 協(xié)議

要講 Paxos ,先要從拜占庭問題講起,其故事背景是這樣的:拜占庭位于現(xiàn)在土耳其的伊斯坦布爾,是東羅馬帝國的首都。由于當時拜占庭羅馬帝國國土遼闊,為了防御目的,因此每個軍隊都分隔很遠,將軍與將軍之間只能靠信差傳消息。在戰(zhàn)爭的時候,拜占庭軍隊內所有將軍必需達成一致的共識,決定是否有贏的機會才去攻打敵人的陣營。但是,軍隊可能有叛徒和敵軍間諜,這些叛徒將軍們會擾亂或左右決策的過程。這時候,在已知有成員謀反的情況下,其余忠誠的將軍在不受叛徒的影響下如何達成一致的協(xié)議,這就是拜占庭將軍問題。

我們否定假設,給出了非拜占庭模型定義:

  1. 一致性模塊的行為可以以任意速度執(zhí)行,允許運行失敗,在失敗后也許會重啟并再次運行;

  2. 一致性模塊之間通過異步方式發(fā)送信息通信,通信時間可以任意長,信息可能會在傳輸過程中丟失,也允許重復發(fā)送相同的信息,多重信息的順序可以任意。但是有一點:信息不允許被篡改。

由此,我們得出了 Paxos 的基本二階段:Prepare 階段、 Accept 階段,這個兩個階段的邏輯非常復雜,是互信算法的基礎,本文并不打算做過深的解讀。有興趣的讀者可以去參考《區(qū)塊鏈算法》一書。

Raft 協(xié)議

Raft 是 Replicated And Fault Tolerant 的縮寫, Paxos 的簡化版本。

在一個分布式系統(tǒng)中,要提高系統(tǒng)的健壯性,可用性和數(shù)據(jù)的安全性,我們最正確的姿勢是什么?當然是靠多備份了,服務多備份,數(shù)據(jù)多備份,去除單點,確保即使相關組件掛掉一些,系統(tǒng)還能健康服務。

去除單點,沒有固定不變的權威,固然好,但是帶來的問題就是,以誰的意見為準,在信息可能丟失的環(huán)境下,這是一個相當困難的事(可見溝通是多么的重要)!

在 1990 年提出來之時,幾乎沒有人能夠理解。經過作者多次簡化,再解釋,包括谷歌等團隊的實踐再創(chuàng)造,再解釋的過程,十幾年過去了,才漸漸的成為事實標準并被大家所了解和接受。但直到現(xiàn)在,無比抽象的 Paxos 算法,還是沒有幾個人能理解。

大道至簡!這是永恒不變的真理, Raft 的目標問題,是構建一個容易理解和構建的分布式一致性協(xié)議,在容易的基礎上,確保理論正確的。

Raft 協(xié)議,如果照本宣讀,還是需要點時間的,本文采用通俗的辦法給大家做解釋

Raft 大致的原理,這是一個選主( leader selection )思想的算法,集群總每個節(jié)點都有三種可能的角色:

  1. leader

對客戶端通信的入口,對內數(shù)據(jù)同步的發(fā)起者,一個集群通常只有一個 leader 節(jié)點

  1. follower:

非 leader 的節(jié)點,被動的接受來自 leader 的數(shù)據(jù)請求

  1. candidate:

一種臨時的角色,只存在于 leader 的選舉階段,某個節(jié)點想要變成 leader ,那么就發(fā)起投票請求,同時自己變成 candidate 。如果選舉成功,則變?yōu)?candidate ,否則退回為 follower 。

算法包含兩個過程:leader 選舉和日志復制:

  • 選舉過程:(假設有 5 個節(jié)點, S1~S5 )

    a、 初始狀態(tài)下,大家都是平等的 follower ,那么 follow 誰呢,總要選個老大吧。大家都蠢蠢欲動,每個 follower 內部都維護了一個隨機的 timer ;

    b、 在 timer 時間到了的時候還沒有人主動聯(lián)系它的話,那它就要變成 candidate ,同時發(fā)出投票請求( RequestVote )給其他人,假設 S1, S3 成為 candidate

    c、 對于相同條件的 candidate , follower 們采取先來先投票的策略。如果超過半數(shù)的 follower 都認為他是合適做領導的,那么恭喜,新的 leader 產生了,假如 S3 變成了新一屆的大哥 leader ;

    d、 S1 很不幸,沒有人愿意選這個悲劇的 candidate ,那它只有老老實實的變回小弟的狀態(tài) follower;

    e、 同樣的,如果在 timer 期間內沒有收到大哥的聯(lián)絡,這時很可能大哥已經跪了,如下圖,所有小弟又開始蠢蠢欲動,新的一輪 (term) 選舉開始了。

  • 日志復制:(假設有 5 個節(jié)點, S1~S5 )

    a、 leader 扮演的是分布式事務中的協(xié)調者,每次有數(shù)據(jù)更新的時候產生二階段提交( two-phase commit )。在 leader 收到數(shù)據(jù)操作的請求,先不著急更新本地數(shù)據(jù)(數(shù)據(jù)是持久化在磁盤上的),而是生成對應的 log ,然后把生成 log 的請求廣播給所有的 follower ;

    b、 每個 follower 在收到請求之后有兩種選擇:一種是聽從 leader 的命令,也寫入 log ,然后返回 success 回去;另一種情況,在某些條件不滿足的情況下, follower 認為不應該聽從 leader 的命令,返回 false ;

    c、 此時如果超過半數(shù)的 follower 都成功寫了 log ,那么 leader 開始_第二階段_的提交:正式寫入數(shù)據(jù),然后同樣廣播給 follower , follower 也根據(jù)自身情況選擇寫入或者不寫入并返回結果給 leader ,最終所有節(jié)點的數(shù)據(jù)達成一致。

    d、 這兩階段中如果任意一個都有超過半數(shù)的 follower 返回 false 或者根本沒有返回,那么這個分布式事務是不成功的。此時雖然不會有回滾的過程,但是由于數(shù)據(jù)不會真正在多數(shù)節(jié)點上提交,所以會在之后的過程中被覆蓋掉

Raft 協(xié)議保證_leader_的強領導地位 ,client 讀寫都_通過_leader_,有很高的一致性,但有些同學會問,那分布式的價值在什么地方呢?如何才能負載均衡呢?在實際中我們采用 Multi Raft 架構,結合應用,不同的應用選舉不同的 leader 節(jié)點,在負載均衡。

3.5、跨機房部署

在分布式系統(tǒng)中,跨機房問題一直都是老大難問題。機房之間的網(wǎng)絡延時較大,且不穩(wěn)定。跨機房問題主要包含兩個方面:數(shù)據(jù)同步以及服務切換??鐧C房部署方案有三個:集群整體切換、單個集群跨機房、 Paxos 選主副本。下面分別介紹。

集群整體切換

集群整體切換是最為常見的方案。如圖所示,假設某系統(tǒng)部署在兩個機房:機房 1 和機房 2 。兩個機房保持獨立,每個機房部署單獨的總控節(jié)點,且每個總控節(jié)點各有一個備份節(jié)點。當總控節(jié)點出現(xiàn)故障時,能夠自動將機房內的備份節(jié)點切換為總控節(jié)點繼續(xù)提供服務。另外,兩個機房部署了相同的副本數(shù),例如數(shù)據(jù)分片 A 在機房 1 存儲的副本為 A11 和 A12 ,在機房 2 存儲的副本為 A21 和 A22 。在某個時刻,機房 1 為主機房,機房 2 為備機房。

【分布式】分布式存儲架構

機房之間的數(shù)據(jù)同步方式可能為強同步或者異步。如果采用異步模式,那么,備機房的數(shù)據(jù)總是落后于主機房。當主機房整體出現(xiàn)故障時,有兩種選擇:要么將服務切換到備機房,忍受數(shù)據(jù)丟失的風險;要么停止服務,直到主機房恢復為止。因此,如果數(shù)據(jù)同步為異步,那么,主備機房切換往往是手工的,允許用戶根據(jù)業(yè)務的特點選擇“丟失數(shù)據(jù)”或者“停止服務”。

如果采用強同步模式,那么,備機房的數(shù)據(jù)和主機房保持一致。當主機房出現(xiàn)故障時,除了手工切換,還可以采用自動切換的方式,即通過分布式鎖服務檢測主機房的服務,當主機房出現(xiàn)故障時,自動將備機房切換為主機房。

單個集群跨機房

將單個集群部署到多個機房,允許不同數(shù)據(jù)分片的主副本位于不同的機房,如圖 3-11 所示。每個數(shù)據(jù)分片在機房 1 和機房 2 ,總共包含 4 個副本,其中 A1 、 B1 、 C1 是主副本, A1 和 B1 在機房 1 , C1 在機房 2 。整個集群只有一個總控節(jié)點,它需要同機房 1 和機房 2 的所有工作節(jié)點保持通信。當總控節(jié)點出現(xiàn)故障時,分布式鎖服務將檢測到,并將機房 2 的備份節(jié)點切換為總控節(jié)點。

【分布式】分布式存儲架構

如果采用這種部署方式,總控節(jié)點在執(zhí)行數(shù)據(jù)分布時,需要考慮機房信息,也就是說,盡量將同一個數(shù)據(jù)分片的多個副本分布到多個機房,從而防止單個機房出現(xiàn)故障而影響正常服務。

Paxos 選主副本

如果采用 Paxos 協(xié)議選主副本,那么,每個數(shù)據(jù)分片的多個副本構成一個 Paxos 復制組。如圖所示, B1 、 B2 、 B3 、 B4 構成一個復制組,某一時刻 B1 為復制組的主副本,當 B1 出現(xiàn)故障時,其他副本將嘗試切換為主副本, Paxos 協(xié)議保證只有一個副本會成功。這樣,總控節(jié)點與工作節(jié)點之間不再需要保持租約,總控節(jié)點出現(xiàn)故障也不會對工作節(jié)點產生影響。它的優(yōu)點在于能夠降低對總控節(jié)點的依賴,缺點在于工程復雜度太高,很難在線下模擬所有的異常情況。

【分布式】分布式存儲架構

四、分布式文件系統(tǒng)

分布式文件系統(tǒng)的主要功能有兩個:一個是存儲文檔、圖像、視頻之類的 Blob 類型數(shù)據(jù);另外一個是作為分布式表格系統(tǒng)的持久化層。

4.1、 Google 文件系統(tǒng)( GFS )

GFS, Big Table, Map Reduce 稱為 Google 的三駕馬車,是許多基礎服務的基石。

GFS 于 2003 年提出,是一個分布式的文件系統(tǒng),與此前的很多分布式系統(tǒng)的前提假設存在很大的不同,適用于以下場景

  • 認為組件失效是一種常態(tài),提供了容錯機制,自動負載均衡,使得分布式文件系統(tǒng)可以在廉價機器上運行;

  • 面向大文件存儲,系統(tǒng)主要的工作負載是大規(guī)模的流式讀取,寫操作主要是追加方式寫,很少有隨機寫;

  • 一次寫入,多次讀取,例如互聯(lián)網(wǎng)上的網(wǎng)頁存儲

GFS 文件被劃分為固定大小的數(shù)據(jù)塊( chunk ),由主服務器在創(chuàng)建時分配一個 64 位全局唯一的 chunk 句柄。CS 以普通的 Linux 文件的形式將 chunk 存儲在磁盤中。為了保證可靠性, chunk 在不同的機器中復制多份,默認為三份。

主控服務器中維護了系統(tǒng)的元數(shù)據(jù),包括文件及 chunk 命名空間、文件到 chunk 之間的映射、 chunk 位置信息。它也負責整個系統(tǒng)的全局控制,如 chunk 租約管理、垃圾回收無用 chunk 、 chunk 復制等。主控服務器會定期與 CS 通過心跳的方式交換信息。

客戶端是 GFS 提供給應用程序的訪問接口,它是一組專用接口,不遵循 POSIX 規(guī)范,以庫文件的形式提供。客戶端訪問 GFS 時,首先訪問主控服務器節(jié)點,獲取與之進行交互的 CS 信息,然后直接訪問這些 CS ,完成數(shù)據(jù)存取工作。

需要注意的是, GFS 中的客戶端不緩存文件數(shù)據(jù),只緩存主控服務器中獲取的元數(shù)據(jù),這是由 GFS 的應用特點決定的。GFS 最主要的應用有兩個:MapReduce 與 Bigtable 。對于 MapReduce,GFS 客戶端使用方式為順序讀寫,沒有緩存文件數(shù)據(jù)的必要;而 Bigtable 作為分布式表格系統(tǒng),內部實現(xiàn)了一套緩存機制。另外,如何維護客戶端緩存與實際數(shù)據(jù)之間的一致性是一個極其復雜的問題。

由此可見, Hadoop 的 HDFS 其實是 GFS 的簡化版,是 Cutting 博士“山寨” GFS 出來的產物。是盜火種的產物。

4.2、 Taobao 文件系統(tǒng)( TFS )

互聯(lián)網(wǎng)應用經常需要存儲用戶上傳的文檔、圖片、視頻等,比如 Facebook 相冊、淘寶圖片、 Dropbox 文檔等。文檔、圖片、視頻一般稱為 Blob 數(shù)據(jù)。Blob 文件系統(tǒng)的特點是數(shù)據(jù)寫入后基本都是只讀,很少出現(xiàn)更新操作,這就是 Taobao 文件系統(tǒng)( TFS )的主要特點。

TFS 架構上借鑒了 GFS ,但與 GFS 又有很大的不同。

  • TFS 內部不維護文件目錄樹,扁平化的數(shù)據(jù)組織結構,可將文件名映射到文件的物理地址,簡化了文件的訪問流程;

  • 針對海量小文件的隨機讀寫訪問性能做了特殊優(yōu)化,滿足了淘寶對小文件存儲的需求,被廣泛地應用在淘寶各項應用中;

  • 采用了 HA 架構和平滑擴容,保證了整個文件系統(tǒng)的可用性和擴展性。

【分布式】分布式存儲架構

一個 TFS 集群由兩個 NameServer 節(jié)點(一主一備)和多個 DataServer 節(jié)點組成, NameServer 通過心跳對 DataSrver 的狀態(tài)進行監(jiān)測。NameServer 相當于 GFS 中的 Master,DataServer 相當于 GFS 中的 ChunkServer 。NameServer 區(qū)分為主 NameServer 和備 NameServer ,只有主 NameServer 提供服務,當主 NameServer 出現(xiàn)故障時,能夠被心跳守護進程檢測到,并將服務切換到備 NameServer 。每個 DataServer 上會運行多個 dsp 進程,一個 dsp 對應一個掛載點,這個掛載點一般對應一個獨立磁盤,從而管理多塊磁盤。

在 TFS 中,將大量的小文件(實際數(shù)據(jù)文件)合并成一個大文件(這一點比 HDFS 有優(yōu)化和改進),這個大文件稱為塊( Block ),每個 Block 擁有在集群內唯一的編號(塊 ID ),通過<塊 ID ,塊內偏移>可以唯一確定一個文件。TFS 中 Block 的實際數(shù)據(jù)都存儲在 DataServer 中,大小一般為 64MB ,默認存儲三份,相當于 GFS 中的 chunk 。應用客戶端是 TFS 提供給應用程序的訪問接口,應用客戶端不緩存文件數(shù)據(jù),只緩存 NameServer 的元數(shù)據(jù)。

4.3、 Fackbook Haystack 文件系統(tǒng)

到 2014 年, Facebook 大概有超 4000 億張圖片,總大小為 30PB ,通過計算可以得出每張照片的平均大小為 30PB/260GB ,約為 100KB 。用戶每周新增照片數(shù)為 10 億(總大小為 60TB ),平均每秒新增的照片數(shù)為 109/7/40000 (按每天 40000s 計),約為每秒 3800 次寫操作,讀操作峰值可以達到每秒百萬次。

Facebook 相冊后端早期采用基于 NAS 的存儲,通過 NFS 掛載 NAS 中的照片文件來提供服務。后來出于性能和成本考慮,自主研發(fā)了 Facebook Haystack 存儲相冊數(shù)據(jù)。

和 TFS 類似, Facebook Haystack 新架構主要解決圖片存取 IO 次數(shù)過多的文件,主要的思路是多個邏輯文件共享同一個物理文件。Haystack 架構及讀請求處理流程圖如下

【分布式】分布式存儲架構

Haystack 架構主要有三個部分:Haystack Directory , Haystack Store 以及 Haystack Cache 。Haystack Store 是物理存儲節(jié)點,以物理卷軸 (physical volume) 的形式組織存儲空間,每個物理卷軸一般很大,比如 100GB ,這樣 10TB 的數(shù)據(jù)也只有 100 個物理卷軸。每個物理卷軸對應一個物理文件,因此,每個存儲節(jié)點上的物理文件元信息都很小。多個物理存儲節(jié)點上的物理卷軸組成一個邏輯卷軸 (logical volume) ,用于備份。Haystack Directory 存放邏輯卷軸和物理卷軸的對應關系,假設每個卷軸的大小為 100GB ,對應關系的條數(shù)為 20PB / 100GB = 0.2MB ,占用的內存可以忽略。Haystack cache 主要用于解決對 CDN 提供商過于依賴的問題,提供最近增加的圖片的緩存服務。

Haystack 圖片讀取請求大致流程為:用戶訪問一個頁面時, Web Server 請求 Haystack Directory 構造一個 URL :http:// < CDN > / < Cache > / < Machine id > / < Logical volume,Photo > ,后續(xù)根據(jù)各個部分的信息依次訪問 CDN , Cache 和后端的 Haystack Store 存儲節(jié)點。Haystack Directory 構造 URL 時可以省略 部分從而使得用戶直接請求 Haystack Cache 而不必經過 CDN 。Haystack cache 收到的請求包含兩個部分:用戶 Browser 的請求及 CDN 的請求, Haystack cache 只緩存用戶 Browser 發(fā)送的請求且要求請求的 Haystack Store 存儲節(jié)點是可寫的。一般來說, Haystack Store 的存儲節(jié)點寫一段時間以后達到容量上限變?yōu)橹蛔x,因此,可寫節(jié)點的圖片為最近增加的圖片,是熱點數(shù)據(jù)。

Haystack 的寫請求 ( 圖片上傳 ) 處理流程為:Web Server 首先請求 Haystack Directory 獲取圖片的 id 和可寫的邏輯卷軸,接著將數(shù)據(jù)寫入對應的每一個物理卷軸 ( 備份數(shù)一般為 3) 。

Facebook Haystack 及 Taobao TFS 這樣的文件系統(tǒng)一般稱為 Blob 文件系統(tǒng)。它們都是解決大量的小圖片文件的問題,因此架構很類似,不同點包括

  • 邏輯卷軸大小的選擇,比如 Haystack 選擇 100GB 的邏輯卷軸大小, TFS 中 block 大小一般為 64MB ;

  • Haystack 使用 RAID 6 ,且底層文件系統(tǒng)使用性能更好的 XFS ,淘寶后期擯除了 RAID 機制,文件系統(tǒng)使用 Ext3 ;

  • Haystack 使用了 Akamai & Limelight 的 CDN 服務,而 Taobao 已經使用自建的 CDN ,當然, Facebook 也在考慮自建 CDN 。

4.4、 CDN 內容分發(fā)網(wǎng)絡

CDN 的全稱是 Content Delivery Network ,即內容分發(fā)網(wǎng)絡。其目的是通過在現(xiàn)有的 Internet 中增加一層新的網(wǎng)絡架構,將網(wǎng)站的內容發(fā)布到最接近用戶的網(wǎng)絡 " 邊緣 " 。實現(xiàn)如下三個目的

  • 解決因分布、帶寬、服務器性能帶來的訪問延遲問題,適用于站點加速、點播、直播等場景。使用戶可就近取得所需內容,解決 Internet 網(wǎng)絡擁擠的狀況,提高用戶訪問網(wǎng)站的響應速度和成功率。

  • 控制時延無疑是現(xiàn)代信息科技的重要指標, CDN 的意圖就是盡可能的減少資源在轉發(fā)、傳輸、鏈路抖動等情況下順利保障信息的連貫性。

  • CDN 就是扮演者護航者和加速者的角色,更快準狠的觸發(fā)信息和觸達每一個用戶,帶來更為極致的使用體驗。

如下圖所示 DNS 在對域名解析時不再向用戶返回源服務器的 IP ,而是返回了由智 CDN 負載均衡系統(tǒng)選定的某個邊緣節(jié)點的 IP 。用戶利用這個 IP 訪問邊緣節(jié)點,然后該節(jié)點通過其內部 DNS 解析得到源服務器 IP 并發(fā)出請求來獲取用戶所需的頁面,如果請求成功,邊緣節(jié)點會將頁面緩存下來,下次用戶訪問時可以直接讀取,而不需要每次都訪問源服務器。

Taobao 的 CDN 架構是自研的,用于支持用戶購物,尤其是“雙 11” 光棍節(jié)時的海量圖片請求,圖片存儲在后臺的 TFS 集群中, CDN 系統(tǒng)將這些圖片緩存到離用戶最近的邊緣節(jié)點。CDN 采用兩級 Cache :L1-Cache 以及 L2-Cache 。用戶訪問淘寶網(wǎng)的圖片時,通過全局調度系統(tǒng)( Global Load Balancing )調度到某個 L1-Cache 節(jié)點。如果 L1-Cache 命中,那么直接將圖片數(shù)據(jù)返回用戶;否則,請求 L2-Cache 節(jié)點,并將返回的圖片數(shù)據(jù)緩存到 L1-Cache 節(jié)點。如果 L2-Cache 命中,直接將圖片數(shù)據(jù)返回給 L1-Cache 節(jié)點;否則,請求源服務器的圖片服務器集群。每臺圖片服務器是一個運行著 Nginx 的 Web 服務器,它還會在本地緩存圖片,只有當本地緩存也不命中時才會請求后端的 TFS 集群,圖片服務器集群和 TFS 集群部署在同一個數(shù)據(jù)中心內。

【分布式】分布式存儲架構

對于每個 CDN 節(jié)點,其架構如圖 4-11 所示。從圖中可以看出,每個 CDN 節(jié)點內部通過 LVS+Haproxy 的方式進行負載均衡。其中, LVS 是四層負載均衡軟件,性能好;Haproxy 是七層負載均衡軟件,能夠支持更加靈活的負載均衡策略。通過有機結合兩者,可以將不同的圖片請求調度到不同的 Squid 服務器。

【分布式】分布式存儲架構

上圖是 CDN 的單節(jié)點架構,它有以下三個特點

  • Squid 服務器構成淘寶單節(jié)點中的 CDN 中的分布式緩存,這個實現(xiàn)比分布式緩存簡單很多,因為不需要考慮數(shù)據(jù)持久化。

  • 分級緩存,由于緩存數(shù)據(jù)有較高的局部性,在 Squid 服務器上使用 SSD+SAS+SATA 混合存儲,圖片隨著熱點變化而遷移,最熱門的存儲到 SSD ,中等熱度的存儲到 SAS ,輕熱度的存儲到 SATA 。通過這樣的方式,能夠很好地結合 SSD 的性能和 SAS 、 SATA 磁盤的成本優(yōu)勢;

  • 低功耗服務器定制, CDN 緩存服務是 IO 密集型而不是 CPU 密集型的服務,因此,選用 Intel Atom CPU 定制低功耗服務器,在保證服務性能的前提下大大降低了整體功耗。

五、分布式鍵值系統(tǒng)

分布式鍵值系統(tǒng)是用于存儲關系簡單的半結構化數(shù)據(jù),半結構化數(shù)據(jù)均封裝成由 鍵值對組成的對象,其中 key 為唯一標示符;value 為屬性值,可以為任何類型,如文字、圖片,也可以為空;timestamp 為時間戳,提供對象的多版本支持。分布式鍵值系統(tǒng)以鍵值對存儲,它的結構不固定,每一元組可以有不一樣的字段,可根據(jù)需要增加鍵值對,從而不局限于固定的結構,適用面更大,可擴展性更好。

分布式鍵值系統(tǒng)支持針對單個 鍵值對的增、刪、查、改操作,可以運行在 PC 服務器集群上,并實現(xiàn)集群按需擴展,從而處理大規(guī)模數(shù)據(jù),并通過數(shù)據(jù)備份保障容錯性,避免了分割數(shù)據(jù)帶來的復雜性和成本。

總體來說,分布式鍵值系統(tǒng)從存儲數(shù)據(jù)結構的角度看,分布式鍵值系統(tǒng)與傳統(tǒng)的哈希表比較類似,不同的是,分布式鍵值系統(tǒng)支持將數(shù)據(jù)分布到集群中的多個存儲節(jié)點。分布式鍵值系統(tǒng)可以配置數(shù)據(jù)的備份數(shù)目,可以將一份數(shù)據(jù)的所有副本存儲到不同的節(jié)點上,當有節(jié)點發(fā)生異常無法正常提供服務時,其余的節(jié)點會繼續(xù)提供服務。

5.1、 Amazon Dynamo

Dynamo 以很簡單的鍵值方式存儲數(shù)據(jù),不支持復雜的查詢。Dynamo 中存儲的是數(shù)據(jù)值的原始形式,不解析數(shù)據(jù)的具體內容。Dynamo 主要用于 Amazon 的購物車及 S3 云存儲服務。在實現(xiàn)過程中解決了如下問題:

問題 采用的技術
數(shù)據(jù)分布 改進的哈希算法
復制協(xié)議 復制寫協(xié)議(NRW參數(shù)可調)
數(shù)據(jù)沖突的解決 向量時鐘
臨時故障處理 數(shù)據(jù)回傳機制
永久故障處理 Merkle哈希樹
成員資格及錯誤檢測 基于Gossip的成員資格和錯誤檢測協(xié)議

Dynamo 采用一致性哈希將數(shù)據(jù)分布到多個存儲節(jié)點中,概括來說:給系統(tǒng)中的每個節(jié)點分配一個隨機 token ,這些 token 構成一個哈希環(huán)。執(zhí)行數(shù)據(jù)存放操作時,先計算主鍵的哈希值,然后存放到順時針方向的第一個大于或者等于該哈希值的 token 所在的節(jié)點。一致性哈希的有點在于節(jié)點加入 / 刪除只會影響到在哈希環(huán)相鄰的節(jié)點,而對其他節(jié)點沒影響。

Dynamo 架構

考慮到節(jié)點的異構性,不同節(jié)點的處理能力差別很大, Dynamo 使用了改進的一致性哈希算法:每個物理節(jié)點根據(jù)其性能的差異分配多個 token ,每個 token 對應一個虛擬節(jié)點,每個虛擬節(jié)點的處理能力基本相當,并隨機分布在哈希空間中。存儲時,數(shù)據(jù)按照哈希值落到某個虛擬節(jié)點負責的區(qū)域,然后被存儲到該虛擬節(jié)點所對應的物理節(jié)點。

如下圖,某 Dynamo 集群中原有 3 個節(jié)點,每個節(jié)點分配 3 個 token 。存放數(shù)據(jù)時,首先計算主鍵的哈希值,并根據(jù)哈希值將數(shù)據(jù)存放到對應 token 所在的節(jié)點。假設增加節(jié)點 4 ,節(jié)點 token 分配情況發(fā)生變化,這就實現(xiàn)了自動負載均衡。

【分布式】分布式存儲架構

為了找到數(shù)據(jù)所屬的節(jié)點,要求每個節(jié)點維護一定的集群信息用于定位。Dynamo 系統(tǒng)中每個節(jié)點維護整個集群的信息,客戶端也緩存整個集群的信息,因此,絕大部分請求能夠一次定位到目標節(jié)點。

Gossip 協(xié)議

由于機器或者人為的因素,系統(tǒng)中的節(jié)點成員加入或者刪除經常發(fā)生,為了保證每個節(jié)點緩存的都是 Dynamo 集群中最新的成員信息,所有節(jié)點每隔固定時間(比如 1s )通過 Gossip 協(xié)議的方式從其他節(jié)點中任意選擇一個與之通信的節(jié)點。如果連接成功,雙方交換各自保存的集群信息。

Gossip 協(xié)議用于 P2P 系統(tǒng)中自治的節(jié)點協(xié)調對整個集群的認識,比如集群的節(jié)點狀態(tài)、負載情況。我們先看看兩個節(jié)點 A 和 B 是如何交換對世界的認識的。

  • A 告訴 B 其管理的所有節(jié)點的版本(包括 Down 狀態(tài)和 Up 狀態(tài)的節(jié)點);

  • B 告訴 A 哪些版本它比較舊了,哪些版本它有最新的,然后把最新的那些節(jié)點發(fā)給 A (處于 Down 狀態(tài)的節(jié)點由于版本沒有發(fā)生更新所以不會被關注);

  • A 將 B 中比較舊的節(jié)點發(fā)送給 B ,同時將 B 發(fā)送來的最新節(jié)點信息做本地更新;

  • B 收到 A 發(fā)來的最新節(jié)點信息后,對本地緩存的比較舊的節(jié)點做更新。

由于種子節(jié)點的存在,新節(jié)點加入可以做得比較簡單。新節(jié)點加入時首先與種子節(jié)點交換集群信息,從而對集群有了認識。DHT ( Distributed Hash Table ,也稱為一致性哈希表)環(huán)中原有的其他節(jié)點也會定期和種子節(jié)點交換集群信息,從而發(fā)現(xiàn)新節(jié)點的加入。

集群不斷變化,可能隨時有機器下線,因此,每個節(jié)點還需要定期通過 Gossip 協(xié)議同其他節(jié)點交換集群信息。如果發(fā)現(xiàn)某個節(jié)點很長時間狀態(tài)都沒有更新,比如距離上次更新的時間間隔超過一定的閾值,則認為該節(jié)點已經下線了。

5.2、 Taobao Tiar

Tair 是一個分布式的 key/value 系統(tǒng)。

Tair 有四種引擎:mdb, rdb, kdb 和 ldb 。分別基于四種開源的 key/value 數(shù)據(jù)庫:memcached, Redis, Kyoto Cabinet 和 leveldb 。Tair 可以讓你更方便地使用這些 KV 數(shù)據(jù)庫。比如 Redis 沒有提供 sharding 操作,如果有多個 Redis Server ,你需要自己寫代碼實現(xiàn) sharding , Tair 幫你封裝了這些。

Tair 有以下優(yōu)點:

  • 統(tǒng)一的 API 。無論底層使用何種引擎,上層的 API 是一樣的。

  • Tair 將集群操作封裝起來,解放了開發(fā)者。淘寶內部在使用 Tair 時,一般都是雙機房雙集群容錯,利用 invalid server 保證兩個集群間的一致性,這些對于開發(fā)者都是透明的。

Tair 使用場景

  • 非持久化 (mdb,rdb)

    • 數(shù)據(jù)可以以 key/value 的形式存儲

    • 數(shù)據(jù)可以接受丟失

    • 訪問速度要求很高

    • 單個數(shù)據(jù)大小不是很大,一般在 KB 級別

    • 數(shù)據(jù)量很大,并且有較大的增長可能性

    • 數(shù)據(jù)更新不頻繁

  • 持久化 (kdb,ldb)

    • 數(shù)據(jù)可以以 key/value 的形式存儲

    • 數(shù)據(jù)需要持久化

    • 單個數(shù)據(jù)大小不是很大,一般在 KB 級別

    • 數(shù)據(jù)量很大,并且有較大的增長可能性

    • 數(shù)據(jù)的讀寫比例較高

Tair 的架構

Tair 作為一個分布式系統(tǒng),是由一個中心控制節(jié)點和若干個服務節(jié)點組成,

  • config server 功能:

    • 通過維護和 data server 心跳來獲知集群中存活節(jié)點的信息;

    • 根據(jù)存活節(jié)點的信息來構建數(shù)據(jù)在集群中的分布表;

    • 根據(jù)數(shù)據(jù)分布表的查詢服務;

    • 調度 data server 之間的數(shù)據(jù)遷移、復制;

  • data server 功能

    • 提供存儲引擎;

    • 接受 client 的 put/get/remove 等操作;

    • 執(zhí)行數(shù)據(jù)遷移,復制等;

    • 插件:在接受請求的時候處理一些自定義功能;

    • 訪問統(tǒng)計;

  • client 功能

    • 在應用端提供訪問 tair 集群的接口;

    • 更新并緩存數(shù)據(jù)分布表和 invalid server 地址等;

    • local cache ,避免過熱數(shù)據(jù)訪問影響 tair 集群服務;

    • 流控;

在下圖中,。客戶端首先請求 Config Server 獲取數(shù)據(jù)所在的 Data Server ,接著往 Data Server 發(fā)送讀寫請求。Tair 允許將數(shù)據(jù)存放到多臺 Data Server ,以實現(xiàn)異常容錯。

【分布式】分布式存儲架構

數(shù)據(jù)分布均衡性

Tair 的分布采用的是一致性哈希算法,對于所有的 key ,分到 Q 個桶中,桶是負載均衡和數(shù)據(jù)遷移的基本單位, config server 根據(jù)一定的策略把每個桶指派到不同的 data server 上,因為數(shù)據(jù)按照 key 做 hash 算法,保證了桶分布的均衡性,從而保證了數(shù)據(jù)分布的均衡性。

容錯

當某臺 Data Server 故障不可用時, Config Server 能夠檢測到。每個哈希桶在 Tair 中存儲多個副本,如果是備副本,那么 Config Server 會重新為其指定一臺 Data Server ,如果是持久化存儲,還將復制數(shù)據(jù)到新的 Data Server 上。如果是主副本,那么 ConfigServer 首先將某個正常的備副本提升為主副本,對外提供服務。接著,再選擇另外一臺 Data Server 增加一個備副本,確保數(shù)據(jù)的備份數(shù)。

數(shù)據(jù)遷移

增加或減少 data server 的時候, config server 會發(fā)現(xiàn)這個情況, config server 負責重新計算一張新的桶在 data server 上的分布表,將原來由減少的機器服務的桶的訪問重新指派到其他的 data server 中,這個時候就會發(fā)生數(shù)據(jù)的遷移。比如原來由 data server A 負責的桶,在新表中需要由 B 負責,而 B 上并沒有該桶的數(shù)據(jù),那么就將數(shù)據(jù)遷移到 B 上來,同時 config server 會發(fā)現(xiàn)哪些桶的備份數(shù)目減少了,然后根據(jù)負載均衡情況在負載較低的 data server 上增加這些桶的備份。當系統(tǒng)增加 data server 的時候, config server 根據(jù)負載,協(xié)調 data server 將他們控制的部分桶遷移到新的 data server 上,遷移完成后調整路由;

數(shù)據(jù)遷移時 data server 對外提供服務的策略,假設 data server A 要把桶 1,2,3 遷移到 data server B ,因為遷移完成前,客戶端的路由表沒有變化,客戶端對 1,2,3 的訪問請求都會路由到 A ,現(xiàn)在假設 1 還沒遷移, 2 正在遷移, 3 已經遷移完成,那么如果訪問 1 ,則還是訪問 data server A ,如果訪問 3 ,則 A 會把請求轉發(fā)給 B ,并且將 B 的返回結果返回給客戶,如果訪問 2 ,則在 A 上處理,同時如果是對 2 的修改操作,會記錄修改 log ,當桶 2 完成遷移的時候,還有把 log 發(fā)送給 B ,在 B 上應用這些 log ,最終 AB 數(shù)據(jù)一致才是真正完成遷移。如果 A 是由于宕機而引發(fā)的遷移,客戶端會收到一張中間臨時狀態(tài)的分配表,把宕機的 data server 負責的桶臨時指派給有其備份的 data server 來處理,此時服務是可用的,負載可能不均衡,當遷移完成后,又能達到一個新的負載均衡狀態(tài)。

5.3、 ETCD

ETCD etcd 是一個高可用的鍵值存儲系統(tǒng),主要用于共享配置和服務發(fā)現(xiàn)。

  • 由 CoreOS 開發(fā)并維護的,靈感來自于 ZooKeeper 和 Doozer ;

  • 它使用 Go 語言編寫,并通過 Raft 一致性算法處理日志復制以保證強一致。

  • Google 的容器集群管理系統(tǒng) Kubernetes 、開源 PaaS 平臺 Cloud Foundry 和 CoreOS 的 Fleet 都廣泛使用了 etcd ;

  • 當集群網(wǎng)絡出現(xiàn)動蕩,或者當前 master 節(jié)點出現(xiàn)異常時, etcd 可以進行 master 節(jié)點的選舉工作,同時恢復集群中損失的數(shù)據(jù)

ETCD 的特點

  • 簡單:基于 HTTP+JSON 的 API 讓你用 curl 就可以輕松使用。

  • 安全:可選 SSL 客戶認證機制。

  • 快速:每個實例每秒支持一千次寫操作。

  • 可信:使用 Raft 算法充分實現(xiàn)了分布式。

提供的能力

Etcd 主要提供以下能力

  • 提供存儲以及獲取數(shù)據(jù)的接口,它通過協(xié)議保證 Etcd 集群中的多個節(jié)點數(shù)據(jù)的強一致性。用于存儲元信息以及共享配置。

  • 提供監(jiān)聽機制,客戶端可以監(jiān)聽某個 key 或者某些 key 的變更。用于監(jiān)聽和推送變更。

  • 提供 key 的過期以及續(xù)約機制,客戶端通過定時刷新來實現(xiàn)續(xù)約( v2 和 v3 的實現(xiàn)機制也不一樣)。用于集群監(jiān)控以及服務注冊發(fā)現(xiàn)。

  • 提供原子的 CAS ( Compare-and-Swap )和 CAD ( Compare-and-Delete )支持( v2 通過接口參數(shù)實現(xiàn), v3 通過批量事務實現(xiàn))。用于分布式鎖以及 leader 選舉。

ETCD 架構

Etcd v2 存儲, Watch 以及過期機制

Etcd v2 是個純內存的實現(xiàn),并未實時將數(shù)據(jù)寫入到磁盤,持久化機制很簡單,就是將 store 整合序列化成 json 寫入文件。數(shù)據(jù)在內存中是一個簡單的樹結構。

store 中有一個全局的 currentIndex ,每次變更, index 會加 1. 然后每個 event 都會關聯(lián)到 currentIndex.

當客戶端調用 watch 接口(參數(shù)中增加 wait 參數(shù))時,如果請求參數(shù)中有 waitIndex ,并且 waitIndex 小于 currentIndex ,則從 EventHistroy 表中查詢 index 小于等于 waitIndex ,并且和 watch key 匹配的 event ,如果有數(shù)據(jù),則直接返回。如果歷史表中沒有或者請求沒有帶 waitIndex ,則放入 WatchHub 中,每個 key 會關聯(lián)一個 watcher 列表。當有變更操作時,變更生成的 event 會放入 EventHistroy 表中,同時通知和該 key 相關的 watcher 。

Etcd v3 存儲, Watch 以及過期機制

Etcd v3 將 watch 和 store 拆開實現(xiàn),我們先分析下 store 的實現(xiàn)。Etcd v3 store 分為兩部分,一部分是內存中的索引, kvindex ,是基于 google 開源的一個 golang 的 btree 實現(xiàn)的,另外一部分是后端存儲。

按照它的設計, backend 可以對接多種存儲,當前使用的 boltdb 。boltdb 是一個單機的支持事務的 kv 存儲, Etcd 的事務是基于 boltdb 的事務實現(xiàn)的。Etcd 在 boltdb 中存儲的 key 是 reversion , value 是 Etcd 自己的 key-value 組合,也就是說 Etcd 會在 boltdb 中把每個版本都保存下,從而實現(xiàn)了多版本機制。

5.4 、產品選型比較( Etcd , Zookeeper , Consul 比較)

這三個產品是經常被人拿來做選型比較的。

  • Etcd 和 Zookeeper 提供的能力非常相似,都是通用的一致性元信息存儲,都提供 watch 機制用于變更通知和分發(fā),也都被分布式系統(tǒng)用來作為共享信息存儲,在軟件生態(tài)中所處的位置也幾乎是一樣的,可以互相替代的。二者除了實現(xiàn)細節(jié),語言,一致性協(xié)議上的區(qū)別,最大的區(qū)別在周邊生態(tài)圈。Zookeeper 是 apache 下的,用 java 寫的,提供 rpc 接口,最早從 hadoop 項目中孵化出來,在分布式系統(tǒng)中得到廣泛使用( hadoop, solr, kafka, mesos 等)。Etcd 是 coreos 公司旗下的開源產品,比較新,以其簡單好用的 rest 接口以及活躍的社區(qū)俘獲了一批用戶,在新的一些集群中得到使用(比如 kubernetes )。雖然 v3 為了性能也改成二進制 rpc 接口了,但其易用性上比 Zookeeper 還是好一些。

  • Consul 的目標則更為具體一些, Etcd 和 Zookeeper 提供的是分布式一致性存儲能力,具體的業(yè)務場景需要用戶自己實現(xiàn),比如服務發(fā)現(xiàn),比如配置變更。而 Consul 則以服務發(fā)現(xiàn)和配置變更為主要目標,同時附帶了 kv 存儲。在軟件生態(tài)中,越抽象的組件適用范圍越廣,但同時對具體業(yè)務場景需求的滿足上肯定有不足之處。文章來源地址http://www.zghlxwxcb.cn/news/detail-497442.html

到了這里,關于【分布式】分布式存儲架構的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 分布式系統(tǒng)架構設計之分布式數(shù)據(jù)存儲的擴展方式、主從復制以及分布式一致性

    分布式系統(tǒng)架構設計之分布式數(shù)據(jù)存儲的擴展方式、主從復制以及分布式一致性

    在分布式系統(tǒng)中,數(shù)據(jù)存儲的擴展是為了適應業(yè)務的增長和提高系統(tǒng)的性能。分為水平擴展和垂直擴展兩種方式,這兩種方式在架構設計和應用場景上有著不同的優(yōu)勢和局限性。 水平擴展是通過增加節(jié)點或服務器的數(shù)量來擴大整個系統(tǒng)的容量和性能。在數(shù)據(jù)存儲領域,水平擴

    2024年02月03日
    瀏覽(102)
  • 存儲網(wǎng)絡架構——DAS、NAS、SAN、分布式組網(wǎng)架構

    存儲網(wǎng)絡架構——DAS、NAS、SAN、分布式組網(wǎng)架構

    目錄 物理存儲的類型 存儲網(wǎng)絡架構 DAS直連式存儲 NAS網(wǎng)絡附加存儲 SAN存儲區(qū)域網(wǎng)絡 分布式存儲組網(wǎng) 存儲的類型主要包含塊存儲、文件存儲、對象存儲、表格存儲等 常用的為塊存儲和文件存儲(文件存儲可以直接進行文件讀寫,塊存儲需要進行文件系統(tǒng)格式化后才可以進行

    2024年02月02日
    瀏覽(27)
  • 深入淺出 -- 系統(tǒng)架構之分布式多形態(tài)的存儲型集群

    深入淺出 -- 系統(tǒng)架構之分布式多形態(tài)的存儲型集群

    在上階段,我們簡單聊了下集群的基本知識,以及快速過了一下邏輯處理型集群的內容,下面重點來看看存儲型集群,畢竟這塊才是重頭戲,集群的形態(tài)在其中有著多種多樣的變化。 邏輯處理型的應用,部署集群架構是為了解決單點故障、獲得更高的吞吐量,集群內各節(jié)點之

    2024年04月10日
    瀏覽(103)
  • 分布式數(shù)據(jù)存儲建設方法論——從HDFS架構優(yōu)化與實踐分析

    作者:禪與計算機程序設計藝術 隨著互聯(lián)網(wǎng)、云計算、大數(shù)據(jù)等新一代信息技術的出現(xiàn)和普及,數(shù)據(jù)量的激增、數(shù)據(jù)安全性的需求以及數(shù)據(jù)的分布式儲存需求日益成為各大公司和組織面臨的難題。傳統(tǒng)的單體架構模式已經無法應付如此復雜的業(yè)務場景,因此,分布式數(shù)據(jù)存儲

    2024年02月11日
    瀏覽(30)
  • 7 集中式日志和分布式跟蹤

    7 集中式日志和分布式跟蹤

    前面的文章: 1、 1 一個測試驅動的Spring Boot應用程序開發(fā) 2、 2 使用React構造前端應用 3、 3 試驅動的Spring Boot應用程序開發(fā)數(shù)據(jù)層示例 4、 4 向微服務架構轉變 5、 5 轉向事件驅動的架構 6、 6 網(wǎng)關和配置服務器 代碼:下載 前面的系統(tǒng)中已經涉及幾個組件生成的日志(Multipl

    2024年02月03日
    瀏覽(33)
  • SDN:分布式與集中式的優(yōu)缺點

    SDN定義 軟件定義網(wǎng)絡 (Software Defined Network, SDN ),是Emulex網(wǎng)絡一種新型網(wǎng)絡創(chuàng)新架構,其核心技術OpenFlow通過將網(wǎng)絡設備控制面與數(shù)據(jù)面分離開來,從而實現(xiàn)了網(wǎng)絡流量的靈活控制。 我覺得這一段對于計算機的發(fā)展歷程的描述,其實也是一段對于集中式與分布式的很好的論

    2024年02月07日
    瀏覽(22)
  • 【分布式技術】分布式存儲ceph之RBD塊存儲部署

    【分布式技術】分布式存儲ceph之RBD塊存儲部署

    目錄 創(chuàng)建 Ceph 塊存儲系統(tǒng) RBD 接口 服務端操作 1、創(chuàng)建一個名為 rbd-demo 的專門用于 RBD 的存儲池 2、將存儲池轉換為 RBD 模式 3、初始化存儲池 4、創(chuàng)建鏡像 5、在管理節(jié)點創(chuàng)建并授權一個用戶可訪問指定的 RBD 存儲池 6、修改RBD鏡像特性,CentOS7默認情況下只支持layering和stripin

    2024年01月18日
    瀏覽(35)
  • 分布式鍵值存儲是什么?(分布式鍵值存儲大值)

    分布式鍵值存儲是一種分布式數(shù)據(jù)存儲系統(tǒng),它將數(shù)據(jù)存儲為鍵值對的形式,并將這些鍵值對分散在多個節(jié)點上。每個節(jié)點都可以獨立地處理一部分數(shù)據(jù),從而實現(xiàn)高可用性和可擴展性。分布式鍵值存儲通常具有以下特點: 簡單:數(shù)據(jù)以鍵值對的形式存儲,操作簡單,易于使

    2024年02月03日
    瀏覽(22)
  • 云存儲、云計算與分布式存儲、分布式計算是一回事嗎?

    云存儲、云計算與分布式存儲、分布式計算是一回事嗎?

    隨著互聯(lián)網(wǎng)的蓬勃興起,大數(shù)據(jù)、人工智能、物聯(lián)網(wǎng)、云計算與云存儲等這些專業(yè)詞匯在大眾視野內出現(xiàn)的頻率越來越高,再加上近幾年分布式技術異軍突起,更使得分布式存儲、分布式計算等成為熱詞。然而,很多人對這些名詞都一知半解,所以本文將主要和大家聊一聊,

    2024年01月25日
    瀏覽(31)
  • 【分布式技術】分布式存儲ceph之RGW接口

    【分布式技術】分布式存儲ceph之RGW接口

    目錄 1、對象存儲概念 ?2、創(chuàng)建 RGW 接口 //在管理節(jié)點創(chuàng)建一個 RGW 守護進程 #創(chuàng)建成功后默認情況下會自動創(chuàng)建一系列用于 RGW 的存儲池? #默認情況下 RGW 監(jiān)聽 7480 號端口? //開啟 http+https ,更改監(jiān)聽端口 #更改監(jiān)聽端口 ?? ? ? ? ? //創(chuàng)建 RadosGW 賬戶 客戶端測試 OSD 故障模擬

    2024年01月19日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包