Ceph淺析(中):結構、工做原理及流程

Ceph的結構

Ceph系統的層次結構

Ceph存儲系統的邏輯層次結構以下圖所示:web

 

自下向上,能夠將Ceph系統分爲四個層次:算法

(1)基礎存儲系統RADOS(Reliable, Autonomic, Distributed Object Store,便可靠的、自動化的、分佈式的對象存儲)編程

顧名思義,這一層自己就是一個完整的對象存儲系統,全部存儲在Ceph系統中的用戶數據事實上最終都是由這一層來存儲的。而Ceph的高可靠、高可擴展、高性能、高自動化等等特性本質上也是由這一層所提供的。所以,理解RADOS是理解Ceph的基礎與關鍵。安全

物理上,RADOS由大量的存儲設備節點組層,每一個節點擁有本身的硬件資源(CPU、內存、硬盤、網絡),並運行着操做系統和文件系統。4.二、4.3節將對RADOS進行展開介紹。服務器

(2)基礎庫librados網絡

這一層的功能是對RADOS進行抽象和封裝,並向上層提供API,以便直接基於RADOS(而不是整個Ceph)進行應用開發。特別要注意的是,RADOS是一個對象存儲系統,所以,librados實現的API也只是針對對象存儲功能的。數據結構

RADOS採用C++開發,所提供的原生librados API包括C和C++兩種,其文檔參見[2]。物理上,librados和基於其上開發的應用位於同一臺機器,於是也被稱爲本地API。應用調用本機上的librados API,再由後者經過socket與RADOS集羣中的節點通訊並完成各類操做。架構

(3)高層應用接口dom

這一層包括了三個部分:RADOS GW(RADOS Gateway)、 RBD(Reliable Block Device)和Ceph FS(Ceph File System),其做用是在librados庫的基礎上提供抽象層次更高、更便於應用或客戶端使用的上層接口。異步

其中,RADOS GW是一個提供與Amazon S3和Swift兼容的RESTful API的gateway,以供相應的對象存儲應用開發使用。RADOS GW提供的API抽象層次更高,但功能則不如librados強大。所以,開發者應針對本身的需求選擇使用。

RBD則提供了一個標準的塊設備接口,經常使用於在虛擬化的場景下爲虛擬機建立volume。目前,Red Hat已經將RBD驅動集成在KVM/QEMU中,以提升虛擬機訪問性能。

Ceph FS是一個POSIX兼容的分佈式文件系統。因爲還處在開發狀態,於是Ceph官網並不推薦將其用於生產環境中。

(4)應用層

這一層就是不一樣場景下對於Ceph各個應用接口的各類應用方式,例如基於librados直接開發的對象存儲應用,基於RADOS GW開發的對象存儲應用,基於RBD實現的雲硬盤等等。

在上文的介紹中,有一個地方可能容易引發困惑:RADOS自身既然已是一個對象存儲系統,而且也能夠提供librados API,爲什麼還要再單獨開發一個RADOS GW?

理解這個問題,事實上有助於理解RADOS的本質,所以有必要在此加以分析。粗看起來,librados和RADOS GW的區別在於,librados提供的是本地API,而RADOS GW提供的則是RESTful API,兩者的編程模型和實際性能不一樣。而更進一步說,則和這兩個不一樣抽象層次的目標應用場景差別有關。換言之,雖然RADOS和S三、Swift同屬分佈式對象存儲系統,但RADOS提供的功能更爲基礎、也更爲豐富。這一點能夠經過對比看出。

因爲Swift和S3支持的API功能近似,這裏以Swift舉例說明。Swift提供的API功能主要包括:

  • 用戶管理操做:用戶認證、獲取帳戶信息、列出容器列表等;
  • 容器管理操做:建立/刪除容器、讀取容器信息、列出容器內對象列表等;
  • 對象管理操做:對象的寫入、讀取、複製、更新、刪除、訪問許可設置、元數據讀取或更新等。

