存储池介绍

Ceph 对集群中所有存储资源进行池化管理,pool 是一个逻辑上的概念,其表达的是一组数据存储和查找的约束条件。

Ceph 集群刚刚搭建成功之后会有系统内会默认创建一个 RBD 存储池(然而本人测试的 Luminous 版本却发现并没有默认的 RBD)。

Ceph 提供两种类型的存储池,多副本存储池(Replicated Pool)纠删码存储池(Erasure Code Pool)

存储池提供以下功能:

  • 自恢复力: 你可以设置在不丢数据的前提下允许多少 OSD 失效,对多副本存储池来说,此值是一对象应达到的副本数。 典型配置存储一个对象和它的一个副本(即 size = 2 ), 但你可以更改副本数; 对纠删编码的存储池来说,此值是编码块数(即纠删码配置里的 m=2 )。
  • 归置组: 你可以设置一个存储池的归置组数量。典型配置给每个 OSD 分配大约 100 个归置组, 这样,不用过多计算资源就能得到较优的均衡。配置了多个存储池时,要考虑到这些存储池和整个集群的归置组数量要合理。
  • CRUSH 规则: 当你在存储池里存数据的时候,与此存储池相关联的 CRUSH 规则集可控制 CRUSH 算法, 并以此操纵集群内对象及其副本的复制(或纠删码编码的存储池里的数据块)。你可以自定义存储池的 CRUSH 规则。
  • 快照: 用 ceph osd pool mksnap 创建快照的时候,实际上创建了某一特定存储池的快照。
  • 设置所有者: 你可以设置一个用户 ID 为一个存储池的所有者。

要把数据组织到存储池里,你可以列出、创建、删除存储池,也可以查看每个存储池的利用率。

环境说明

  • 操作系统: Ubuntu 18.04 LTS
  • Ceph 版本: 12.2.12 Luminous (stable)
  • 节点架构: 1 mon, 1 mgr, 3 osd

多副本存储池

所谓多副本存储池,就是把所有的对象都存多个副本,Ceph 默认的副本配置是 size = 3, 也就是说数据存三份,2 个副本。但是一般典型的配置 都会把 size 重置为 2,节省空间。

查看存储池列表

root@ceph1:~# ceph osd lspools
1 rbd,2 cephfs_data,3 cephfs_metadata,

root@ceph1:~# rados lspools
rbd
cephfs_data
cephfs_metadata 

查看详细的存储池信息:

ceph osd pool ls detail 

在新安装好的集群上,只有一个 rbd 存储池。

创建存储池

创建存储池前先看看 存储池、归置组和 CRUSH 配置参考。 你最好在配置文件里重置默认归置组数量,因为默认值并不理想。关于归置组数量请参考 设置归置组数量

修改默认归置组数量,只需要在 ceph.conf 文件的 [osd] 配置段修改就好了。

例如:

osd pool default pg num = 100
osd pool default pgp num = 100

命令形式:

ceph osd pool create {pool_name} {pg_num} [{pgp_num}] [replicated] [crush_ruleset_name] [expected_num_objects]

参数说明:

名称 类型 是否必需 参数说明
pool_name string Yes 存储池名称,必须唯一
pg_num int Yes 存储池的归置组总数,默认值为 8
pgp_num int No 用于归置的归置组总数。此值应该等于归置组总数
replicated string No replicated 表示创建的为多副本存储池
crush_ruleset_name string No 此存储池所用的 CRUSH 规则集名字。指定的规则集必须存在。
expected_num_objects int No 为这个存储池预估的对象数。
设置此值(要同时把 filestore merge threshold 设置为负数)后,
在创建存储池时就会拆分 PG 文件夹,
以免运行时拆分文件夹导致延时增大。

例如:

ceph osd pool create mytestpool 256 256 

设置存储池配额

存储池配额可设置最大字节数、以及每个存储池最大对象数。

命令形式:

ceph osd pool set-quota {pool_name} [max_objects {obj_count}] [max_bytes {bytes}]

例如:

ceph osd pool set-quota mytestpool max_objects 10000

查看存储池配额

root@ceph1:~#  ceph osd pool get-quota mytestpool
quotas for pool 'rbd':
  max objects: 10000
  max bytes  : N/A

获取/设置 pool 副本数

获取存储池副本:

ceph osd pool get {pool_name} size

例如:

ceph osd pool get mytestpool size

设置存储池副本:

ceph osd pool set {pool_name} size {size}

例如:

ceph osd pool set mytestpool size 2

调整存储池选项值

命令形式:

ceph osd pool set {pool_name} {key} {value}

例如:

# 获取 pg_num / pgp_num
ceph osd pool get mytestpool pg_num
ceph osd pool get mytestpool pgp_num
# 设置 pg_num
ceph osd pool set mytestpool pg_num 512
ceph osd pool set mytestpool pgp_num 512

具体有哪些属性可以调整,以及有效范围说明,请参考 调整存储池选项值

警告: Pool 的 pg_num 只能增大,不能减小。并且如果修改了 pg_num 最好同时修改 pgp_num,保持 pg_num = pgp_num。

减少 pg_num 会报错,例如:

root@ceph1:~# ceph osd pool get rbd pg_num
pg_num: 64
root@ceph1:~# ceph osd pool set rbd pg_num 60
Error EEXIST: specified pg_num 60 <= current 64

