ceph存储池管理

一、ceph存储池详解

1、ceph的存储流程

  • 数据怎么存储进去的呢?

当客户端需要存储一个文件到ceph集群的时候,ceph会将这个文件切分成多个对象,默认情况下每个对象4M,切分之后每个对象都有一个对应的对象ID,ceph拿到这个对象ID之后执行hash算法,去计算出这个对象写入到哪个PG(placement group),在PG上通过这个crush算法,最后存储到主OSD上面,主OSD进行同步到备用的OSD上,写入完成

  • PG的理解

    • 就是虚拟出来的,逻辑划分

    • 将对象存储到PG上

    • 集群PG数目经过严格的划分,PG映射哪些OSD

    • 一个PG可以存储多个对象,一个对象只能在一个PG上面

    • 方便管理,PG的数量远远小于对象的数量,管理一个PG就相等于是管理多个对象

    • 一个PG对应多个osd

1、数据写入

  • ceph默认有多副本机制

  • client通过这个mon节点获取到集群的信息

  • client根据hash使用对象id和存储池名称算出对象的所在的PG

  • client将对象放入到PG,使用存储池的crush算法得出了PG映射的一组osd

  • client通过PG-map,得出一组osd中的主osd,第一个osd就是主osd

  • client向主osd发起io请求,完成对象的读写操作

  • 主osd同步到备用的osd上即可

2、数据读取了

  • ceph读取数据的话,永远是在主osd节点上读取的,不会从备用节点上面读取

二、ceph存储池

1、什么是存储池呢?

  • 图解

  • 一个存储池有多个pg,一个pg映射多个osd

2、存储池的配置

1、存储池创建

  • 创建出来的存储池,里面pg,osd对应的关系是自动的创建出来的,不需要人为操作
ceph osd pool create poolname [pg_num:int] [pgp_num:int] [replicated|erasure] [earsure_code_profile]


# poolname 存储池的名称

# pg_num  pg的数量

# pgp_num  pg分裂的,下面有详解

# replicated|erasure  存储池类型,默认创建的是副本池,还有一个是纠删池(常用的)

# earsure_code_profile 纠删码配置模版,当需要创建纠删池的时候,必选参数,有一个默认的纠删码规则

[root@ceph01 ~]# ceph osd pool create test
pool 'test' created

# 查看集群有哪些存储池
[root@ceph01 ~]# ceph osd pool ls
device_health_metrics
test

# 查看存储池的详细信息
[root@ceph01 ~]# ceph osd pool ls detail 
pool 1 'device_health_metrics' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 1 pgp_num 1 autoscale_mode on last_change 74 flags hashpspool stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr_devicehealth
pool 2 'test' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 81 flags hashpspool stripe_width 0

# min_size=2 表示这个存储池中至少有2个副本处于可用的状态,才能进行IO读写,有一个osd故障了,还有2个osd,可以读写

# 但是2个osd故障了,只剩下一个osd了,这个存储池不会进行读写操作

  • 创建存储池后,里面会有pg,osd,自动的创建出来的
ceph pg ls-by-pool test

# 可以看到pg,osd之间的关系

# 默认的故障域是主机,这个是存储池的规则,因此的话,一个pg映射到3个不同主机上的osd

# 防止主机故障

# 每个存储池都有自己的规则

1、pgp是什么?

  • pg里面存储的是对象,如果pg数量少,对象的数量特别的多,因此我们需要创建更多的pg

  • pg不是直接创建出来的,而是原有的pg一分为二,分裂出来的

  • 当pg_num数量增加的时候,存储池中的pg一分为二,新的PG,需要进行crush算法,重新映射哪些osd上面

  • ceph会继续再平衡的,对象会从旧的osd上迁移到新的osd上

  • 图解

pg 1 映射osd 1 2 3 

pg_num数量增加 pg1.1 pg1.2

pg1.1 映射关系不变

pg1.2 映射到osd 4 5 6 

ceph 再平衡,将数据迁移到 osd 4 5 6 

  • 这样的作用

    • 数据分布的更加均匀了,分布在多个osd上面了

    • 每一个osd处理的对象减少了,i/o压力分散了

2、存储池的标签

  • 作用就是区分,表名这个存储池是干什么的,rgw,rbd,还是cephfs

  • 就是一个标签的作用

ceph osd pool application enable test rbd

[root@ceph01 ~]# ceph osd pool ls  detail | grep rbd
pool 2 'test' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 83 flags hashpspool stripe_width 0 application rbd

移除标签

[root@ceph01 ~]# ceph osd pool application disable test rbd
Error EPERM: Are you SURE? Disabling an application within a pool might result in loss of application functionality; pass --yes-i-really-mean-it to proceed anyway