因而可知,Swift(以及S3)提供的API所操做的「對象」只有三個:用戶帳戶、用戶存儲數據對象的容器、數據對象。而且,全部的操做均不涉及存儲系統 的底層硬件或系統信息。不難看出,這樣的API設計徹底是針對對象存儲應用開發者和對象存儲應用用戶的,而且假定其開發者和用戶關心的內容更偏重於帳戶和數據的管理,而對底層存儲系統細節不感興趣,更不關心效率、性能等方面的深刻優化。 

而librados API的設計思想則與此徹底不一樣。一方面,librados中沒有帳戶、容器這樣的高層概念;另外一方面,librados API向開發者開放了大量的RADOS狀態信息與配置參數,容許開發者對RADOS系統以及其中存儲的對象的狀態進行觀察,並強有力地對系統存儲策略進行控制。換言之,經過調用librados API,應用不只可以實現對數據對象的操做,還可以實現對RADOS系統的管理和配置。這對於S3和Swift的RESTful API設計是不可想像的,也是沒有必要的。 

基於上述分析對比,不難看出,librados事實上更適合對於系統有着深入理解,同時對於功能定製擴展和性能深度優化有着強烈需求的高級用戶。基於librados的開發可能更適合於在私有Ceph系統上開發專用應用,或者爲基於Ceph的公有存儲系統開發後臺數據管理、處理應用。而RADOS GW則更適合於常見的基於web的對象存儲應用開發,例如公有云上的對象存儲服務。 

RADOS的邏輯結構 

RADOS的系統邏輯結構以下圖所示

 

在使用RADOS系統時,大量的客戶端程序經過與OSD或者monitor的交互獲取cluster map,而後直接在本地進行計算,得出對象的存儲位置後,便直接與對應的OSD通訊,完成數據的各類操做。可見,在此過程當中,只要保證cluster map不頻繁更新,則客戶端顯然能夠不依賴於任何元數據服務器,不進行任何查表操做,便完成數據訪問流程。在RADOS的運行過程當中,cluster map的更新徹底取決於系統的狀態變化,而致使這一變化的常見事件只有兩種:OSD出現故障,或者RADOS規模擴大。而正常應用場景下,這兩種事件發生 的頻率顯然遠遠低於客戶端對數據進行訪問的頻率。

 OSD的邏輯結構

根據定義,OSD能夠被抽象爲兩個組成部分,即系統部分和守護進程(OSD deamon)部分。

OSD的系統部分本質上就是一臺安裝了操做系統和文件系統的計算機,其硬件部分至少包括一個單核的處理器、必定數量的內存、一塊硬盤以及一張網卡。

因爲這麼小規模的x86架構服務器並不實用(事實上也見不到),於是實際應用中一般將多個OSD集中部署在一臺更大規模的服務器上。在選擇系統配置時,應當 可以保證每一個OSD佔用必定的計算能力、必定量的內存和一塊硬盤。同時,應當保證該服務器具有足夠的網絡帶寬。具體的硬件配置選擇能夠參考。

在 上述系統平臺上,每一個OSD擁有一個本身的OSD deamon。這個deamon負責完成OSD的全部邏輯功能,包括與monitor和其餘OSD(事實上是其餘OSD的deamon)通訊以維護更新系 統狀態,與其餘OSD共同完成數據的存儲和維護,與client通訊完成各類數據對象操做等等。

Ceph系統的邏輯結構就介紹到這裏。下篇文章將着重說明Ceph(主要是RADOS)的工做原理和操做流程。

如圖所示,RADOS集羣主要由兩種節點組成。一種是爲數衆多的、負責完成數據存儲和維護功能的OSD(Object Storage Device),另外一種則是若干個負責完成系統狀態檢測和維護的monitor。OSD和monitor之間相互傳輸節點狀態信息,共同得出系統的整體工 做狀態,並造成一個全局系統狀態記錄數據結構,即所謂的cluster map。這個數據結構與RADOS提供的特定算法相配合,便實現了Ceph「無需查表,算算就好」的核心機制以及若干優秀特性。 

