李航:分佈式存儲 Ceph 介紹及原理架構分享

出品 | 滴滴技術node

做者 | 李航redis


前言:本文主要從架構簡介使用場景,以及內部IO流程、心跳機制、通訊框架、CRUSH算法、QOS等多個方面逐漸介紹分佈式存儲系統Ceph的特性。但願對你有所幫助。
算法

閱讀索引docker


1. Ceph 架構簡介及使用場景介紹swift

         1.1 Ceph 簡介後端

         1.2 Ceph 特色設計模式

         1.3 Ceph 架構緩存

         1.4 Ceph 核心組件及概念介紹安全

         1.5 三種存儲類型-塊存儲bash

         1.6 三種存儲類型-文件存儲

         1.7 三種存儲類型-對象存儲

2. Ceph IO 流程及數據分佈

        2.1 正常IO 流程圖

       2.2 新主IO 流程圖

      2.3 Ceph IO 算法流程

      2.4 Ceph IO 僞代碼流程

      2.5 Ceph RBD IO 流程

      2.6 Ceph RBD IO 框架圖

      2.7 Ceph Pool 和 PG 分佈狀況

      2.8 Ceph 數據擴容 PG 分佈

3. Ceph 心跳機制

     3.1 心跳介紹

     3.2 Ceph 心跳檢測

     3.3 Ceph OSD 之間相互心跳檢測

     3.4 Ceph OSD 與 Mon 心跳檢測

     3.5 Ceph 心跳檢測總結

4. Ceph 通訊框架

    4.1 Ceph 通訊框架種類介紹

    4.2 Ceph 通訊框架設計模式

    4.3 Ceph 通訊框架流程圖

    4.4 Ceph 通訊框架類圖

    4.5 Ceph 通訊數據格式

5. Ceph CRUSH 算法

    5.1 數據分佈算法挑戰

    5.2 Ceph CRUSH 算法說明

    5.3 Ceph CRUSH 算法原理

           5.3.1 層級化的 Cluster Map

           5.3.2 數據分佈策略 Placement Rules

           5.3.3 Bucket 隨機算法類型

   5.4 Ceph CRUSH 算法案例

6. 定製化 Ceph RBD QOS

   6.1 QOS 介紹

   6.2 Ceph IO 操做類型

   6.3 Ceph 官方 QOS 原理

   6.4 定製化 QOS 原理

          6.4.1 令牌桶算法介紹

          6.4.2 RBD 令牌桶算法流程

          6.4.3 RBD 令牌桶算法框架圖

▍1. Ceph 架構簡介及使用場景介紹

▍1.1 Ceph 簡介

Ceph 是一個統一的分佈式存儲系統,設計初衷是提供較好的性能、可靠性和可擴展性。

Ceph 項目最先起源於 Sage 就讀博士期間的工做(最先的成果於2004年發表),並隨後貢獻給開源社區。在通過了數年的發展以後,目前已獲得衆多雲計算廠商的支持並被普遍應用。

RedHat 及 OpenStack 均可與 Ceph 整合以支持虛擬機鏡像的後端存儲。

▍1.2 Ceph 特色

高性能

a. 摒棄了傳統的集中式存儲元數據尋址的方案,採用 CRUSH 算法,數據分佈均衡,並行度高。

b. 考慮了容災域的隔離,可以實現各種負載的副本放置規則,例如跨機房、機架感知等。

c. 可以支持上千個存儲節點的規模,支持 TB 到 PB 級的數據。

高可用性

a. 副本數能夠靈活控制。

b. 支持故障域分隔,數據強一致性。

c. 多種故障場景自動進行修復自愈。

d. 沒有單點故障,自動管理。

高可擴展性

a. 去中心化。

b. 擴展靈活。

c. 隨着節點增長而線性增加。

特性豐富

a. 支持三種存儲接口:塊存儲、文件存儲、對象存儲。

b. 支持自定義接口,支持多種語言驅動。

▍1.3 Ceph 架構

支持三種接口:

Object:有原生的 API,並且也兼容 Swift 和 S3 的 API。

Block:支持精簡配置、快照、克隆。

File:Posix 接口,支持快照。


▍1.4 Ceph 核心組件及概念介紹

Monitor

