ceph分布式存儲(chǔ)-管理crushmap

1. 介紹


CRUSH 算法通過(guò)計(jì)算數(shù)據(jù)存儲(chǔ)位置來(lái)確定如何存儲(chǔ)和檢索。 CRUSH 授權(quán) Ceph 客戶端直接連接 OSD ,而非通過(guò)一個(gè)中央服務(wù)器或代理。數(shù)據(jù)存儲(chǔ)、檢索算法的使用,使 Ceph 避免了單點(diǎn)故障、性能瓶頸、和伸縮的物理限制。

CRUSH 需要一張集群的 Map,且使用 CRUSH Map 把數(shù)據(jù)偽隨機(jī)地、盡量平均地分布到整個(gè)集群的 OSD 里。CRUSH Map 包含 OSD 列表、把設(shè)備匯聚為物理位置的“桶”列表、和指示 CRUSH 如何復(fù)制存儲(chǔ)池里的數(shù)據(jù)的規(guī)則列表。

完全手動(dòng)管理 CRUSH Map 也是可能的,在配置文件中設(shè)定:

osd crush update on start = false

2. 編輯 CRUSH Map

要編輯現(xiàn)有的 CRUSH Map:

  1. 獲取 CRUSH Map;
  2. 反編譯 CRUSH 圖;
  3. 至少編輯一個(gè)設(shè)備、桶、規(guī)則;
  4. 重編譯 CRUSH Map;
  5. 注入 CRUSH Map。

要激活 CRUSH Map 里某存儲(chǔ)池的規(guī)則,找到通用規(guī)則集編號(hào),然后把它指定到那個(gè)規(guī)則集。

2.1 獲取 CRUSH Map

要獲取集群的 CRUSH Map,執(zhí)行命令:

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

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

2.2 反編譯 CRUSH Map

要反編譯 CRUSH Map,執(zhí)行命令:

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

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

2.3 編譯 CRUSH Map

要編譯 CRUSH Map,執(zhí)行命令:

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

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

2.4 注入 CRUSH Map

要把 CRUSH Map 應(yīng)用到集群,執(zhí)行命令:

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

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

3. CRUSH Map 參數(shù)

CRUSH Map 主要有 4 個(gè)段落。

  1. 設(shè)備: 由任意對(duì)象存儲(chǔ)設(shè)備組成,即對(duì)應(yīng)一個(gè) ceph-osd進(jìn)程的存儲(chǔ)器。 Ceph 配置文件里的每個(gè) OSD 都應(yīng)該有一個(gè)設(shè)備。
  2. 桶類(lèi)型: 定義了 CRUSH 分級(jí)結(jié)構(gòu)里要用的桶類(lèi)型( types ),桶由逐級(jí)匯聚的存儲(chǔ)位置(如行、機(jī)柜、機(jī)箱、主機(jī)等等)及其權(quán)重組成。
  3. 桶實(shí)例: 定義了桶類(lèi)型后,還必須聲明主機(jī)的桶類(lèi)型、以及規(guī)劃的其它故障域。
  4. 規(guī)則: 由選擇桶的方法組成。

3.1 CRUSH Map 之設(shè)備

為把 PG 映射到 OSD , CRUSH Map 需要 OSD 列表(即配置文件所定義的 OSD 守護(hù)進(jìn)程名稱),所以它們首先出現(xiàn)在 CRUSH Map 里。要在 CRUSH Map 里聲明一個(gè)設(shè)備,在設(shè)備列表后面新建一行,輸入 device 、之后是唯一的數(shù)字 ID 、之后是相應(yīng)的 ceph-osd 守護(hù)進(jìn)程實(shí)例名字。

# 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 之桶類(lèi)型

CRUSH Map 里的第二個(gè)列表定義了 bucket (桶)類(lèi)型,桶簡(jiǎn)化了節(jié)點(diǎn)和葉子層次。節(jié)點(diǎn)(或非葉子)桶在分級(jí)結(jié)構(gòu)里一般表示物理位置,節(jié)點(diǎn)匯聚了其它節(jié)點(diǎn)或葉子,葉桶表示 ceph-osd 守護(hù)進(jìn)程及其對(duì)應(yīng)的存儲(chǔ)媒體。

