天天看點

帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)

3.1.4    RBD Cache

1.  RBDCache介紹

RBDCache在 Ceph 的塊存儲接口中,用來緩存用戶端的資料,它主要提供讀緩存和寫合并功能,最終提高I/O 讀寫的性能。需要注意的是,Ceph 既支援以核心子產品方式動态地為Linux主機提供塊裝置(KRBD),也支援以QEMUBlockDriver的形式為VM提供虛拟塊裝置(QEMU+librbd),本章節描述的是第二種形式。

RBDCache目前在 librbd中主要以 ObjectBufferExtent 為基本機關進行緩存,一個RBD塊裝置在 librbd層以固定大小分為若幹個對象,而讀寫請求通常會有不同的 I/O尺寸,每個請求的 Buffer大小都會以 Object為機關放到一個或多個 ObjectBufferExtent中。

目前 RBDCache 隻支援以記憶體形式存在,是以需要提供一些政策來不斷回寫到Ceph叢集來實作資料持久化,以防止用戶端掉電引起的 RBDCache緩存資料丢失。

在 librbd中有若幹選項來控制RBDCache 的大小和回寫政策。rbd_cache_size:控制 librbd 能使用的最大緩存大小。rbd_cache_max_dirty:控制緩存中允許髒資料的最大值。

rbd_cache_target_dirty :控制 RBDCache 開始執行回寫過程的髒資料水位線,其數值不能超過 rbd_cache_max_dirty大小。

rbd_cache_max_dirty_age   :控制緩存中單個髒資料最大的存在時間,避免髒資料長時間存在。

除了在空間次元和時間次元控制緩存回寫邏輯之外,librbd 也提供了flush 接口,該接口同樣能夠觸發緩存中的髒資料回寫操作。

因為 RBDCache 是以記憶體的形式存在,是以會出現下面的問題:

(1)記憶體作為緩存,緩存空間不能太大;

(2)Kernelcrash 或者主機掉電,很容易造成資料丢失的風險。

為了解決上面的問題,Ceph引入一種非易失存儲媒體代替記憶體,持久化 RBDCache資料。為了适配這種新的存儲媒體,RWL(ReplicatedWriteLog)技術被開發出來,下面對RWL進行介紹。

2.  RWL使用的 PMDK技術

PMDK, 全稱 PersistentMemoryDevelopmentKit,它是一套具有 DAX(DirectAccess)通路特性的開發工具庫。

NVM(Non-VolatileMemory)存儲能夠使具備DAX功能的檔案系統直接暴露在使用者空間,使用者态程式可以使用标準的檔案系統 API來操作 NVM,同樣也可以使用 mmap将其直接映射到使用者空間。無論使用哪種方式,對 NVM的操作都會直接轉換為對NVM的登入(load)和存儲(store),中間沒有頁面緩存(pagecache)(這也是支援DAX模式的檔案系統和普通檔案系統之間的主要差別)。

在使用檔案系統時,資料的完整性一般都由檔案系統來保證,而   NVM   作為一種非易失性存儲,在使用 mmap 方式來讀寫時,如何保證資料的完整性和一緻性就顯得尤為重要。通常有很多種方式可以做到這一點(後文将展開讨論),比如靠上層應用程式自己的政策來保證,也可以使用第三方庫來保證,PMDK(更具體點來說是 PMDK中的 libpmemobj)就是用來完成這項工作的。在圖 3-9中箭頭的位置都是 libpmemobj庫的位置。

帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)

圖 3-9PMOK架構和應用

3.  RWL架構

圖 3-10所示的是 RWL的架構,從圖中可以看出,計算節點提供 persistmemory,來存儲緩存資料,在存儲節點也提供 persistmemory,作為計算節點緩存資料的備援備份。

RWL 儲存緩存資料的過程如下。

(1)  用戶端對 Image發送寫請求;

(2) 每個Image在本地的 persistmemory中,都會有一塊獨立的空間來存儲緩存資料;

(3) 把用戶端的資料和一些控制資訊封裝成一個結構體,這裡稱作資料日志,存儲在persistmemory中,每寫一些資料日志(比如30條資料日志),會增加一條同步日志;

帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)

圖 3-10RwL架構

(4)  與此同時,通過 RDMA技術,把封裝的結構體在遠端的 persistmemory中再備份,達到容災的目的。

因為用戶端每次的寫入資料都優先存儲在 persistmemory中,而沒有通過 librbd寫入 Ceph 存儲叢集中,是以這些資料會标記為髒資料;RWL會根據一些條件,把這些髒資料寫入 Ceph叢集,這樣 persistmemory就會有空間存儲新的用戶端資料。

表3-1所示是開啟RWL和沒有開啟RWL的測試資料。通過資料可以看出,開啟 RWL後,IOPS得到了大幅提升。

表3-1    100GB卷空間測試對比

cache iosize iodepth

rwl

size

rbd_cache_

disable_patch

VM

cache attr

IOPS BW Avg-lat
enable 16KB 1 1G YES writeback 4960 81.3Mbit/s 3041.43µs
disable N/A none 323 5292Kbit/s 6306.72µs

4.  RWL的優點和局限性

RWL 可以提高資料的讀寫性能,滿足使用者對高性能的要求,即使伺服器掉電,資料也不會丢失,為使用者提供了較高的資料高可用性。