Ceph的工做原理及流程

本節將對Ceph的工做原理和若干關鍵工做流程進行扼要介紹。如前所述,因爲Ceph的功能實現本質上依託於RADOS,於是,此處的介紹事實上也是針對RADOS進行。對於上層的部分,特別是RADOS GW和RBD,因爲現有的文檔中(包括Sage的論文中)並未詳細介紹,還請讀者多多包涵。

首先介紹RADOS中最爲核心的、基於計算的對象尋址機制,而後說明對象存取的工做流程,以後介紹RADOS集羣維護的工做過程,最後結合Ceph的結構和原理對其技術優點加以回顧和剖析。

尋址流程

Ceph系統中的尋址流程以下圖所示:

上圖左側的幾個概念說明以下:

1. File —— 此處的file就是用戶須要存儲或者訪問的文件。對於一個基於Ceph開發的對象存儲應用而言,這個file也就對應於應用中的「對象」,也就是用戶直接操做的「對象」。

2. Ojbect —— 此處的object是RADOS所看到的「對象」。Object與上面提到的file的區別是,object的最大size由RADOS限定(一般爲2MB或4MB),以便實現底層存儲的組織管理。所以,當上層應用向RADOS存入size很大的file時,須要將file切分紅統一大小的一系列object(最後一個的大小能夠不一樣)進行存儲。爲避免混淆,在本文中將盡可能避免使用中文的「對象」這一名詞,而直接使用file或object進行說明。

3. PG(Placement Group)—— 顧名思義,PG的用途是對object的存儲進行組織和位置映射。具體而言,一個PG負責組織若干個object(能夠爲數千個甚至更多),但一個object只能被映射到一個PG中,即,PG和object之間是「一對多」映射關係。同時,一個PG會被映射到n個OSD上,而每一個OSD上都會承載大量的PG,即,PG和OSD之間是「多對多」映射關係。在實踐當中,n至少爲2,若是用於生產環境,則至少爲3。一個OSD上的PG則可達到數百個。事實上,PG數量的設置牽扯到數據分佈的均勻性問題。關於這一點,下文還將有所展開。

4. OSD —— 即object storage device,前文已經詳細介紹,此處再也不展開。惟一須要說明的是,OSD的數量事實上也關係到系統的數據分佈均勻性,所以其數量不該太少。在實踐當中,至少也應該是數十上百個的量級纔有助於Ceph系統的設計發揮其應有的優點。

5. Failure domain —— 這個概念在論文中並無進行定義,好在對分佈式存儲系統有必定概念的讀者應該可以瞭解其大意。

基於上述定義,即可以對尋址流程進行解釋了。具體而言, Ceph中的尋址至少要經歷如下三次映射:

1. File -> object映射

此次映射的目的是,將用戶要操做的file,映射爲RADOS可以處理的object。其映射十分簡單,本質上就是按照object的最大size對file進行切分,至關於RAID中的條帶化過程。這種切分的好處有二:一是讓大小不限的file變成最大size一致、能夠被RADOS高效管理的object;二是讓對單一file實施的串行處理變爲對多個object實施的並行化處理。

每個切分後產生的object將得到惟一的oid,即object id。其產生方式也是線性映射,極其簡單。圖中,ino是待操做file的元數據,能夠簡單理解爲該file的惟一id。ono則是由該file切分產生的某個object的序號。而oid就是將這個序號簡單連綴在該file id以後獲得的。舉例而言,若是一個id爲filename的file被切分紅了三個object,則其object序號依次爲0、1和2,而最終獲得的oid就依次爲filename0、filename1和filename2。

這裏隱含的問題是,ino的惟一性必須獲得保證,不然後續映射沒法正確進行。

2. Object -> PG映射

在file被映射爲一個或多個object以後,就須要將每一個object獨立地映射到一個PG中去。這個映射過程也很簡單,如圖中所示,其計算公式是:

hash(oid) & mask -> pgid