一個 Ceph 集羣須要多個 Monitor 組成的小集羣,它們經過 Paxos 同步數據,用來保存 OSD 的元數據。

OSD

OSD 全稱 Object Storage Device,也就是負責響應客戶端請求返回具體數據的進程。一個 Ceph 集羣通常都有不少個 OSD。

MDS

MDS 全稱 Ceph Metadata Server,是 CephFS 服務依賴的元數據服務。

Object

Ceph 最底層的存儲單元是 Object 對象,每一個 Object 包含元數據和原始數據。

PG

PG 全稱 Placement Grouops,是一個邏輯的概念,一個 PG 包含多個 OSD。引入 PG 這一層實際上是爲了更好的分配數據和定位數據。

RADOS

RADOS 全稱 Reliable Autonomic Distributed Object Store,是 Ceph 集羣的精華,用戶實現數據分配、Failover 等集羣操做。

Libradio

Librados 是 Rados 提供庫,由於 RADOS 是協議很難直接訪問,所以上層的 RBD、RGW 和 CephFS 都是經過 librados 訪問的,目前提供 PHP、Ruby、Java、Python、C和C++支持。

CRUSH

CRUSH 是 Ceph 使用的數據分佈算法,相似一致性哈希,讓數據分配到預期的地方。

RBD

RBD 全稱 RADOS block device,是 Ceph 對外提供的塊設備服務。

RGW

RGW 全稱 RADOS gateway,是 Ceph 對外提供的對象存儲服務,接口與 S3 和 Swift 兼容。

CephFS

CephFS 全稱 Ceph File System,是 Ceph 對外提供的文件系統服務。

▍1.5 三種存儲類型-塊存儲


典型設備:

磁盤陣列,硬盤

主要是將裸磁盤空間映射給主機使用的。

優勢:

a. 經過 Raid 與 LVM 等手段,對數據提供了保護。

b. 多塊廉價的硬盤組合起來,提升容量。

c. 多塊磁盤組合出來的邏輯盤,提高讀寫效率。

缺點:

a. 採用 SAN 架構組網時,光纖交換機,造價成本高。

b. 主機之間沒法共享數據。

使用場景:

a. docker 容器、虛擬機磁盤存儲分配。

b. 日誌存儲。

c. 文件存儲。

d. …

▍1.6 三種存儲類型-文件存儲


典型設備:

FTP、NFS 服務器

爲了克服塊存儲文件沒法共享的問題,因此有了文件存儲。

在服務器上架設 FTP 與 NFS 服務,就是文件存儲。

優勢:

a. 造價低,隨便一臺機器就能夠了。

b. 方便文件共享。

缺點:

a. 讀寫速率低。

b. 傳輸速率慢。

使用場景:

a. 日誌存儲。

b. 有目錄結構的文件存儲。

c. …

▍1.7 三種存儲類型-對象存儲


典型設備:

內置大容量硬盤的分佈式服務器(swift, s3)

多臺服務器內置大容量硬盤,安裝上對象存儲管理軟件,對外提供讀寫訪問功能。

優勢:

a. 具有塊存儲的讀寫高速。

b. 具有文件存儲的共享等特性。

使用場景:

(適合更新變更較少的數據)

a. 圖片存儲。

b. 視頻存儲。

c. …

▍2. Ceph IO 流程


▍2.1 正常 IO 流程圖



步驟:

  • 1. client 建立 cluster handler。

  • 2. client 讀取配置文件。

  • 3. client 鏈接上 monitor,獲取集羣 map 信息。

  • 4. client 讀寫 io 根據 crshmap 算法請求對應的主 osd 數據節點。

  • 5. 主 osd 數據節點同時寫入另外兩個副本節點數據。

  • 6. 等待主節點以及另外兩個副本節點寫完數據狀態。


7. 主節點及副本節點寫入狀態都成功後,返回給 client,io 寫入完成。


▍2.2 新主 IO 流程圖

說明:

若是新加入的 OSD1 取代了原有的 OSD4 成爲 Primary OSD, 因爲 OSD1 上未建立 PG , 不存在數據,那麼 PG 上的 I/O 沒法進行,怎樣工做的呢?