RWL必須使用 persistmemory 儲存設備,普通的儲存設備無法滿足其使用要求,目前這種 persistmemory 裝置仍然相當昂貴,使用者需要綜合考慮該方案的成本效益。

3.1.5     QoS

QoS(QualityofService)是一種控制機制,它提供了針對不同使用者或不同資料流采用不同優先級的 I/O 讀寫能力服務政策,可根據程式的要求,保證資料流的性能達到一定的水準。

在存儲領域,QoS 主要表現為對存儲通路的IOPS或者帶寬(Bandwith)控制,一個優秀的 QoS算法要求能夠滿足每個Client的最低請求處理需求,同時也保證 I/O服務能力不超過預設值限制,且能夠根據優先級不同,配置設定不同的權重資源,mClock 就是這樣的算法。令牌桶也能夠實作一定的QoS上限能力限制,但因其無法保證 QoS 下限,本小節不做展開介紹。

1.  mClock

mClock是基于時間标簽的 I/O 排程算法,适用于集中式管理的存儲系統。mClock使用Reservation、Limit及 Proportion作為 QoSSpec。Client端提供(r,l,w)參數值,Server端根據這3個參數計算時間标簽(計算公式見式3-1、式3-2、式3-3,式中運算符号含義說明見表3-2),并分為兩個階段處理I/O請求。

(1)  Constraint-Based 階段,處理所有預留時間标簽滿足條件的請求(預留時間标簽值小于或等于目前時間);

(2)  Weight-Based階段,處理上限時間标簽滿足條件的請求,若有多個Client同時滿足條件,則依據權重時間标簽的大小決定處理順序(即權重時間标簽較小的 Client的請求優先被處理)。

帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)
帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)

表3-2 運算符号含義說明

符号 含義

Rr

i

表示Client i 的第r 個請求的預留時間标簽 1
Lr 表示Client i 的第r 個請求的上限時間标簽
Pr 表示Client i 的第r 個請求的權重時間标簽
ri 表示Client i 的預留值
li 表示Client i 的上限值
wi 表示Client i 的權重

mClock 算法的僞代碼如下所示。

RequestArrival (request r,timet,client Ci)begin

if Ci was idle then

minPtag = minimum of all Ptags

foreachactive Cj do

Pj-= minPtag-t

end

R<i, r> = max{R<i, r-1> + 1/r<i>, t}L<i, r> = max{L<i, r-1> + 1/l<i>, t}P<i, r> = max{P<i, r-1> + 1/w<i>, t}ScheduleRequest()

ScheduleRequest ()begin

Let E bethe setof requestswith Rtag <=t

if E not empty then

select IO request withminimum R tagfrom Eelse

Let E' bethe setof requestswith Ltag <= t

if E' not empty then

select IO request with minimum P tag fromE'

/*Assuming request belong to clientc<k>*/Subtract 1/r<k> from R tags of C<k>

mClock-Server動态地工作在 Constraint-Based和 Weight-Based階段,為了減少Client之間的競争,它總是期望請求在Constraint-Based階段被處理。當某個 Client的請求在 Weight-Based 階段被處理,該 Client子隊列剩餘請求的預留時間标簽都要減去 1/r, 以保留該Client預留時間标簽的正确性,調整過程如圖3-11所示,若不對剩餘請求的預留時間标簽進行處理,則第三個請求的初始的預留時間标簽t+3/r更難以滿足 Constraint-Based階段被處理的條件,進而使得該Client的I/O請求一直在Weight-Based階段被處理,無法滿足預期的預留效果。

1Clienti第一個到達的請求的時間設為t(t= currenttime)。

帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)

圖 3-11請求在 weght-Based 階段被處理時預留時間标簽調整過程

mClock存在一定的局限性, 即 mClock的應用場景為多個 Client向同一個 Server端發送請求,但是對于分布式存儲系統,需要多個 Client端向多個 Server端發送請求,mClock算法在此類場景不再适用。

2.  dmClock

DistributedmClock(即dmClock)算法對mClock算法進行了改進,dmClock是mClock的分布式版本,需要在每個 Server上都運作一個mClock服務端,将 QoSSpec分到不同的Server共同完成。

dmClock算法與 mClock 算法之間的差異如下。

(1)  分布式系統中的各個 Server向 Client 傳回的響應結果中包含其請求在哪個階段被處理;

(2)  Client會統計各個 Server所完成請求的個數,在向某一 Server發送請求時,請求中會攜帶自上次給該 Server 下發的請求之後,其他 Server完成的請求個數之和,分别用ρ和δ表示兩個階段的增量;

(3) Server在計算請求時間标簽時,不再根據步長(1/r,1/w,1/l)等長遞增,而使用ρ和δ調整因子,使得總的處理速度滿足QoS限制條件。

請求的時間标簽計算公式見式3-4、式3-5、式3-6。

帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)

如前面所講,dmClock也是由 Client和 Server兩部分組成,其中 Client的主要功能

是統計每個 Server分别在兩個階段完成請求的個數,以此來調整 Server處理請求的速率。Server部分是算法的核心,每個Server 中的dmClock-Server 隊列由一個兩級映射隊列組成,如圖 3-12所示,一級是由各個 Client組成的 Clientqueue,另一級是 Client對應的請求子隊列 requestqueue。

帶你讀《存儲漫談Ceph原理與實踐》第三章接入層3.1塊存儲 RBD(四)

圖 3-12dmCock-Server隊列

繼續閱讀