删除存储池

删除存储是非常危险测操作,会销毁存储池中的全部数据,所以如果要删除存储池,你首先要在配置文档 ceph.conf 加入一条配置, 设置允许删除存储池,然后重启 MON 服务生效。

mon_allow_pool_delete = true

其次为了防止删错,你需要连续输入两次 {pool_name}, 并且命令后面跟上 --yes-i-really-really-mean-it 参数。

命令形式:

ceph osd pool rm {pool_name} [{pool_name} –yes-i-really-really-mean-it]

例如:

root@ceph1:~# ceph osd pool rm mytestpool mytestpool --yes-i-really-really-mean-it
pool 'mytestpool' removed
提示:如果你给自建的存储池创建了定制的规则集,你不需要存储池时最好删除它。 如果你曾严格地创建了用户及其权限给一个存储池,但存储池已不存在,最好也删除那些用户。

重命名存储池

ceph osd pool rename {current_pool_name} {new_pool_name}

例如:

root@ceph1:~# ceph osd pool rename mytestpool new-pool-name
pool 'mytestpool' renamed to 'new-pool-name'

查看存储池统计信息

root@ceph1:~# rados df
POOL_NAME       USED    OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD      WR_OPS WR      
cephfs_data     1.00GiB     258      0    516                  0       0        0      2    2KiB    290 1.00GiB 
cephfs_metadata  214KiB      22      0     44                  0       0        0     75  479KiB    213  338KiB 
new-pool-name        0B       0      0      0                  0       0        0      0      0B      0      0B 
rbd             1.07GiB     294      5    588                  0       0        0   1943 14.6MiB    709 1.07GiB 

total_objects    574
total_used       11.2GiB
total_avail      24.1GiB
total_space      35.3GiB

创建/删除存储池快照

创建存储池快照

ceph osd pool mksnap {pool_name} {snap_name}

删除存储池快照

ceph osd pool rmsnap {pool_name} {snap_name}

纠删码存储池

Ceph 在没有特别指定参数的情况下,默认创建的是多副本存储池。纠删码存储池可以在提供与副本相同的冗余水平的同时节省空间。

最简单的纠删码存储池等效于RAID5,它相当于 size = 2 的副本池,却能节省 25% 的磁盘空间。

创建存储池

命令形式:

ceph osd pool create {pool_name} {pg_num} {pgp_num} erasure [erasure_code_profile] [crush_ruleset_name] [expected_num_objects]

下面命令创建一个最简单的纠删码存储池:

root@ceph1:~# ceph osd pool create ecpool 12 12 erasure
pool 'ecpool' created
root@ceph1:~# echo ABCDEFGHI | rados --pool ecpool put NYAN -
root@ceph1:~# rados --pool ecpool get NYAN -
ABCDEFGHI

纠删码配置

默认的纠删码配置只能允许损坏一个 OSD。它等效于 size=2 的 多副本存储池,但是需要 1.5TB 而不是 2TB 的数据来存储 1TB 的数据。

一个默认的纠删码配置是这样的:

root@ceph1:~# ceph osd erasure-code-profile get default
k=2
m=1
plugin=jerasure
technique=reed_sol_van

在此配置中 k=2 和 m=1 ,其含义为数据分布于 3 个 OSD ( k+m==3 )且允许一个失效。

选择正确的配置文件很重要,因为在创建池之后无法对其进行修改:需要创建一个具有不同配置文件的新池,并将先前池中的所有对象移至新池。

为了在不增加原始存储空间需求的前提下提升冗余性,你可以新建配置。 例如,一个 k=10 且 m=4 的配置可容忍 4 个 OSD 失效,它会把一对象分布到 14 个( k+m=14 ) OSD 上。 此对象先被分割为 10 块(若对象为 10MB ,那每块就是 1MB )、并计算出 4 个用于恢复的编码块(各编码块尺寸等于数据块,即 1MB ); 这样,原始空间仅多占用 10% 就可容忍 4 个 OSD 同时失效、且不丢失数据。

可以通过下面命令创建纠删码配置:

root@ceph1:~# ceph osd erasure-code-profile set myprofile k=10 m=4 ruleset-failure-domain=rack
root@ceph1:~# ceph osd pool create ecpool 12 12 erasure myprofile
pool 'ecpool' created

纠删码存储池与缓存分级

纠删码存储池比复制池需要更多的资源,并且缺少某些功能,例如部分写入。为了弥补这些缺陷,建议在纠删码存储池前面设置一个缓存层。

比如,如果 hot-storage 是由快速存储组成,我们可以使用下面的方式设置缓存层:

ceph osd tier add ecpool hot-storage
ceph osd tier cache-mode hot-storage writeback
ceph osd tier set-overlay ecpool hot-storage

此时会将 hot-storage 池作为 ecpool 池的回写模式,这样一来 ecpool 的每次写入和读取实际上都在使用 hot-storage 缓存池,并从其灵活性和速度中受益。

此外由于它需要部分写入,因此无法在纠删码池上创建 RBD 镜像。但是,当复制池层设置了缓存层时,可以在擦除编码池上创建RBD映像, 但是,当复制池层设置了缓存层时,可以在纠删码池上创建 RBD 镜像。
rbd create --size 10G ecpool/myvolume

参考文献