步驟:

  • 1. client 鏈接 monitor 獲取集羣 map 信息。

  • 2. 同時新主 osd1 因爲沒有 pg 數據會主動上報 monitor 告知讓 osd2 臨時接替爲主。

  • 3. 臨時主 osd2 會把數據全量同步給新主 osd1。

  • 4. client IO 讀寫直接鏈接臨時主 osd2 進行讀寫。

  • 5. osd2 收到讀寫 io,同時寫入另外兩副本節點。

  • 6. 等待 osd2 以及另外兩副本寫入成功。

  • 7. osd2 三份數據都寫入成功返回給 client, 此時 client io 讀寫完畢。

  • 8. 若是 osd1 數據同步完畢,臨時主 osd2 會交出主角色。

  • 9. osd1 成爲主節點,osd2 變成副本。

▍2.3 Ceph IO 算法流程


1. File用戶須要讀寫的文件。File->Object 映射:

a. ino (File 的元數據,File 的惟一id)。

b. ono(File 切分產生的某個 object 的序號,默認以 4M 切分一個塊大小)。

c. oid(object id: ino + ono)。

2. Object 是 RADOS 須要的對象。Ceph 指定一個靜態hash函數計算 oid 的值,將 oid 映射成一個近似均勻分佈的僞隨機值,而後和 mask 按位相與,獲得 pgid。Object->PG 映射:

a) hash(oid) & mask-> pgid 。

b) mask = PG 總數 m(m 爲2的整數冪)-1 。

3. PG(Placement Group),用途是對 object 的存儲進行組織和位置映射, (相似於 redis cluster 裏面的 slot 的概念) 一個 PG 裏面會有不少 object。採用 CRUSH 算法,將 pgid 代入其中,而後獲得一組 OSD。PG->OSD 映射:

a) CRUSH(pgid)->(osd1,osd2,osd3) 。

▍2.4 Ceph IO 僞代碼流程

1 locator = object_name
2
3 obj_hash =  hash(locator)
4
5 pg = obj_hash % num_pg
6
7 osds_for_pg = crush(pg)    # returns a list of osds
8
9 primary = osds_for_pg[0]
10
11 replicas = osds_for_pg[1:]複製代碼

 ▍2.5 Ceph RBD IO 流程

數據組織:


步驟:

  • 1. 客戶端建立一個 pool,須要爲這個 pool 指定 pg 的數量。

  • 2. 建立 pool/image rbd 設備進行掛載。

  • 3. 用戶寫入的數據進行切塊,每一個塊的大小默認爲4M,而且每一個塊都有一個名字,名字就是 object+序號。

  • 4. 將每一個 object 經過 pg 進行副本位置的分配。

  • 5. pg 根據 cursh 算法會尋找3個 osd,把這個 object 分別保存在這三個 osd 上。

  • 6. osd 上實際是把底層的 disk 進行了格式化操做,通常部署工具會將它格式化爲 xfs 文件系統。

  • 7. object 的存儲就變成了存儲一個文 rbd0.object1.file。

▍2.6 Ceph RBD IO 框架圖


客戶端寫數據 osd 過程:

  • 1. 採用的是 librbd 的形式,使用 librbd 建立一個塊設備,向這個塊設備中寫入數據。

  • 2. 在客戶端本地同過調用 librados 接口,而後通過 pool,rbd,object、pg 進行層層映射,在 PG 這一層中,能夠知道數據保存在哪3個 OSD 上,這3個 OSD 分爲主從的關係。

  • 3. 客戶端與 primay OSD 創建 SOCKET 通訊,將要寫入的數據傳給 primary OSD,由primary OSD 再將數據發送給其餘 replica OSD 數據節點。

▍2.7 Ceph Pool 和 PG 分佈狀況


說明:

  • a. pool 是 ceph 存儲數據時的邏輯分區,它起到 namespace 的做用。

  • b. 每一個 pool 包含必定數量(可配置)的 PG。

  • c. PG 裏的對象被映射到不一樣的 OSD 上。

  • d. pool 是分佈到整個集羣的。

  • e. pool 能夠作故障隔離域,根據不一樣的用戶場景不一進行隔離。

▍2.8 Ceph 數據擴容 PG 分佈

場景數據遷移流程:

a. 現狀3個 OSD, 4個 PG

