编辑crush map:
1、获取crush map;
2、反编译crush map;
3、至少编辑一个设备,桶, 规则;
4、重新编译crush map;
5、重新注入crush map;
获取crush map
要获取集群的crush map,执行命令:
ceph osd getcrushmap -o {compiled-crushmap-filename}
ceph将crush输出(-o)到你指定的文件,由于crush map是已编译的,所以需要反编译;
反编译crush map
要反编译crush map, 执行命令:
crushtool -d {compiled-crushmap-filename} -o {decompiled-crushmap-filename}
ceph将反编译(-d)二进制crush图,且输出(-o)到你指定的文件;
编译crush map
要编译crush map,执行命令:
crushtool -c {decompiled-crushmap-filename} -o {compiled-crushmap-filename}
ceph将已编译的crush map保存到你指定的文件;
注入crush map
要把crush map应用到集群,执行命令:
ceph osd setcrushmap -i {compiled-crushmap-filename}
ceph 将把你指定的已编译的crush map输入到集群;
crush map 参数:
CRUSH 图主要有 4 个主要段落。
- 设备 由任意对象存储设备组成,即对应一个 ceph-osd 进程的存储器。 Ceph 配置文件里的每个 OSD 都应该有一个设备。
- 桶类型: 定义了 CRUSH 分级结构里要用的桶类型( types ),桶由逐级汇聚的存储位置(如行、机柜、机箱、主机等等)及其权重组成。
- 桶例程: 定义了桶类型后,还必须声明主机的桶类型、以及规划的其它故障域。
- 规则: 由选择桶的方法组成。
如果你用我们的某个“入门手册”配起了 Ceph ,应该注意到了,你并不需要创建 CRUSH 图。 Ceph 部署工具生成了默认 CRUSH 运行图,它列出了你定义在 Ceph 配置文件中的 OSD 设备、并把配置文件 [osd] 段下定义的各 OSD 主机声明为桶。为保证数据安全和可用,你应该创建自己的 CRUSH 图,以反映出自己集群的故障域
Note : 生成的 CRUSH 图没考虑大粒度故障域,所以你修改 CRUSH 图时要考虑上,像机柜、行、数据中心。
CRUSH 图之设备:
为把归置组映射到 OSD , CRUSH 图需要 OSD 列表(即配置文件所定义的 OSD 守护进程名称),所以它们首先出现在 CRUSH 图里。要在 CRUSH 图里声明一个设备,在设备列表后面新建一行,输入 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
一般来说, 一个OSD映射到一个单独的硬盘或raid
crush map 之桶类型:
crush map里的第二个列表定义了bucket(桶)类型,桶简化了节点和叶子层次。节点(或非叶)桶在分级结构里一般表示物理位置,节点汇聚了其它节点或叶子,叶桶表示 ceph-osd 守护进程及其对应的存储媒体。
Tip:CRUSH 中用到的 bucket 意思是分级结构中的一个节点,也就是一个位置或一部分硬件。但是在 RADOS 网关接口的术语中,它又是不同的概念。
要往 CRUSH 图中增加一种 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
crush map 之桶层次
crush算法根据各设备的权重、大致统一的概率把数据对象分布到存储设备中,crush根据你定义的集群运行图分布对象及其副本,crush map表达了可用存储设置以及包含它们的逻辑单元;
要把归置组映射到跨故障域的OSD,一个crush图需要定义一些列分级桶类型(即现有crush图的#type下)。创建桶分级结构的目的是按故障域隔离叶节点,像主机,机箱,机柜,电力分配单元,集群,行,房间和数据中心。除了表示叶节点的OSD,其他分级结构都是任意的,你可以按需定义;
我们建议 CRUSH 图内的命名符合贵公司的硬件命名规则,并且采用反映物理硬件的例程名。良好的命名可简化集群管理和故障排除,当 OSD 和/或其它硬件出问题时,管理员可轻易找到对应物理硬件。
在下例中,桶分级结构有一个名为 osd 的分支、和两个节点分别名为 host 和 rack 。
Note :编号较高的 rack 桶类型汇聚编号较低的 host 桶类型
位于 CRUSH map起始部分、 #devices 列表内是表示叶节点的存储设备,没必要声明为桶例程。位于分级结构第二低层的桶一般用于汇聚设备(即它通常是包含存储媒体的计算机,你可以用自己喜欢的名字描述,如节点、计算机、服务器、主机、机器等等)。在高密度环境下,经常出现一机框内安装多个主机/节点的情况,因此还要考虑机框故障——比如,某一节点故障后需要拉出机框维修,这会影响多个主机/节点和其内的 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
}
Note:在前述示例中,机柜桶不包含任何 OSD ,它只包含低一级的主机桶、以及其内条目的权重之和。
桶类型
Ceph 支持四种桶,每种都是性能和组织简易间的折衷。如果你不确定用哪种桶,我们建议 straw ,关于桶类型的详细讨论见 CRUSH - Controlled, Scalable, Decentralized Placement of Replicated Data ,特别是 Section 3.4 。支持的桶类型有:
- Uniform: 这种桶用完全相同的权重汇聚设备。例如,公司采购或淘汰硬件时,一般都有相同的物理配置(如批发)。当存储设备权重都相同时,你可以用uniform 桶类型,它允许 CRUSH 按常数把副本映射到 uniform 桶。权重不统一时,你应该采用其它算法。
- List: 这种桶把它们的内容汇聚为链表。它基于 RUSH P 算法,一个列表就是一个自然、直观的扩张集群:对象会按一定概率被重定位到最新的设备、或者像从前一样仍保留在较老的设备上。结果是优化了新条目加入桶时的数据迁移。然而,如果从链表的中间或末尾删除了一些条目,将会导致大量没必要的挪动。所以这种桶适合永不或极少缩减的场景。
- Tree: 它用一种二进制搜索树,在桶包含大量条目时比 list 桶更高效。它基于 RUSH R 算法, tree 桶把归置时间减少到了 O(log n) ,这使得它们更适合管理更大规模的设备或嵌套桶。
- Straw: list 和 tree 桶用分而治之策略,给特定条目一定优先级(如位于链表开头的条目)、或避开对整个子树上所有条目的考虑。这样提升了副本归置进程的性能,但是也导致了重新组织时的次优结果,如增加、拆除、或重设某条目的权重。 straw 桶类型允许所有条目模拟拉稻草的过程公平地相互“竞争”副本归置
Hash
各个桶都用了一种哈希算法,当前 Ceph 仅支持 rjenkins1 ,输入 0 表示哈希算法设置为 rjenkins1 。
调整桶的权重
Ceph 用双整形表示桶权重。权重和设备容量不同,我们建议用 1.00 作为 1TB 存储设备的相对权重,这样 0.5 的权重大概代表 500GB 、 3.00 大概代表 3TB 。较高级桶的权重是所有枝叶桶的权重之和。
一个桶的权重是一维的,你也可以计算条目权重来反映存储设备性能。例如,如果你有很多 1TB 的硬盘,其中一些数据传输速率相对低、其他的数据传输率相对高,即使它们容量相同,也应该设置不同的权重(如给吞吐量较低的硬盘设置权重 0.8 ,较高的设置 1.20 )。
CRUSH map之规则
CRUSH 图支持“ CRUSH 规则”概念,用以确定一个存储池里数据的归置。对大型集群来说,你可能创建很多存储池,且每个存储池都有它自己的 CRUSH 规则集和规则。默认的 CRUSH 图里,每个存储池有一条规则、一个规则集被分配到每个默认存储池,它们有:
data / metadata / rbd
Note:大多数情况下,你都不需要修改默认规则。新创建存储池的默认规则集是 0 。
CRUSH 规则定义了归置和复制策略、或分布策略,用它可以规定 CRUSH 如何放置对象副本。例如,你也许想创建一条规则用以选择一对目的地做双路复制;另一条规则用以选择位于两个数据中心的三个目的地做三路镜像;又一条规则用 6 个设备做 RAID-4 。关于 CRUSH 规则的详细研究见 CRUSH - Controlled, Scalable, Decentralized Placement of Replicated Data ,主要是 Section 3.2 。
规则格式如下:
rule <rulename> {
ruleset <ruleset>
type [replicated | raid4 ]
min_size <min-size>
max_size <max-size>
step take <bucket-type>
step [choose | chooseleaf] [firstn|indep ] <N> <bucket-type>
set emit
}
ruleset
Description: 区分一条规则属于某个规则集的手段。给存储池设置规则集后激活。
Purpose: 规则掩码的一个组件。
Type: Integer
Required: Yes
Default: 0
type
Description: 为硬盘(复制的)或 RAID 写一条规则。
Purpose: 规则掩码的一个组件。
Type: String
Required: Yes
Default: replicated
Valid Values: Currently only replicated
min_size
Description: 如果一个归置组副本数小于此数, CRUSH 将不应用此规则。
Type: Integer
Purpose: 规则掩码的一个组件。
Required: Yes
Default: 1
max_size
Description: 如果一个归置组副本数大于此数, CRUSH 将不应用此规则。
Type: Integer
Purpose: 规则掩码的一个组件。
Required: Yes
Default: 10
step take <bucket-name>
Description: 选取桶名并迭代到树底。
Purpose: 规则掩码的一个组件。
Required: Yes
Example: step take data
step choose firstn {num} type {bucket-type}
Description: 选取指定类型桶的数量,这个数字通常是存储池的副本数(即 pool size )。
如果 {num} == 0 选择 pool-num-replicas 个桶(所有可用的);
如果 {num} > 0 && < pool-num-replicas 就选择那么多的桶;
如果 {num} < 0 它意为 pool-num-replicas - {num} 。
Purpose: 规则掩码的一个组件。
Prerequisite: 跟在 step take 或 step choose 之后。
Example:
step choose firstn 1 type row
step chooseleaf firstn {num} type {bucket-type}
Description:
选择 {bucket-type} 类型的一堆桶,并从各桶的子树里选择一个叶子节点。集合内桶的数量通常是存储池的副本数(即 pool size )。
如果 {num} == 0 选择 pool-num-replicas 个桶(所有可用的);
如果 {num} > 0 && < pool-num-replicas 就选择那么多的桶;
如果 {num} < 0 它意为 pool-num-replicas - {num} 。
Purpose: 规则掩码的一个组件。 它的使用避免了通过两步来选择一设备。
Prerequisite: Follows step take or step choose.
Example:
step chooseleaf firstn 0 type row
step emit
Description: 输出当前值并清空堆栈。通常用于规则末尾,也适用于相同规则应用到不同树的情况。
Purpose: 规则掩码的一个组件。
Prerequisite: Follows step choose.
Example: step emit
Important: 把规则集编号设置到存储池,才能用一个通用规则集编号激活一或多条规则。
主亲和性:
某一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 时选中它的可能性低。
给存储池指定 OSD:
假设你想让大多数存储池坐落到使用大硬盘的 OSD 上,但是其中一些存储池映射到使用高速 SSD 的 OSD 上。在同一个 CRUSH 图内有多个独立的 CRUSH 树是可能的,定义两棵树、分别有自己的根节点——一个用于硬盘(如 root platter )、一个用于 SSD (如 root ssd ),如:
1 device 0 osd.0 2 device 1 osd.1 3 device 2 osd.2 4 device 3 osd.3 5 device 4 osd.4 6 device 5 osd.5 7 device 6 osd.6 8 device 7 osd.7 9 10 host ceph-osd-ssd-server-1 { 11 id -1 12 alg straw 13 hash 0 14 item osd.0 weight 1.00 15 item osd.1 weight 1.00 16 } 17 18 host ceph-osd-ssd-server-2 { 19 id -2 20 alg straw 21 hash 0 22 item osd.2 weight 1.00 23 item osd.3 weight 1.00 24 } 25 26 host ceph-osd-platter-server-1 { 27 id -3 28 alg straw 29 hash 0 30 item osd.4 weight 1.00 31 item osd.5 weight 1.00 32 } 33 34 host ceph-osd-platter-server-2 { 35 id -4 36 alg straw 37 hash 0 38 item osd.6 weight 1.00 39 item osd.7 weight 1.00 40 } 41 42 root platter { 43 id -5 44 alg straw 45 hash 0 46 item ceph-osd-platter-server-1 weight 2.00 47 item ceph-osd-platter-server-2 weight 2.00 48 } 49 50 root ssd { 51 id -6 52 alg straw 53 hash 0 54 item ceph-osd-ssd-server-1 weight 2.00 55 item ceph-osd-ssd-server-2 weight 2.00 56 } 57 58 rule data { 59 ruleset 0 60 type replicated 61 min_size 2 62 max_size 2 63 step take platter 64 step chooseleaf firstn 0 type host 65 step emit 66 } 67 68 rule metadata { 69 ruleset 1 70 type replicated 71 min_size 0 72 max_size 10 73 step take platter 74 step chooseleaf firstn 0 type host 75 step emit 76 } 77 78 rule rbd { 79 ruleset 2 80 type replicated 81 min_size 0 82 max_size 10 83 step take platter 84 step chooseleaf firstn 0 type host 85 step emit 86 } 87 88 rule platter { 89 ruleset 3 90 type replicated 91 min_size 0 92 max_size 10 93 step take platter 94 step chooseleaf firstn 0 type host 95 step emit 96 } 97 98 rule ssd { 99 ruleset 4 100 type replicated 101 min_size 0 102 max_size 4 103 step take ssd 104 step chooseleaf firstn 0 type host 105 step emit 106 } 107 108 rule ssd-primary { 109 ruleset 5 110 type replicated 111 min_size 5 112 max_size 10 113 step take ssd 114 step chooseleaf firstn 1 type host 115 step emit 116 step take platter 117 step chooseleaf firstn -1 type host 118 step emit 119 }
然后设置一个存储池,让它使用SSD规则:
ceph osd pool set <poolname> crush_ruleset 4
同样,用ssd-primary规则将使存储池内的各归置组用SSD作主OSD, 普通硬盘作副本;
增加/移动 OSD
要增加或删除在线集群里 OSD 所对应的 CRUSH 图条目,执行 ceph osd crush set 命令:
ceph osd crush set {id-or-name} {weight} root={pool-name} [{bucket-type}={bucket-name} ...]
调整一OSD的crush权重:
要调整在线集群中一 OSD 的 CRUSH 权重,执行命令:
ceph osd crush reweight {name} {weight}
删除OSD:
要从在线集群里把一 OSD 踢出 CRUSH 图,执行命令:
ceph osd crush remove {name}
增加桶:
要在运行集群的 CRUSH 图中新建一个桶,用 ceph osd crush add-bucket 命令:
ceph osd crush add-bucket {bucket-name} {bucket-type}
http://mirrors.myccdn.info/ceph/doc/docs_zh/output/html/rados/operations/crush-map/
http://xxlazy.appspot.com/How-to-use-v2ex-setup-bbs.html