因而可知,其計算由兩步組成。首先是使用Ceph系統指定的一個靜態哈希函數計算oid的哈希值,將oid映射成爲一個近似均勻分佈的僞隨機值。而後,將這個僞隨機值和mask按位相與,獲得最終的PG序號(pgid)。根據RADOS的設計,給定PG的總數爲m(m應該爲2的整數冪),則mask的值爲m-1。所以,哈希值計算和按位與操做的總體結果事實上是從全部m個PG中近似均勻地隨機選擇一個。基於這一機制,當有大量object和大量PG時,RADOS可以保證object和PG之間的近似均勻映射。又由於object是由file切分而來,大部分object的size相同,於是,這一映射最終保證了,各個PG中存儲的object的總數據量近似均勻。

從介紹不難看出,這裏反覆強調了「大量」。只有當object和PG的數量較多時,這種僞隨機關係的近似均勻性才能成立,Ceph的數據存儲均勻性纔有保證。爲保證「大量」的成立,一方面,object的最大size應該被合理配置,以使得一樣數量的file可以被切分紅更多的object;另外一方面,Ceph也推薦PG總數應該爲OSD總數的數百倍,以保證有足夠數量的PG可供映射。

3. PG -> OSD映射

第三次映射就是將做爲object的邏輯組織單元的PG映射到數據的實際存儲單元OSD。如圖所示,RADOS採用一個名爲CRUSH的算法,將pgid代入其中,而後獲得一組共n個OSD。這n個OSD即共同負責存儲和維護一個PG中的全部object。前已述及,n的數值能夠根據實際應用中對於可靠性的需求而配置,在生產環境下一般爲3。具體到每一個OSD,則由其上運行的OSD deamon負責執行映射到本地的object在本地文件系統中的存儲、訪問、元數據維護等操做。

和「object -> PG」映射中採用的哈希算法不一樣,這個CRUSH算法的結果不是絕對不變的,而是受到其餘因素的影響。其影響因素主要有二:

一是當前系統狀態,也就是上文邏輯結構中曾經說起的cluster map。當系統中的OSD狀態、數量發生變化時,cluster map可能發生變化,而這種變化將會影響到PG與OSD之間的映射。

二是存儲策略配置。這裏的策略主要與安全相關。利用策略配置,系統管理員能夠指定承載同一個PG的3個OSD分別位於數據中心的不一樣服務器乃至機架上,從而進一步改善存儲的可靠性。

所以,只有在系統狀態(cluster map)和存儲策略都不發生變化的時候,PG和OSD之間的映射關係纔是固定不變的。在實際使用當中,策略一經配置一般不會改變。而系統狀態的改變或者是因爲設備損壞,或者是由於存儲集羣規模擴大。好在Ceph自己提供了對於這種變化的自動化支持,於是,即使PG與OSD之間的映射關係發生了變化,也並不會對應用形成困擾。事實上,Ceph正是須要有目的的利用這種動態映射關係。正是利用了CRUSH的動態特性,Ceph能夠將一個PG根據須要動態遷移到不一樣的OSD組合上,從而自動化地實現高可靠性、數據分佈re-blancing等特性。

之因此在這次映射中使用CRUSH算法,而不是其餘哈希算法,緣由之一正是CRUSH具備上述可配置特性,能夠根據管理員的配置參數決定OSD的物理位置映射策略;另外一方面是由於CRUSH具備特殊的「穩定性」,也即,當系統中加入新的OSD,致使系統規模增大時,大部分PG與OSD之間的映射關係不會發生改變,只有少部分PG的映射關係會發生變化並引起數據遷移。這種可配置性和穩定性都不是普通哈希算法所能提供的。所以,CRUSH算法的設計也是Ceph的核心內容之一,具體介紹能夠參考。

至此爲止,Ceph經過三次映射,完成了從file到object、PG和OSD整個映射過程。通觀整個過程,能夠看到,這裏沒有任何的全局性查表操做需求。至於惟一的全局性數據結構cluster map,在後文中將加以介紹。能夠在這裏指明的是,cluster map的維護和操做都是輕量級的,不會對系統的可擴展性、性能等因素形成不良影響。