b. 擴容到4個 OSD, 4個 PG

現狀:


擴容後:


說明:

每一個 OSD 上分佈不少 PG, 而且每一個 PG 會自動散落在不一樣的 OSD 上。若是擴容那麼相應的 PG 會進行遷移到新的 OSD 上,保證 PG 數量的均衡。

▍3. Ceph 心跳機制

▍3.1 心跳介紹

心跳是用於節點間檢測對方是否故障的,以便及時發現故障節點進入相應的故障處理流程。

問題:

a. 故障檢測時間和心跳報文帶來的負載之間作權衡。

b. 心跳頻率過高則過多的心跳報文會影響系統性能。

c. 心跳頻率太低則會延長髮現故障節點的時間,從而影響系統的可用性。

故障檢測策略應該可以作到:

及時:節點發生異常如宕機或網絡中斷時,集羣能夠在可接受的時間範圍內感知。

適當的壓力:包括對節點的壓力,和對網絡的壓力。

容忍網絡抖動:網絡偶爾延遲。

擴散機制:節點存活狀態改變致使的元信息變化須要經過某種機制擴散到整個集羣。

▍3.2 Ceph 心跳檢測


OSD 節點會監聽 public、cluster、front 和 back 四個端口

· public 端口:監聽來自 Monitor 和 Client 的鏈接。

· cluster 端口:監聽來自 OSD Peer 的鏈接。

· front 端口:供客戶端鏈接集羣使用的網卡, 這裏臨時給集羣內部之間進行心跳。

· back 端口:供客集羣內部使用的網卡。集羣內部之間進行心跳。

· hbclient:發送 ping 心跳的 messenger。

▍3.3 Ceph OSD 之間相互心跳檢測


步驟:

a. 同一個 PG 內 OSD 互相心跳,他們互相發送 PING/PONG 信息。

b. 每隔6s檢測一次(實際會在這個基礎上加一個隨機時間來避免峯值)。

c. 20s沒有檢測到心跳回復,加入 failure 隊列。

▍3.4 Ceph OSD與Mon心跳檢測


OSD 報告給 Monitor:

  • a. OSD 有事件發生時(好比故障、PG 變動)。

  • b. 自身啓動5秒內。

  • c. OSD 週期性的上報給 Monito

  • d. OSD 檢查 failure_queue 中的夥伴 OSD 失敗信息。

  • e. 向 Monitor 發送失效報告,並將失敗信息加入 failure_pending 隊列,而後將其從 failure_queue 移除。

  • f. 收到來自 failure_queue 或者 failure_pending 中的 OSD 的心跳時,將其從兩個隊列中移除,並告知 Monitor 取消以前的失效報告。

  • g. 當發生與 Monitor 網絡重連時,會將 failure_pending 中的錯誤報告加回到 failure_queue 中,並再次發送給 Monitor。

  • h. Monitor 統計下線 OSD

  • i. Monitor 收集來自 OSD 的夥伴失效報告。

  • j. 當錯誤報告指向的 OSD 失效超過必定閾值,且有足夠多的 OSD 報告其失效時,將該 OSD 下線。

▍3.5 Ceph 心跳檢測總結

Ceph 經過夥伴 OSD 彙報失效節點和 Monitor 統計來自 OSD 的心跳兩種方式斷定 OSD 節點失效。

及時:

夥伴 OSD 能夠在秒級發現節點失效並彙報 Monitor,並在幾分鐘內由 Monitor 將失效 OSD 下線。

適當的壓力:

因爲有夥伴 OSD 彙報機制,Monitor 與 OSD 之間的心跳統計更像是一種保險措施,所以 OSD 向 Monitor 發送心跳的間隔能夠長達600秒,Monitor 的檢測閾值也能夠長達900秒。Ceph 其實是將故障檢測過程當中中心節點的壓力分散到全部的 OSD 上,以此提升中心節點 Monitor 的可靠性,進而提升整個集羣的可擴展性。

容忍網絡抖動:

Monitor 收到 OSD 對其夥伴 OSD 的彙報後,並無立刻將目標 OSD 下線,而是週期性的等待幾個條件:

1. 目標 OSD 的失效時間大於經過固定量 osd_heartbeat_grace 和歷史網絡條件動態肯定的閾值。