要往 CRUSH Map 中增加一種 bucket 類(lèi)型,在現(xiàn)有桶類(lèi)型列表下方新增一行,輸入 type 、之后是惟一數(shù)字 ID 和一個(gè)桶名。按慣例,會(huì)有一個(gè)葉子桶為 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 算法根據(jù)各設(shè)備的權(quán)重、大致統(tǒng)一的概率把數(shù)據(jù)對(duì)象分布到存儲(chǔ)設(shè)備中。 CRUSH 根據(jù)你定義的集群運(yùn)行圖分布對(duì)象及其副本, CRUSH Map 表達(dá)了可用存儲(chǔ)設(shè)備以及包含它們的邏輯單元。

要把 PG 映射到跨故障域的 OSD ,一個(gè) CRUSH Map 需定義一系列分級(jí)桶類(lèi)型(即現(xiàn)有 CRUSH Map 的 # type 下)。創(chuàng)建桶分級(jí)結(jié)構(gòu)的目的是按故障域隔離葉子節(jié)點(diǎn),像主機(jī)、機(jī)箱、機(jī)柜、電力分配單元、機(jī)群、行、房間、和數(shù)據(jù)中心。除了表示葉子節(jié)點(diǎn)的 OSD ,其它分級(jí)結(jié)構(gòu)都是任意的,你可以按需定義。

聲明一個(gè)桶實(shí)例時(shí),你必須指定其類(lèi)型、惟一名稱(字符串)、惟一負(fù)整數(shù) ID (可選)、指定和各條目總?cè)萘?能力相關(guān)的權(quán)重、指定桶算法(通常是 straw )、和哈希(通常為 0 ,表示哈希算法 rjenkins1 )。一個(gè)桶可以包含一到多個(gè)條目,這些條目可以由節(jié)點(diǎn)桶或葉子組成,它們可以有個(gè)權(quán)重用來(lái)反映條目的相對(duì)權(quán)重。

你可以按下列語(yǔ)法聲明一個(gè)節(jié)點(diǎn)桶:

    [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]
    }

例如,我們可以定義兩個(gè)主機(jī)桶和一個(gè)機(jī)柜桶,機(jī)柜桶包含兩個(gè)主機(jī)桶, OSD 被聲明為主機(jī)桶內(nèi)的條目:

    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
    }
調(diào)整桶的權(quán)重

Ceph 用雙精度類(lèi)型數(shù)據(jù)表示桶權(quán)重。權(quán)重和設(shè)備容量不同,我們建議用 1.00 作為 1TB 存儲(chǔ)設(shè)備的相對(duì)權(quán)重,這樣 0.5 的權(quán)重大概代表 500GB 、 3.00 大概代表 3TB 。較高級(jí)桶的權(quán)重是所有葉子桶的權(quán)重之和。

一個(gè)桶的權(quán)重是一維的,你也可以計(jì)算條目權(quán)重來(lái)反映存儲(chǔ)設(shè)備性能。例如,如果你有很多 1TB 的硬盤(pán),其中一些數(shù)據(jù)傳輸速率相對(duì)低、其他的數(shù)據(jù)傳輸率相對(duì)高,即使它們?nèi)萘肯嗤?,也?yīng)該設(shè)置不同的權(quán)重(如給吞吐量較低的硬盤(pán)設(shè)置權(quán)重 0.8 ,較高的設(shè)置 1.20 )。

3.4 CRUSH Map 之規(guī)則

CRUSH Map 支持“ CRUSH 規(guī)則”的概念,用以確定一個(gè)存儲(chǔ)池里數(shù)據(jù)的分布。CRUSH 規(guī)則定義了歸置和復(fù)制策略、或分布策略,用它可以規(guī)定 CRUSH 如何放置對(duì)象副本。對(duì)大型集群來(lái)說(shuō),你可能創(chuàng)建很多存儲(chǔ)池,且每個(gè)存儲(chǔ)池都有它自己的 CRUSH 規(guī)則集和規(guī)則。默認(rèn)的 CRUSH Map 里,每個(gè)存儲(chǔ)池有一條規(guī)則、一個(gè)規(guī)則集被分配到每個(gè)默認(rèn)存儲(chǔ)池。