一個可能出現的困惑是:爲何須要同時設計第二次和第三次映射?難道不重複麼?關於這一點,Sage在其論文中解說很少,而筆者我的的分析以下:

咱們能夠反過來想像一下,若是沒有PG這一層映射,又會怎麼樣呢?在這種狀況下,必定須要採用某種算法,將object直接映射到一組OSD上。若是這種算法是某種固定映射的哈希算法,則意味着一個object將被固定映射在一組OSD上,當其中一個或多個OSD損壞時,object沒法被自動遷移至其餘OSD上(由於映射函數不容許),當系統爲了擴容新增了OSD時,object也沒法被re-balance到新的OSD上(一樣由於映射函數不容許)。這些限制都違背了Ceph系統高可靠性、高自動化的設計初衷。

若是採用一個動態算法(例如仍然採用CRUSH算法)來完成這一映射,彷佛是能夠避免靜態映射致使的問題。可是,其結果將是各個OSD所處理的本地元數據量爆增,由此帶來的計算複雜度和維護工做量也是難以承受的。

例如,在Ceph的現有機制中,一個OSD平時須要和與其共同承載同一個PG的其餘OSD交換信息,以肯定各自是否工做正常,是否須要進行維護操做。因爲一個OSD上大約承載數百個PG,每一個PG內一般有3個OSD,所以,一段時間內,一個OSD大約須要進行數百至數千次OSD信息交換。

然而,若是沒有PG的存在,則一個OSD須要和與其共同承載同一個object的其餘OSD交換信息。因爲每一個OSD上承載的object極可能高達數百萬個,所以,一樣長度的一段時間內,一個OSD大約須要進行的OSD間信息交換將暴漲至數百萬乃至數千萬次。而這種狀態維護成本顯然太高。

綜上所述,筆者認爲,引入PG的好處至少有二:一方面實現了object和OSD之間的動態映射,從而爲Ceph的可靠性、自動化等特性的實現留下了空間;另外一方面也有效簡化了數據的存儲組織,大大下降了系統的維護管理開銷。理解這一點,對於完全理解Ceph的對象尋址機制,是十分重要的。

數據操做流程

此處將首先以file寫入過程爲例,對數據操做流程進行說明。

爲簡化說明,便於理解,此處進行若干假定。首先,假定待寫入的file較小,無需切分,僅被映射爲一個object。其次,假定系統中一個PG被映射到3個OSD上。

基於上述假定,則file寫入流程能夠被下圖表示:

 

如圖所示,當某個client須要向Ceph集羣寫入一個file時,首先須要在本地完成5.1節中所敘述的尋址流程,將file變爲一個object,而後找出存儲該object的一組三個OSD。這三個OSD具備各自不一樣的序號,序號最靠前的那個OSD就是這一組中的Primary OSD,然後兩個則依次是Secondary OSD和Tertiary OSD。

找出三個OSD後,client將直接和Primary OSD通訊,發起寫入操做(步驟1)。Primary OSD收到請求後,分別向Secondary OSD和Tertiary OSD發起寫入操做(步驟二、3)。當Secondary OSD和Tertiary OSD各自完成寫入操做後,將分別向Primary OSD發送確認信息(步驟四、5)。當Primary OSD確信其餘兩個OSD的寫入完成後,則本身也完成數據寫入,並向client確認object寫入操做完成(步驟6)。

之因此採用這樣的寫入流程,本質上是爲了保證寫入過程當中的可靠性,儘量避免形成數據丟失。同時,因爲client只須要向Primary OSD發送數據,所以,在Internet使用場景下的外網帶寬和總體訪問延遲又獲得了必定程度的優化。