# 提示,需要输入--yes-i-really-mean-it 才生效,需要确认一下才行
[root@ceph01 ~]# ceph osd pool application disable test rbd --yes-i-really-mean-itdisable application 'rbd' on pool 'test'

# 查看存储池详情
[root@ceph01 ~]# ceph osd pool  ls detail 
pool 1 'device_health_metrics' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 1 pgp_num 1 autoscale_mode on last_change 74 flags hashpspool stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr_devicehealth
pool 2 'test' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 84 flags hashpspool stripe_width 0


3、对象管理

  • 使用rados操作ceph集群,只是为了做测试而已

  • 生产环境中,不是这样的,而是对外提供服务的,rbd,rgw,cephfs提供外部的

1、上传对象

  • 基本单位是对象,上传单个文件

  • 或者就是将目录打包,然后在上传

[root@ceph01 ~]# rados -p test put obj1 /etc/hosts 

# -p 是指定存储池

# put 是上传操作

# obj1 是对象的id(对象名称),自己指定

# /etc/hosts 需要上传的文件

# 核心存储到pg上,最后是落在osd上了

2、查看对象

[root@ceph01 ~]# rados -p test ls
obj1

3、下载对象

[root@ceph01 ~]# rados -p test get obj1 ./hosts
[root@ceph01 ~]# cat hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.50.20 ceph01
192.168.50.21 ceph02
192.168.50.22 ceph03

4、删除对象

[root@ceph01 ~]# rados -p test ls 
obj1
[root@ceph01 ~]# rados -p test rm obj1
[root@ceph01 ~]# rados -p test ls 

5、查询对象所在的pg,osd

# 查看osd map信息,存储池test里面的q1对象的信息
[root@ceph01 ~]# ceph osd map test q1
osdmap e85 pool 'test' (2) object 'q1' -> pg 2.884c1a51 (2.11) -> up ([4,1,8], p4) acting ([4,1,8], p4)

# 发现在pg2.11上

# 对应的osd是4,1,8 这个osd.4是主osd

6、限制存储池配额

  • 2种方式的限制

    • 一个是限制这个对象的数目,这个不是很常用的

    • 还有一个就是限制最大字节数,就是限制最大存储空间

  • 限制满的话,不会报错,会一直卡在那

# 设置最大字节数为5M

[root@ceph01 ~]# ceph osd pool  set-quota test max_bytes 5M
set-quota max_bytes = 5242880 for pool test

# 查看存储池的配额
[root@ceph01 ~]# ceph osd pool get-quota test 
quotas for pool 'test':
  max objects: N/A
  max bytes  : 5 MiB  (current num bytes: 222 bytes)


# 上传一个6M的文件,可以完整的上传上去,但是下次再次上传的时候,就会一直卡在那

[root@ceph01 ~]# dd if=/dev/zero of=123.txt count=1 bs=6M
1+0 records in
1+0 records out
6291456 bytes (6.3 MB, 6.0 MiB) copied, 0.00336372 s, 1.9 GB/s

[root@ceph01 ~]# rados -p test put q2 123.txt
[root@ceph01 ~]# rados -p test ls 
q2
q1

# 有一个问题就是,超出了怎么还能上传进去了

# 只有这个存储池的空间没有满,就能完整的上传进去

# 再次上传一个就上传不了了

[root@ceph01 ~]# rados -p test put q3 /etc/hosts


^C

  • 配额满的话,不能进行上传和下载的操作,只能进行这个get操作

4、存储池快照

  • 这个不是很常用的

  • 核心原理

    • 对现在的存储池打上一个快照,里面有存储池的对象

    • 如果文件丢失的话,需要将快照的某个对象下载到本地,然后在上传到存储池中

    • 非常的不好用,如果对象特别多个的,需要编程,一个一个遍历,下载,上传

[root@ceph01 ~]# rados -p test2 put 1.txt /etc/hosts
[root@ceph01 ~]# rados -p test2 ls 
1.txt
[root@ceph01 ~]# rados -p test2 mksnap snap01
created pool test2 snap snap01

# 查看这个存储池有哪些快照
[root@ceph01 ~]# rados -p test2 lssnap
1	snap01	2026.03.16 22:05:17
1 snaps

# 删除存储池的中的文件

[root@ceph01 ~]# rados -p test2 rm 1.txt

# 删除后,发现里面还有对象,是一个bug,但是了实际是删除掉的
[root@ceph01 ~]# rados -p test2 ls 
1.txt

# 将这个对象下载到本地,发现没有
[root@ceph01 ~]# rados -p test2 get 1.txt 1.txt
error getting test2/1.txt: (2) No such file or directory

# 将文件还原