2. 來自不一樣主機的彙報達到 mon_osd_min_down_reporters。

3. 知足前兩個條件前失效彙報沒有被源 OSD 取消。

擴散

做爲中心節點的 Monitor 並無在更新 OSDMap 後嘗試廣播通知全部的 OSD 和 Client,而是惰性的等待 OSD 和 Client 來獲取。以此來減小 Monitor 壓力並簡化交互邏輯。

▍4. Ceph 通訊框架

▍4.1 Ceph 通訊框架種類介紹

網絡通訊框架三種不一樣的實現方式:

Simple 線程模式

特色:每個網絡連接,都會建立兩個線程,一個用於接收,一個用於發送。

缺點:大量的連接會產生大量的線程,會消耗 CPU 資源,影響性能。

Async 事件的I/O多路複用模式

特色:這種是目前網絡通訊中普遍採用的方式。k版默認已經使用 Asnyc 了。

XIO 方式使用了開源的網絡通訊庫 accelio 來實現

特色:這種方式須要依賴第三方的庫 accelio 穩定性,目前處於試驗階段。

▍4.2 Ceph 通訊框架設計模式

設計模式(Subscribe/Publish):

訂閱發佈模式又名觀察者模式,它意圖是「定義對象間的一種一對多的依賴關係,

當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新」。

▍4.3 Ceph 通訊框架流程圖


步驟:

  • a. Accepter 監聽 peer 的請求, 調用 SimpleMessenger::add_accept_pipe() 建立新的 Pipe 到 SimpleMessenger::pipes 來處理該請求。

  • b. Pipe 用於消息的讀取和發送。該類主要有兩個組件,Pipe::Reader,Pipe::Writer 用來處理消息讀取和發送。

  • c. Messenger 做爲消息的發佈者, 各個 Dispatcher 子類做爲消息的訂閱者, Messenger 收到消息以後,經過 Pipe 讀取消息,而後轉給 Dispatcher 處理。

  • d. Dispatcher 是訂閱者的基類,具體的訂閱後端繼承該類,初始化的時候經過 Messenger::add_dispatcher_tail/head 註冊到 Messenger::dispatchers. 收到消息。

  • e. DispatchQueue 該類用來緩存收到的消息, 而後喚醒 DispatchQueue::dispatch_thread 線程找到後端的 Dispatch 處理消息。


▍4.4 Ceph 通訊框架類圖


▍4.5 Ceph 通訊數據格式

通訊協議格式須要雙方約定數據格式。

消息的內容主要分爲三部分:

· header //消息頭,類型消息的信封

· user data //須要發送的實際數據

        o payload //操做保存元數據

        o middle //預留字段

        o data //讀寫數據

        o footer //消息的結束標記

1   class Message : public RefCountedObject {
2   protected:
3    ceph_msg_header  header;      // 消息頭
4    ceph_msg_footer  footer;      // 消息尾
5    bufferlist       payload;  // "front" unaligned blob
6    bufferlist       middle;   // "middle" unaligned blob
7    bufferlist       data;     // data payload (page-alignment will be preserved where possible)
8 
9  /* recv_stamp is set when the Messenger starts reading the
10  * Message off the wire */
11 utime_t recv_stamp;       //開始接收數據的時間戳
12  /* dispatch_stamp is set when the Messenger starts calling dispatch() on
13    * its endpoints */
14   utime_t dispatch_stamp;   //dispatch 的時間戳
15  /* throttle_stamp is the point at which we got throttle */
16  utime_t throttle_stamp;   //獲取throttle 的slot的時間戳
17   /* time at which message was fully read */
18   utime_t recv_complete_stamp;  //接收完成的時間戳
19
20  ConnectionRef connection;     //網絡鏈接
21 
22  uint32_t magic = 0;           //消息的魔術字
23 
24  bi::list_member_hook<> dispatch_q;  //boost::intrusive 成員字段
25  };
26
27 struct ceph_msg_header {
28     __le64 seq;       // 當前session內 消息的惟一 序號
29     __le64 tid;       // 消息的全局惟一的 id
30     __le16 type;      // 消息類型
31     __le16 priority;  // 優先級
32     __le16 version;   // 版本號 
33
34     __le32 front_len; // payload 的長度
35     __le32 middle_len;// middle 的長度
36     __le32 data_len;  // data 的 長度
37     __le16 data_off;  // 對象的數據偏移量
38
39
40    struct ceph_entity_name src; //消息源
41
42    /* oldest code we think can decode this.  unknown if zero. */ 
43     __le16 compat_version;
44     __le16 reserved;
45     __le32 crc;       /* header crc32c */
46   } __attribute__ ((packed));
47
48   struct ceph_msg_footer {
49    __le32 front_crc, middle_crc, data_crc; //crc校驗碼
50    __le64  sig; //消息的64位signature
51    __u8 flags; //結束標誌
52  } __attribute__ ((packed));複製代碼

