CrushMap介紹

1. 介紹


CRUSH 算法經過計算數據存儲位置來肯定如何存儲和檢索。 CRUSH 受權 Ceph 客戶端直接鏈接 OSD ,而非經過一箇中央服務器或代理。數據存儲、檢索算法的使用,使 Ceph 避免了單點故障、性能瓶頸、和伸縮的物理限制。node

CRUSH 須要一張集羣的 Map,且使用 CRUSH Map 把數據僞隨機地、儘可能平均地分佈到整個集羣的 OSD 裏。CRUSH Map 包含 OSD 列表、把設備匯聚爲物理位置的「桶」列表、和指示 CRUSH 如何複製存儲池裏的數據的規則列表。算法

徹底手動管理 CRUSH Map 也是可能的,在配置文件中設定:服務器

osd crush update on start = falseide

2. 編輯 CRUSH Map

要編輯現有的 CRUSH Map:性能

  1. 獲取 CRUSH Map;spa

  1. 反編譯 CRUSH 圖;代理

  1. 至少編輯一個設備、桶、規則;orm

  1. 重編譯 CRUSH Map;server

  1. 注入 CRUSH Map。對象

要激活 CRUSH Map 裏某存儲池的規則,找到通用規則集編號,而後把它指定到那個規則集。

2.1 獲取 CRUSH Map

要獲取集羣的 CRUSH Map,執行命令:

ceph osd getcrushmap -o {compiled-crushmap-filename}

Ceph 將把 CRUSH 輸出( -o )到你指定的文件,因爲 CRUSH Map 是已編譯的,因此編輯前必須先反編譯。

2.2 反編譯 CRUSH Map

要反編譯 CRUSH Map,執行命令:

crushtool -d {compiled-crushmap-filename} -o {decompiled-crushmap-filename}

Ceph 將反編譯( -d )二進制 CRUSH Map,且輸出( -o )到你指定的文件。

2.3 編譯 CRUSH Map

要編譯 CRUSH Map,執行命令:

crushtool -c {decompiled-crush-map-filename} -o {compiled-crush-map-filename}

Ceph 將把已編譯的 CRUSH Map 保存到你指定的文件。

2.4 注入 CRUSH Map

要把 CRUSH Map 應用到集羣,執行命令:

ceph osd setcrushmap -i  {compiled-crushmap-filename}

Ceph 將把你指定的已編譯 CRUSH Map 注入到集羣。

3. CRUSH Map 參數

CRUSH Map 主要有 4 個段落。

  1. 設備: 由任意對象存儲設備組成,即對應一個 ceph-osd進程的存儲器。 Ceph 配置文件裏的每一個 OSD 都應該有一個設備。

  1. 桶類型: 定義了 CRUSH 分級結構裏要用的桶類型( types ),桶由逐級匯聚的存儲位置(如行、機櫃、機箱、主機等等)及其權重組成。

  1. 桶實例: 定義了桶類型後,還必須聲明主機的桶類型、以及規劃的其它故障域。

  1. 規則: 由選擇桶的方法組成。

3.1 CRUSH Map 之設備

爲把 PG 映射到 OSD , CRUSH Map 須要 OSD 列表(即配置文件所定義的 OSD 守護進程名稱),因此它們首先出如今 CRUSH Map 裏。要在 CRUSH Map 裏聲明一個設備,在設備列表後面新建一行,輸入 device 、以後是惟一的數字 ID 、以後是相應的 ceph-osd 守護進程實例名字。

# devices

device {num} {osd.name}

例如:

# devices

device 0 osd.0

device 1 osd.1

device 2 osd.2

device 3 osd.3

3.2 CRUSH Map 之桶類型

CRUSH Map 裏的第二個列表定義了 bucket (桶)類型,桶簡化了節點和葉子層次。節點(或非葉子)桶在分級結構裏通常表示物理位置,節點匯聚了其它節點或葉子,葉桶表示 ceph-osd 守護進程及其對應的存儲媒體。