# 将快照里面的对象下载到本地
[root@ceph01 ~]# rados -p test2 -s snap01 get 1.txt ./1.txt

[root@ceph01 ~]# rados -p test2 put 1.txt 1.txt
[root@ceph01 ~]# rados -p test2 ls 
1.txt

  • 非常的麻烦

5、修改存储池的属性

1、列出存储池的所有属性

[root@ceph01 ~]# ceph osd pool get test all
size: 3
min_size: 2
pg_num: 32
pgp_num: 32
crush_rule: replicated_rule
hashpspool: true
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
fast_read: 0
pg_autoscale_mode: on
bulk: false

2、调整副本数为4

ceph osd pool set test1 size 4

# 虽然设置为4个,但是了,故障域是主机,没有4个节点

# ceph -s 就会警告

3、禁止删除存储池

[root@ceph01 ~]# ceph osd pool set test2 nodelete true
set pool 3 nodelete to true

# 如果想要删除的话,就需要设置为false

  • 删除存储池
[root@ceph01 ~]# ceph osd pool rm test2
Error EPERM: WARNING: this will *PERMANENTLY DESTROY* all data stored in pool test2.  If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, followed by --yes-i-really-really-mean-it.

# 存储池名字需要写2遍
[root@ceph01 ~]# ceph osd pool rm test2 test2 --yes-i-really-really-mean-it
Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

# 还是无法删除
  • 将刚刚设置了不允许被删除,现在我们取消
[root@ceph01 ~]# ceph osd pool rm test2 test2 --yes-i-really-really-mean-it
Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

  • 发现还是删除不了,提示需要mon_allow_pool_delete 默认为false,不允许删除pool
[root@ceph01 ~]# ceph config set mon mon_allow_pool_delete true
[root@ceph01 ~]# ceph osd pool rm test2 test2 --yes-i-really-really-mean-it
pool 'test2' removed

  • 非常慎重,删除存储池,因为删除后,里面的对象就没有了

6、纠删码池管理

  • 这个是常用的,只能做对象网关

  • 也有冗余性

1、核心原理

一个3M的文件,拆解为3个1M的文件,2个1M的校验块,冗余的能力是校验块的块数,就是冗余2个,就是如果故障了2个数据块的话,客户端还是能够访问的,因为这个校验块能够恢复这个数据,如果3个数据块全部故障了,则恢复不了

  • 默认是3+2,3个数据块,2个校验块

2、创建纠删码池

[root@ceph01 ~]# ceph osd pool create test1 erasure
pool 'test1' created


# 使用的是默认的纠删码规则
[root@ceph01 ~]# ceph osd pool ls detail | grep test1
pool 5 'test1' erasure profile default size 4 min_size 3 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 109 flags hashpspool stripe_width 8192

查看纠删码默认的配置文件

[root@ceph01 ~]# ceph osd erasure-code-profile ls
default


[root@ceph01 ~]# ceph osd erasure-code-profile get default
k=2  # 数据块数
m=2  # 校验块数
plugin=jerasure
technique=reed_sol_van

1、创建自己的纠删码规则

[root@ceph01 ~]# ceph osd erasure-code-profile set  test_profile crush-failure-domain=osd k=3 m=2

# 上面使用的故障域是osd,就是将数据分配在不同的osd上即可,如果是主机的话,则分布在不同的主机上,没有5个节点,因此不行,需要分布在不同的osd上才行


[root@ceph01 ~]# ceph osd erasure-code-profile ls
default
test_profile


[root@ceph01 ~]# ceph osd erasure-code-profile get  test_profile
crush-device-class=
crush-failure-domain=osd
crush-root=default
jerasure-per-chunk-alignment=false
k=3
m=2
plugin=jerasure
technique=reed_sol_van
w=8

2、使用自己的纠删码规则创建池

[root@ceph01 ~]# ceph osd pool create test2 erasure test_profile
pool 'test2' created

[root@ceph01 ~]# ceph osd pool get test2 all
size: 5  # 3+2 
min_size: 4
pg_num: 32
pgp_num: 32
crush_rule: test2
hashpspool: true
allow_ec_overwrites: false
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
erasure_code_profile: test_profile  # 使用自己的规则
fast_read: 0
pg_autoscale_mode: on
bulk: false

3、上传对象,查看osd

[root@ceph01 ~]# rados -p test2 put 1.txt /etc/hosts

# 发现有5个osd
[root@ceph01 ~]# ceph osd map test2 1.txt
osdmap e114 pool 'test2' (6) object '1.txt' -> pg 6.e0e3a40b (6.b) -> up ([1,3,0,4,7], p1) acting ([1,3,0,4,7], p1)

posted @ 2026-03-16 20:48  乔的港口  阅读(2)  评论(0)    收藏  举报