注意: 大多數(shù)情況下,你都不需要修改默認(rèn)規(guī)則。新創(chuàng)建存儲(chǔ)池的默認(rèn)規(guī)則集是 0

規(guī)則格式如下:

    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
    }

參數(shù)說(shuō)明:

  • ruleset:區(qū)分一條規(guī)則屬于某個(gè)規(guī)則集的手段。給存儲(chǔ)池設(shè)置規(guī)則集后激活。
  • type:規(guī)則類(lèi)型,目前僅支持 replicatederasure ,默認(rèn)是 replicated 。
  • min_size:可以選擇此規(guī)則的存儲(chǔ)池最小副本數(shù)。
  • max_size:可以選擇此規(guī)則的存儲(chǔ)池最大副本數(shù)。
  • step take <bucket-name>:選取起始的桶名,并迭代到樹(shù)底。
  • step choose firstn {num} type {bucket-type}:選取指定類(lèi)型桶的數(shù)量,這個(gè)數(shù)字通常是存儲(chǔ)池的副本數(shù)(即 pool size )。如果 {num} == 0 , 選擇 pool-num-replicas 個(gè)桶(所有可用的);如果 {num} > 0 && < pool-num-replicas ,就選擇那么多的桶;如果 {num} < 0 ,它意味著選擇 pool-num-replicas - {num} 個(gè)桶。
  • step chooseleaf firstn {num} type {bucket-type}:選擇 {bucket-type} 類(lèi)型的桶集合,并從各桶的子樹(shù)里選擇一個(gè)葉子節(jié)點(diǎn)。桶集合的數(shù)量通常是存儲(chǔ)池的副本數(shù)(即 pool size )。如果 {num} == 0 ,選擇 pool-num-replicas 個(gè)桶(所有可用的);如果 {num} > 0 && < pool-num-replicas ,就選擇那么多的桶;如果 {num} < 0 ,它意味著選擇 pool-num-replicas - {num} 個(gè)桶。
  • step emit:輸出當(dāng)前值并清空堆棧。通常用于規(guī)則末尾,也適用于相同規(guī)則應(yīng)用到不同樹(shù)的情況。

4. 主親和性

某個(gè) Ceph 客戶端讀寫(xiě)數(shù)據(jù)時(shí),總是連接 acting set 里的主 OSD (如 [2, 3, 4] 中, osd.2 是主的)。有時(shí)候某個(gè) OSD 與其它的相比并不適合做主 OSD (比如其硬盤(pán)慢、或控制器慢)。最大化硬件利用率時(shí)為防止性能瓶頸(特別是讀操作),你可以調(diào)整 OSD 的主親和性,這樣 CRUSH 就盡量不把它用作 acting set 里的主 OSD 了。

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

主親和性默認(rèn)為 1 (就是說(shuō)此 OSD 可作為主 OSD )。此值合法范圍為 0-1 ,其中 0 意為此 OSD 不能用作主的, 1 意為 OSD 可用作主的。此權(quán)重 < 1 時(shí), CRUSH 選擇主 OSD 時(shí)選中它的可能性就較低。

5. 增加/移動(dòng) OSD

要增加或移動(dòng)在線集群里 OSD 所對(duì)應(yīng)的 CRUSH Map 條目,執(zhí)行 ceph osd crush set 命令。

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

6. 調(diào)整 OSD 的 CRUSH 權(quán)重

要調(diào)整在線集群中某個(gè) OSD 的 CRUSH 權(quán)重,執(zhí)行命令:

    ceph osd crush reweight {name} {weight}

7. 刪除 OSD

要從在線集群里把某個(gè) OSD 徹底踢出 CRUSH Map,或僅踢出某個(gè)指定位置的 OSD,執(zhí)行命令:

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

8. 增加桶

要在運(yùn)行集群的 CRUSH Map 中新建一個(gè)桶,用 ceph osd crush add-bucket 命令:

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

9. 移動(dòng)桶

要把一個(gè)桶移動(dòng)到 CRUSH Map 里的不同位置,執(zhí)行命令:

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