要往 CRUSH Map 中增長一種 bucket 類型,在現有桶類型列表下方新增一行,輸入 type 、以後是唯一數字 ID 和一個桶名。按慣例,會有一個葉子桶爲 type 0 ,然而你能夠指定任何名字(如 osd 、 disk 、 drive 、 storage 等等):

# types

type {num} {bucket-name}

例如:

# types

type 0 osd

type 1 host

type 2 chassis

type 3 rack

type 4 row

type 5 pdu

type 6 pod

type 7 room

type 8 datacenter

type 9 region

type 10 root

3.3 CRUSH Map 之桶層次

CRUSH 算法根據各設備的權重、大體統一的機率把數據對象分佈到存儲設備中。 CRUSH 根據你定義的集羣運行圖分佈對象及其副本, CRUSH Map 表達了可用存儲設備以及包含它們的邏輯單元。

要把 PG 映射到跨故障域的 OSD ,一個 CRUSH Map 需定義一系列分級桶類型(即現有 CRUSH Map 的 # type 下)。建立桶分級結構的目的是按故障域隔離葉子節點,像主機、機箱、機櫃、電力分配單元、機羣、行、房間、和數據中心。除了表示葉子節點的 OSD ,其它分級結構都是任意的,你能夠按需定義。

聲明一個桶實例時,你必須指定其類型、唯一名稱(字符串)、唯一負整數 ID (可選)、指定和各條目總容量/能力相關的權重、指定桶算法(一般是 straw )、和哈希(一般爲 0 ,表示哈希算法 rjenkins1 )。一個桶能夠包含一到多個條目,這些條目能夠由節點桶或葉子組成,它們能夠有個權重用來反映條目的相對權重。

你能夠按下列語法聲明一個節點桶:

[bucket-type] [bucket-name] {

           id [a unique negative numeric ID]

           weight [the relative capacity/capability of the item(s)]

           alg [the bucket type: uniform | list | tree | straw ]

           hash [the hash type: 0 by default]

           item [item-name] weight [weight]

   }

例如,咱們能夠定義兩個主機桶和一個機櫃桶,機櫃桶包含兩個主機桶, OSD 被聲明爲主機桶內的條目:

host node1 {

           id -1

           alg straw

           hash 0

           item osd.0 weight 1.00

           item osd.1 weight 1.00

   }


   host node2 {

           id -2

           alg straw

           hash 0

           item osd.2 weight 1.00

           item osd.3 weight 1.00

   }


   rack rack1 {

           id -3

           alg straw

           hash 0

           item node1 weight 2.00

           item node2 weight 2.00

   }

3.4 CRUSHMap 之調整桶的權重

Ceph 用雙精度類型數據表示桶權重。權重和設備容量不一樣,咱們建議用 1.00 做爲 1TB 存儲設備的相對權重,這樣 0.5 的權重大概表明 500GB 、 3.00 大概表明 3TB 。較高級桶的權重是全部葉子桶的權重之和。

一個桶的權重是一維的,你也能夠計算條目權重來反映存儲設備性能。例如,若是你有不少 1TB 的硬盤,其中一些數據傳輸速率相對低、其餘的數據傳輸率相對高,即便它們容量相同,也應該設置不一樣的權重(如給吞吐量較低的硬盤設置權重 0.8 ,較高的設置 1.20 )。

3.5 CRUSH Map 之規則

CRUSH Map 支持「 CRUSH 規則」的概念,用以肯定一個存儲池裏數據的分佈。CRUSH 規則定義了歸置和複製策略、或分佈策略,用它能夠規定 CRUSH 如何放置對象副本。對大型集羣來講,你可能建立不少存儲池,且每一個存儲池都有它本身的 CRUSH 規則集和規則。默認的 CRUSH Map 裏,每一個存儲池有一條規則、一個規則集被分配到每一個默認存儲池。

注意: 大多數狀況下,你都不須要修改默認規則。新建立存儲池的默認規則集是 0 。

規則格式以下:

rule <rulename> {


           ruleset <ruleset>

           type [ replicated | erasure ]

           min_size <min-size>

           max_size <max-size>

           step take <bucket-type>

           step [choose|chooseleaf] [firstn|indep] <N> <bucket-type>

           step emit

   }

參數說明:

ruleset:區分一條規則屬於某個規則集的手段。給存儲池設置規則集後激活。

type:規則類型,目前僅支持 replicated 和 erasure ,默認是 replicated 。

min_size:能夠選擇此規則的存儲池最小副本數。

max_size:能夠選擇此規則的存儲池最大副本數。

step take <bucket-name>:選取起始的桶名,並迭代到樹底。

step choose firstn {num} type {bucket-type}:選取指定類型桶的數量,這個數字一般是存儲池的副本數(即 pool size )。若是 {num} == 0 , 選擇 pool-num-replicas 個桶(全部可用的);若是 {num} > 0 && < pool-num-replicas ,就選擇那麼多的桶;若是 {num} < 0,它意味着選擇 pool-num-replicas - {num} 個桶。

step chooseleaf firstn {num} type {bucket-type}:選擇 {bucket-type} 類型的桶集合,並從各桶的子樹裏選擇一個葉子節點。桶集合的數量一般是存儲池的副本數(即 pool size )。若是 {num} == 0 ,選擇 pool-num-replicas 個桶(全部可用的);若是 {num} > 0 && < pool-num-replicas ,就選擇那麼多的桶;若是 {num} < 0 ,它意味着選擇 pool-num-replicas - {num} 個桶。

step emit:輸出當前值並清空堆棧。一般用於規則末尾,也適用於相同規則應用到不一樣樹的狀況。

4. 主親和性

某個 Ceph 客戶端讀寫數據時,老是鏈接 acting set 裏的主 OSD (如 [2, 3, 4] 中, osd.2 是主的)。有時候某個 OSD 與其它的相比並不適合作主 OSD (好比其硬盤慢、或控制器慢)。最大化硬件利用率時爲防止性能瓶頸(特別是讀操做),你能夠調整 OSD 的主親和性,這樣 CRUSH 就儘可能不把它用做 acting set 裏的主 OSD 了。

ceph osd primary-affinity <osd-id> <weight>

主親和性默認爲 1 (就是說此 OSD 可做爲主 OSD )。此值合法範圍爲 0-1 ,其中 0 意爲此 OSD 不能用做主的, 1 意爲 OSD 可用做主的。此權重 < 1 時, CRUSH 選擇主 OSD 時選中它的可能性就較低。

5. 增長/移動 OSD

要增長或移動在線集羣裏 OSD 所對應的 CRUSH Map 條目,執行 ceph osd crush set 命令。

ceph osd crush set {id-or-name} {weight} {bucket-type}={bucket-name} [{bucket-type}={bucket-name} ...]

6. 調整 OSD 的 CRUSH 權重

要調整在線集羣中某個 OSD 的 CRUSH 權重,執行命令:

ceph osd crush reweight {name} {weight}

7. 刪除 OSD

要從在線集羣裏把某個 OSD 完全踢出 CRUSH Map,或僅踢出某個指定位置的 OSD,執行命令:

ceph osd crush remove {name} {<ancestor>}

8. 增長桶

要在運行集羣的 CRUSH Map 中新建一個桶,用 ceph osd crush add-bucket 命令:

ceph osd crush add-bucket {bucket-name} {bucket-type}

9. 移動桶

要把一個桶移動到 CRUSH Map 裏的不一樣位置,執行命令:

ceph osd crush move {bucket-name} {bucket-type}={bucket-name} [{bucket-type}={bucket-name} ...]

10. 刪除桶

要把一個桶從 CRUSH Map 的分級結構中刪除,可用此命令:

ceph osd crush remove {bucket-name}

注意:從 CRUSH 分級結構裏刪除時必須是空桶。

11. 可調選項

從 v0.74 起,若是 CRUSH 可調選項不是最優值( v0.73 版裏的默認值) Ceph 就會發出健康告警,有兩種方法可消除這些告警:

一、調整現有集羣上的可調選項。注意,這可能會致使一些數據遷移(可能有 10% 之多)。這是推薦的辦法,可是在生產集羣上要注意此調整對性能帶來的影響。此命令可啓用較優可調選項:

ceph osd crush tunables optimal

若是切換得不太順利(如負載過高)且切換纔不久,或者有客戶端兼容問題(較老的 cephfs 內核驅動或 rbd 客戶端、或早於 bobtail 的 librados 客戶端),你能夠這樣切回:

ceph osd crush tunables legacy

二、不對 CRUSH 作任何更改也能消除報警,把下列配置加入 ceph.conf 的 [mon] 段下:

mon warn on legacy crush tunables = false

爲使變動生效需重啓全部監視器,或者執行下列命令:

ceph tell mon.\* injectargs --no-mon-warn-on-legacy-crush-tunables

12.CRUSH Map 實例

假設你想讓大多數存儲池映射到使用大容量硬盤的 OSD 上,可是其中一些存儲池映射到使用高速 SSD 的 OSD 上。在同一個 CRUSH Map 內有多個獨立的 CRUSH 層級結構是可能的,定義兩棵樹、分別有本身的根節點 —— 一個用於機械硬盤(如 root platter )、一個用於 SSD (如 root ssd ),具體的 CRUSH Map 內容以下:

# devices

   device 0 osd.0

   device 1 osd.1

   device 2 osd.2

   device 3 osd.3

   device 4 osd.4

   device 5 osd.5

   device 6 osd.6

   device 7 osd.7


   # types

   type 0 osd

   type 1 host

   type 2 root


   # buckets

   host ceph-osd-ssd-server-1 {

           id -1

           alg straw

           hash 0

           item osd.0 weight 1.00

           item osd.1 weight 1.00

   }

   

   host ceph-osd-ssd-server-2 {

           id -2

           alg straw

           hash 0

           item osd.2 weight 1.00

           item osd.3 weight 1.00

   }


   host ceph-osd-platter-server-1 {

           id -3

           alg straw

           hash 0

           item osd.4 weight 1.00

           item osd.5 weight 1.00

   }


   host ceph-osd-platter-server-2 {

           id -4

           alg straw

           hash 0

           item osd.6 weight 1.00

           item osd.7 weight 1.00

   }


   root platter {

           id -5

           alg straw

           hash 0

           item ceph-osd-platter-server-1 weight 2.00

           item ceph-osd-platter-server-2 weight 2.00

   }


   root ssd {

           id -6

           alg straw

           hash 0

           item ceph-osd-ssd-server-1 weight 2.00

           item ceph-osd-ssd-server-2 weight 2.00

   }


   # rules

   rule replicated_ruleset {

           ruleset 0

           type replicated

           min_size 1

           max_size 10

           step take default

           step chooseleaf firstn 0 type host

           step emit

   }


   rule platter {

           ruleset 1

           type replicated

           min_size 0

           max_size 10

           step take platter

           step chooseleaf firstn 0 type host

           step emit

   }


   rule ssd {

           ruleset 2

           type replicated

           min_size 0

           max_size 4

           step take ssd

           step chooseleaf firstn 0 type host

           step emit

   }


   rule ssd-primary {

           ruleset 3

           type replicated

           min_size 5

           max_size 10

           step take ssd

           step chooseleaf firstn 1 type host

           step emit

           step take platter

           step chooseleaf firstn -1 type host

           step emit

   }

而後你能夠設置一個存儲池,讓它使用 SSD 規則:

ceph osd pool set <poolname> crush_ruleset 2

一樣,用 ssd-primary 規則將使存儲池內的各歸置組用 SSD 做主 OSD ,普通硬盤做副本。

相關文章
相關標籤/搜索