固然,這種可靠性機制必然致使較長的延遲,特別是,若是等到全部的OSD都將數據寫入磁盤後再向client發送確認信號,則總體延遲可能難以忍受。所以,Ceph能夠分兩次向client進行確認。當各個OSD都將數據寫入內存緩衝區後,就先向client發送一次確認,此時client便可以向下執行。待各個OSD都將數據寫入磁盤後,會向client發送一個最終確認信號,此時client能夠根據須要刪除本地數據。

分析上述流程能夠看出,在正常狀況下,client能夠獨立完成OSD尋址操做,而沒必要依賴於其餘系統模塊。所以,大量的client能夠同時和大量的OSD進行並行操做。同時,若是一個file被切分紅多個object,這多個object也可被並行發送至多個OSD。

從OSD的角度來看,因爲同一個OSD在不一樣的PG中的角色不一樣,所以,其工做壓力也能夠被儘量均勻地分擔,從而避免單個OSD變成性能瓶頸。

若是須要讀取數據,client只需完成一樣的尋址過程,並直接和Primary OSD聯繫。目前的Ceph設計中,被讀取的數據僅由Primary OSD提供。但目前也有分散讀取壓力以提升性能的討論。

集羣維護

前面的介紹中已經提到,由若干個monitor共同負責整個Ceph集羣中全部OSD狀態的發現與記錄,而且共同造成cluster map的master版本,而後擴散至全體OSD以及client。OSD使用cluster map進行數據的維護,而client使用cluster map進行數據的尋址。

在集羣中,各個monitor的功能整體上是同樣的,其相互間的關係能夠被簡單理解爲主從備份關係。所以,在下面的討論中不對各個monitor加以區分。

略顯出乎意料的是,monitor並不主動輪詢各個OSD的當前狀態。正相反,OSD須要向monitor上報狀態信息。常見的上報有兩種狀況:一是新的OSD被加入集羣,二是某個OSD發現自身或者其餘OSD發生異常。在收到這些上報信息後,monitor將更新cluster map信息並加以擴散。其細節將在下文中加以介紹。

Cluster map的實際內容包括:

(1) Epoch,即版本號。Cluster map的epoch是一個單調遞增序列。Epoch越大,則cluster map版本越新。所以,持有不一樣版本cluster map的OSD或client能夠簡單地經過比較epoch決定應該聽從誰手中的版本。而monitor手中一定有epoch最大、版本最新的cluster map。當任意兩方在通訊時發現彼此epoch值不一樣時,將默認先將cluster map同步至高版本一方的狀態,再進行後續操做。

(2)各個OSD的網絡地址。

(3)各個OSD的狀態。OSD狀態的描述分爲兩個維度:up或者down(代表OSD是否正常工做),in或者out(代表OSD是否在至少一個PG中)。所以,對於任意一個OSD,共有四種可能的狀態:

—— Up且in:說明該OSD正常運行,且已經承載至少一個PG的數據。這是一個OSD的標準工做狀態;

—— Up且out:說明該OSD正常運行,但並未承載任何PG,其中也沒有數據。一個新的OSD剛剛被加入Ceph集羣后,便會處於這一狀態。而一個出現故障的OSD被修復後,從新加入Ceph集羣時,也是處於這一狀態;

—— Down且in:說明該OSD發生異常,但仍然承載着至少一個PG,其中仍然存儲着數據。這種狀態下的OSD剛剛被發現存在異常,可能仍能恢復正常,也可能會完全沒法工做;

—— Down且out:說明該OSD已經完全發生故障,且已經再也不承載任何PG。

(4)CRUSH算法配置參數。代表了Ceph集羣的物理層級關係(cluster hierarchy),位置映射規則(placement rules)。

根據cluster map的定義能夠看出,其版本變化一般只會由(3)和(4)兩項信息的變化觸發。而這二者相比,(3)發生變化的機率更高一些。這能夠經過下面對OSD工做狀態變化過程的介紹加以反映。

一個新的OSD上線後,首先根據配置信息與monitor通訊。Monitor將其加入cluster map,並設置爲up且out狀態,再將最新版本的cluster map發給這個新OSD。