▍5. Ceph CRUSH 算法

▍5.1 數據分佈算法挑戰

數據分佈和負載均衡:

1. 數據分佈均衡,使數據能均勻的分佈到各個節點上。

2. 負載均衡,使數據訪問讀寫操做的負載在各個節點和磁盤的負載均衡。

靈活應對集羣伸縮:

1. 系統能夠方便的增長或者刪除節點設備,而且對節點失效進行處理。

2. 增長或者刪除節點設備後,能自動實現數據的均衡,而且儘量少的遷移數據。

支持大規模集羣:

1. 要求數據分佈算法維護的元數據相對較小,而且計算量不能太大。隨着集羣規模的增 加,數據分佈算法開銷相對比較小。

▍5.2 Ceph CRUSH 算法說明

CRUSH 算法的全稱爲:Controlled Scalable Decentralized Placement of Replicated Data,可控的、可擴展的、分佈式的副本數據放置算法。

PG到OSD 的映射的過程算法叫作 CRUSH 算法。(一個 Object 須要保存三個副本,也就是須要保存在三個 osd 上)。

CRUSH 算法是一個僞隨機的過程,他能夠從全部的 OSD 中,隨機性選擇一個 OSD 集合,可是同一個 PG 每次隨機選擇的結果是不變的,也就是映射的 OSD 集合是固定的。

▍5.3 Ceph CRUSH 算法原理

CRUSH 算法因子:

層次化的 Cluster Map

反映了存儲系統層級的物理拓撲結構。定義了 OSD 集羣具備層級關係的靜態拓撲結構。OSD 層級使得 CRUSH 算法在選擇 OSD 時實現了機架感知能力,也就是經過規則定義, 使得副本能夠分佈在不一樣的機 架、不一樣的機房中、提供數據的安全性 。

Placement Rules

決定了一個 PG 的對象副本如何選擇的規則,經過這些能夠本身設定規則,用戶能夠自定義設置副本在集羣中的分佈。

● 5.3.1 層級化的 Cluster Map


CRUSH Map 是一個樹形結構,OSDMap 更多記錄的是 OSDMap 的屬性(epoch/fsid/pool 信息以及 osd 的 ip 等等)。

葉子節點是 device(也就是 osd),其餘的節點稱爲 bucket 節點,這些 bucket 都是虛構的節點,能夠根據物理結構進行抽象,固然樹形結構只有一個最終的根節點稱之爲 root 節點,中間虛擬的 bucket 節點能夠是數據中心抽象、機房抽象、機架抽象、主機抽象等。

● 5.3.2 數據分佈策略 Placement Rules

數據分佈策略 Placement Rules 主要有特色:

1. 從 CRUSH Map 中的哪一個節點開始查找

2. 使用那個節點做爲故障隔離域

3. 定位副本的搜索模式(廣度優先 or 深度優先)

1 rule replicated_ruleset  #規則集的命名,建立pool時能夠指定rule集
2 
3 {
4
5    ruleset 0                #rules集的編號,順序編便可 
6
7    type replicated          #定義pool類型爲replicated(還有erasure模式) 
8
9     min_size 1                #pool中最小指定的副本數量不能小1
10 
11    max_size 10               #pool中最大指定的副本數量不能大於10
12 
13    step take default         #查找bucket入口點,通常是root類型的bucket 
14 
15    step chooseleaf  firstn  0  type  host #選擇一個host,並遞歸選擇葉子節點osd 
16
17    step emit        #結束
18
19 }   複製代碼


