ceph通过CRUSH算法计算数据存储位置来确定如何存储和检索数据。 CRUSH使Ceph客户端可以直接与OSD通信,而无需通过集中式服务器或代理进行通信。 通过算法确定的存储和检索数据的方法,Ceph避免了单点故障,性能瓶颈以及对其可扩展性的物理限制。
对于ceph集群的一次读写操作,客户端首先与mon通信获取一个集群的map副本。集群map帮助客户端获取ceph集群的状态和配置信息。使用对象和池名/ID将数据转换为对象,然后将对象和PG经过散列来生成其在ceph池中最终存放的哪一个PG,再通过存放的PG进行CRUSH查找来确定存储或获取数据所需的主OSD的位置。得到OSD ID后,客户端直接与OSD通信进行数据读写。所有的计算操作由客户端来完成,因此不会影响集群的性能。一旦数据被写入主OSD,主OSD所在的节点将执行CRUSH查找操作并计算副本PG和OSD的位置进行数据复制,进而实现高可用性。
CRUSH维护了所有基础设施组件的一个嵌套层次结构。CRUSH设备列表通常包括主机、机架、行等。这些组件称为故障域或CRUSH bucket。CRUSH map包含一系列可以bucket,这些bucket表明了设备的具体物理位置。它还包含了一系列的规则告诉CRUSH如何为不同的ceph池复制数据。
CRUSH map 定义了一系列用于描述节点的类型:
osd (or device)
host
chassis
rack
row
pdu
pod
room
datacenter
zone
region
root
层次结构中的每个节点(设备或bucket)都有与之关联的权重,权重设置在叶子上,指示设备的大小,默认节点的权重将是它下面包含的所有设备的总和。 通常,权重以TB为单位。
可以通过ceph osd crush tree
查看层次结构
[root@ceph-admin ~]# ceph osd crush tree
INFO:cephadm:Inferring fsid 23db6d22-b1ce-11ea-b263-1e00940000dc
INFO:cephadm:Using recent ceph image ceph/ceph:v15
ID CLASS WEIGHT TYPE NAME
-1 0.29306 root default
-5 0.09769 host ceph-admin
1 hdd 0.09769 osd.1
-7 0.09769 host ceph-node1
2 hdd 0.09769 osd.2
-3 0.09769 host ceph-node2
0 hdd 0.09769 osd.0
Rules定义如何在层次结构中的设备之间分配数据的策略。CRUSH规则定义了存放和复制策略或分发策略,可让确切指定CRUSH如何放置对象副本。
几乎所有情况下,都可以通过CLI创建CRUSH规则,方法是指定它们将用于的池类型,故障域以及可选的设备类。 在极少数情况下,必须通过手动编辑CRUSH映射来手工编写规则。
可以使用以下命令查看为集群定义了哪些规则:
ceph osd crush rule ls
每个设备可以选择具有与之关联的类别。 默认情况下,OSD在启动时会根据其支持的设备类型自动将其类设置为hdd,ssd或nvme。
可以使用以下命令设置一个或多个OSD的设备类
ceph osd crush set-device-class [...]
设置设备类别后,除非使用以下方法取消旧的类别,否则无法将其更改为另一个类别:
ceph osd crush rm-device-class [...]
使用以下方法创建针对特定设备类别的放置规则:
ceph osd crush rule create-replicated
更改池的规则
ceph osd pool set crush_rule
ceph osd crush set {name} {weight} root={root} [{bucket-type}={bucket-name} ...]
$ ceph osd crush set osd.0 1.0 root=default datacenter=dc1 room=room1 row=foo rack=bar host=foo-bar-1
ceph osd crush reweight {name} {weight}
ceph osd crush remove {name}
ceph osd crush add-bucket {bucket-name} {bucket-type}
$ ceph osd crush add-bucket rack12 rack
将bucket移动到CRUSH地次结构中的其他位置或位置
ceph osd crush move {bucket-name} {bucket-type}={bucket-name}, [...]
ceph osd crush remove {bucket-name}
ceph osd crush remove rack12
对于复制池,创建CRUSH规则时的主要决策是故障域的类型。
例如,如果选择了主机的故障域,则CRUSH将确保数据的每个副本都存储在不同的主机上。如果选择了机架,则每个副本将存储在不同的机架中。选择哪个故障域主要取决于群集的大小以及层次结构的结构。
通常,整个集群层次结构嵌套在名为default的根节点下。如果已自定义层次结构,则可能要创建一个嵌套在层次结构中其他节点上的规则。与该节点关联的类型无关紧要(不必是根节点)。
也可以创建一个规则,将数据放置位置限制为特定类别的设备。默认情况下,Ceph OSD会根据所使用设备的基础类型自动将自身分类为hdd或ssd。这些类也可以自定义。
要创建复制规则,执行以下操作:
ceph osd crush rule create-replicated {name} {root} {failure-domain-type} [{class}]
对于擦除编码池,需要做出与复制池相同的基本决定:故障域是什么,数据将放置在层次结构中的哪个节点下(通常是默认值),并且放置位置将限制为特定的 设备类。 但是,删除代码池的创建方式略有不同,因为需要根据所使用的删除代码仔细构建它们。 因此,必须在擦除代码配置文件中包含此信息。 然后,使用配置文件创建池时,将根据该规则显式或自动创建一个CRUSH规则。
列出擦除代码文件
ceph osd erasure-code-profile ls
获取详细信息
ceph osd erasure-code-profile get {profile-name}
[root@ceph-admin ~]# ceph osd erasure-code-profile ls
INFO:cephadm:Inferring fsid 23db6d22-b1ce-11ea-b263-1e00940000dc
INFO:cephadm:Using recent ceph image ceph/ceph:v15
default
[root@ceph-admin ~]# ceph osd erasure-code-profile get default
INFO:cephadm:Inferring fsid 23db6d22-b1ce-11ea-b263-1e00940000dc
INFO:cephadm:Using recent ceph image ceph/ceph:v15
k=2
m=2
plugin=jerasure
technique=reed_sol_van
通常,绝对不要修改配置文件。 而是在创建新池或为现有池创建新规则时创建并使用新配置文件。
擦除码配置文件由一组键=值对组成。 其中大多数控制擦除代码的行为,该擦除代码正在对池中的数据进行编码。 那些以Crush开头的文件会影响所创建的CRUSH规则。
rush-root: 将数据放置在[default:default]下的CRUSH节点的名称。
rush-failure-domain:CRUSH类型,用于在[default:host]之间分隔擦除编码的碎片。
rush-device-class:用于放置数据的设备类[默认:无,表示使用了所有设备]。
k和m(对于lrc插件,为l):它们确定擦除代码分片的数量,影响最终的CRUSH规则。
一旦定义了配置文件,可以创建规则
ceph osd crush rule create-erasure {name} {profile-name}
删除规则
ceph osd crush rule rm {rule-name}