10. 刪除桶

要把一個(gè)桶從 CRUSH Map 的分級(jí)結(jié)構(gòu)中刪除,可用此命令:

ceph osd crush remove {bucket-name}

注意:從 CRUSH 分級(jí)結(jié)構(gòu)里刪除時(shí)必須是空桶。

11. 可調(diào)選項(xiàng)

從 v0.74 起,如果 CRUSH 可調(diào)選項(xiàng)不是最優(yōu)值( v0.73 版里的默認(rèn)值) Ceph 就會(huì)發(fā)出健康告警,有兩種方法可消除這些告警:

1、調(diào)整現(xiàn)有集群上的可調(diào)選項(xiàng)。注意,這可能會(huì)導(dǎo)致一些數(shù)據(jù)遷移(可能有 10% 之多)。這是推薦的辦法,但是在生產(chǎn)集群上要注意此調(diào)整對(duì)性能帶來(lái)的影響。此命令可啟用較優(yōu)可調(diào)選項(xiàng):

    ceph osd crush tunables optimal

如果切換得不太順利(如負(fù)載太高)且切換才不久,或者有客戶端兼容問(wèn)題(較老的 cephfs 內(nèi)核驅(qū)動(dòng)或 rbd 客戶端、或早于 bobtail 的 librados 客戶端),你可以這樣切回:

    ceph osd crush tunables legacy

2、不對(duì) CRUSH 做任何更改也能消除報(bào)警,把下列配置加入 ceph.conf[mon] 段下:

    mon warn on legacy crush tunables = false

為使變更生效需重啟所有監(jiān)視器,或者執(zhí)行下列命令:

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

5.7 CRUSH Map 實(shí)例

假設(shè)你想讓大多數(shù)存儲(chǔ)池映射到使用大容量硬盤(pán)的 OSD 上,但是其中一些存儲(chǔ)池映射到使用高速 SSD 的 OSD 上。在同一個(gè) CRUSH Map 內(nèi)有多個(gè)獨(dú)立的 CRUSH 層級(jí)結(jié)構(gòu)是可能的,定義兩棵樹(shù)、分別有自己的根節(jié)點(diǎn) —— 一個(gè)用于機(jī)械硬盤(pán)(如 root platter )、一個(gè)用于 SSD (如 root ssd ),具體的 CRUSH Map 內(nèi)容如下:

    # 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
    }

然后你可以設(shè)置一個(gè)存儲(chǔ)池,讓它使用 SSD 規(guī)則:

    ceph osd pool set <poolname> crush_ruleset 2

同樣,用 ssd-primary 規(guī)則將使存儲(chǔ)池內(nèi)的各歸置組用 SSD 作主 OSD ,普通硬盤(pán)作副本。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載社區(qū)的文章 目錄 第1章 概覽 第2章 存儲(chǔ)集群架構(gòu) 2.1 存儲(chǔ)池 2.2 身份認(rèn)證 2.3 PG(s) 2...
    620T閱讀 4,854評(píng)論 0 11
  • 參考文檔 https://www.linuxidc.com/Linux/2017-09/146760.htmhtt...
    三杯水Plus閱讀 4,543評(píng)論 0 8
  • ceph簡(jiǎn)介 Ceph是一個(gè)分布式存儲(chǔ)系統(tǒng),誕生于2004年,是最早致力于開(kāi)發(fā)下一代高性能分布式文件系統(tǒng)的項(xiàng)目。隨...
    愛(ài)吃土豆的程序猿閱讀 6,172評(píng)論 0 21
  • CRUSH 算法通過(guò)計(jì)算數(shù)據(jù)存儲(chǔ)位置來(lái)確定如何存儲(chǔ)和檢索。 CRUSH 授權(quán) Ceph 客戶端直接連接 OSD ,...
    Joncc閱讀 913評(píng)論 0 1
  • 系統(tǒng)環(huán)境: centos73.10.0-514.26.2.el7.x86_64 機(jī)器數(shù)量:五臺(tái) 硬盤(pán):四塊一塊為系...
    think_lonely閱讀 5,042評(píng)論 0 5

友情鏈接更多精彩內(nèi)容