收到monitor發來的cluster map以後,這個新OSD計算出本身所承載的PG(爲簡化討論,此處咱們假定這個新的OSD開始只承載一個PG),以及和本身承載同一個PG的其餘OSD。而後,新OSD將與這些OSD取得聯繫。若是這個PG目前處於降級狀態(即承載該PG的OSD個數少於正常值,如正常應該是3個,此時只有2個或1個。這種狀況一般是OSD故障所致),則其餘OSD將把這個PG內的全部對象和元數據複製給新OSD。數據複製完成後,新OSD被置爲up且in狀態。而cluster map內容也將據此更新。這事實上是一個自動化的failure recovery過程。固然,即使沒有新的OSD加入,降級的PG也將計算出其餘OSD實現failure recovery。

若是該PG目前一切正常,則這個新OSD將替換掉現有OSD中的一個(PG內將從新選出Primary OSD),並承擔其數據。在數據複製完成後,新OSD被置爲up且in狀態,而被替換的OSD將退出該PG(但狀態一般仍然爲up且in,由於還要承載其餘PG)。而cluster map內容也將據此更新。這事實上是一個自動化的數據re-balancing過程。

若是一個OSD發現和本身共同承載一個PG的另外一個OSD沒法聯通,則會將這一狀況上報monitor。此外,若是一個OSD deamon發現自身工做狀態異常,也將把異常狀況主動上報給monitor。在上述狀況下,monitor將把出現問題的OSD的狀態設爲down且in。若是超過某一預訂時間期限,該OSD仍然沒法恢復正常,則其狀態將被設置爲down且out。反之,若是該OSD可以恢復正常,則其狀態會恢復爲up且in。在上述這些狀態變化發生以後,monitor都將更新cluster map並進行擴散。這事實上是自動化的failure detection過程。

由以前介紹能夠看出,對於一個Ceph集羣而言,即使由數千個甚至更多OSD組成,cluster map的數據結構大小也並不驚人。同時,cluster map的狀態更新並不會頻繁發生。即使如此,Ceph依然對cluster map信息的擴散機制進行了優化,以便減輕相關計算和通訊壓力。

首先,cluster map信息是以增量形式擴散的。若是任意一次通訊的雙方發現其epoch不一致,則版本更新的一方將把兩者所擁有的cluster map的差別發送給另一方。

其次,cluster map信息是以異步且lazy的形式擴散的。也即,monitor並不會在每一次cluster map版本更新後都將新版本廣播至全體OSD,而是在有OSD向本身上報信息時,將更新回覆給對方。相似的,各個OSD也是在和其餘OSD通訊時,將更新發送給版本低於本身的對方。

基於上述機制,Ceph避免了因爲cluster map版本更新而引發的廣播風暴。這雖然是一種異步且lazy的機制,但根據Sage論文中的結論,對於一個由n個OSD組成的Ceph集羣,任何一次版本更新可以在O(log(n))時間複雜度內擴散到集羣中的任何一個OSD上。

一個可能被問到的問題是:既然這是一種異步和lazy的擴散機制,則在版本擴散過程當中,系統一定出現各個OSD看到的cluster map不一致的狀況,這是否會致使問題?答案是:不會。事實上,若是一個client和它要訪問的PG內部的各個OSD看到的cluster map狀態一致,則訪問操做就能夠正確進行。而若是這個client或者PG中的某個OSD和其餘幾方的cluster map不一致,則根據Ceph的機制設計,這幾方將首先同步cluster map至最新狀態,並進行必要的數據re-balancing操做,而後便可繼續正常訪問。

經過上述介紹,咱們能夠簡要了解Ceph到底是若是基於cluster map機制,並由monitor、OSD和client共同配合完成集羣狀態的維護與數據訪問的。特別的,基於這個機制,事實上能夠天然而然的完成自動化的數據備份、數據re-balancing、故障探測和故障恢復,並不須要複雜的特殊設計。這一點確實讓人印象深入。

相關文章
相關標籤/搜索