● 5.3.3 Bucket 隨機算法類型

通常的 buckets:適合全部子節點權重相同,並且不多添加刪除 item。

list buckets:適用於集羣擴展類型。增長 item,產生最優的數據移動,查找 item,時間複雜度 O(n)。

tree buckets:查找負責度是 O (log n), 添加刪除葉子節點時,其餘節點 node_id 不變。

straw buckets:容許全部項經過相似抽籤的方式來與其餘項公平「競爭」。定位副本時,bucket 中的每一項都對應一個隨機長度的 straw,且擁有最長長度的 straw 會得到勝利(被選中),添加或者從新計算,子樹之間的數據移動提供最優的解決方案。

▍5.4 Ceph CRUSH 算法案例

說明:

集羣中有部分 sas 和 ssd 磁盤,如今有個業務線性能及可用性優先級高於其餘業務線,可否讓這個高優業務線的數據都存放在 ssd 磁盤上。

普通用戶:


高優用戶:


配置規則:


▍6. 定製化 Ceph RBD QOS

▍6.1 QOS 介紹

QoS (Quality of Service,服務質量)起源於網絡技術,它用來解決網絡延遲和阻塞等問題,可以爲指定的網絡通訊提供更好的服務能力。

問題:

咱們總的 Ceph 集羣的 IO 能力是有限的,好比帶寬,IOPS。如何避免用戶爭搶資源,如何保證集羣全部用戶資源的高可用性,以及如何保證高優用戶資源的可用性。因此咱們須要把有限的 IO 能力合理分配。

▍6.2 Ceph I

O 操做類型

ClientOp:來自客戶端的讀寫 I/O 請求。

SubOp:osd 之間的 I/O 請求。主要包括由客戶端 I/O 產生的副本間數據讀寫請求,以及由數據同步、數據掃描、負載均衡等引發的 I/O 請求。

SnapTrim:快照數據刪除。從客戶端發送快照刪除命令後,刪除相關元數據便直接返回,以後由後臺線程刪除真實的快照數據。經過控制 snaptrim 的速率間接控制刪除速率。

Scrub:用於發現對象的靜默數據錯誤,掃描元數據的 Scrub 和對象總體掃描的 deep Scrub。

Recovery:數據恢復和遷移。集羣擴/縮容、osd 失效/重新加入等過程。

▍6.3 Ceph 官方 QOS 原理


mClock 是一種基於時間標籤的 I/O 調度算法,最早被 Vmware 提出來的用於集中式管理的存儲系統。(目前官方 QOS 模塊屬於半成品)。

基本思想:

· reservation 預留,表示客戶端得到的最低 I/O 資源。

· weight 權重,表示客戶端所佔共享 I/O 資源的比重。

· limit 上限,表示客戶端可得到的最高 I/O 資源。

▍6.4 定製化 QOS 原理

● 6.4.1 令牌桶算法介紹


基於令牌桶算法(TokenBucket)實現了一套簡單有效的 qos 功能,知足了雲平臺用戶的核心需求。

基本思想:

  • 按特定的速率向令牌桶投放令牌。

  • 根據預設的匹配規則先對報文進行分類,不符合匹配規則的報文不須要通過令牌桶的處理,直接發送。

  • 符合匹配規則的報文,則須要令牌桶進行處理。當桶中有足夠的令牌則報文能夠被繼續發送下去,同時令牌桶中的令牌量按報文的長度作相應的減小。

  • 當令牌桶中的令牌不足時,報文將不能被髮送,只有等到桶中生成了新的令牌,報文才能夠發送。這就能夠限制報文的流量只能是小於等於令牌生成的速度,達到限制流量的目的。

● 6.4.2 RBD 令牌桶算法流程


步驟:

  • 用戶發起請求異步IO到達Image中。

  • 請求到達ImageRequestWQ隊列中。

  • 在ImageRequestWQ出隊列的時候加入令牌桶算法TokenBucket。

  • 經過令牌桶算法進行限速,而後發送給ImageRequest進行處理。

● 6.4.3 RBD令牌桶算法框架圖

現有框架圖:


令牌圖算法框架圖:


▍END


相關文章
相關標籤/搜索