三、Ceph集群应用基础

1、块设备RBD基础应用

RBD(RADOS Block Devices)即为块存储的一种,RBD 通过 librbd 库与 OSD 进行交互,RBD为 KVM 等虚拟化技术和云服务(如 OpenStack 和 CloudStack)提供高性能和无限可扩展性的存储后端,这些系统依赖于 libvirt 和 QEMU 实用程序与 RBD 进行集成,客户端基于librbd 库即可将 RADOS 存储集群用作块设备,不过,用于 rbd 的存储池需要事先启用 rbd功能并进行初始化

1.1、创建RBD

# 创建存储池命令格式:
ceph osd pool create <poolname> pg_num pgp_num {replicated|erasure}

# 创建存储池
ceph osd pool create myrbd1 64 64  #创建存储池,指定pg和pgp的数量,pgp是对存在于pg的数据进行组合存储,pgp通常等于pg的值
pool 'myrbd1' created

# 对存储池启用RBD功能
cephadmin@ceph-deploy:~$ ceph osd pool application enable myrbd1 rbd
enabled application 'rbd' on pool 'myrbd1'

# 通过rbd命令对存储池初始化
 rbd pool init -p myrbd1

1.2、创建并验证img

不过,rbd 存储池并不能直接用于块设备,而是需要事先在其中按需创建映像(image),并把映像文件作为块设备使用,rbd 命令可用于创建、查看及删除块设备相在的映像(image),以及克隆映像、创建快照、将映像回滚到快照和查看快照等管理操作

# 下面的命令能够创建一个名为 myimg1的映像
cephadmin@ceph-deploy:~$ rbd create myimg1 --size 1G --pool myrbd1 --image-format 2 --image-feature layering
由于 centos 系统内核较低无法挂载使用,只能开启部分特性。这里以ubuntu客户端为例
除了 layering 其他特性需要高版本内核支持

# 列出指定pool中所有img
cephadmin@ceph-deploy:~$ rbd ls --pool myrbd1
myimg1

# 查看指定rbd的信息
cephadmin@ceph-deploy:~$ rbd --image myimg1 --pool myrbd1 info
rbd image 'myimg1':
	size 1 GiB in 256 objects
	order 22 (4 MiB objects)
	snapshot_count: 0
	id: d56f77b47719
	block_name_prefix: rbd_data.d56f77b47719
	format: 2
	features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
	op_features: 
	flags: 
	create_timestamp: Thu Mar 31 20:47:36 2022
	access_timestamp: Thu Mar 31 20:47:36 2022
	modify_timestamp: Thu Mar 31 20:47:36 2022

1.3、客户端使用块存储

1.3.1、当前ceph状态

cephadmin@ceph-deploy:~$ ceph df
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    120 GiB  120 GiB  278 MiB   278 MiB       0.23
TOTAL  120 GiB  120 GiB  278 MiB   278 MiB       0.23
 
--- POOLS ---
POOL                   ID  PGS   STORED  OBJECTS     USED  %USED  MAX AVAIL
device_health_metrics   1    1      0 B        0      0 B      0     38 GiB
mypool                  3   32      0 B        0      0 B      0     38 GiB
cephfs-metadata         4   32  3.6 KiB       41  168 KiB      0     38 GiB
cephfs-data             5   64      0 B        0      0 B      0     38 GiB
.rgw.root               6   32  1.3 KiB        4   48 KiB      0     38 GiB
default.rgw.log         7   32  3.6 KiB      177  408 KiB      0     38 GiB
default.rgw.control     8   32      0 B        8      0 B      0     38 GiB
default.rgw.meta        9    8      0 B        0      0 B      0     38 GiB
myrbd1                 10   64    133 B        5   36 KiB      0     38 GiB

1.3.2、在客户端安装ceph-common

root@ceph-client:~# apt install ceph-common

# 从部署服务器同步认证文件
cephadmin@ceph-deploy:~/ceph-cluster$ scp ceph.conf ceph.client.admin.keyring root@192.168.1.180:/etc/ceph

1.3.3、客户端映射img

root@ceph-client:~# rbd -p myrbd1 map myimg1
/dev/rbd0

1.3.4、客户端验证RBD

root@ceph-client:~# rbd -p myrbd1 map myimg1
/dev/rbd0
root@ceph-client:~# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   20G  0 disk 
└─sda1   8:1    0   20G  0 part /
sr0     11:0    1 1024M  0 rom  
rbd0   252:0    0    1G  0 disk
root@ceph-client:~#  fdisk -l /dev/rbd0
Disk /dev/rbd0: 1 GiB, 1073741824 bytes, 2097152 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4194304 bytes / 4194304 bytes

1.3.5、客户端格式化磁盘并挂载使用

root@ceph-client:~# mkfs.xfs /dev/rbd0 
meta-data=/dev/rbd0              isize=512    agcount=9, agsize=31744 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0, rmapbt=0, reflink=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=1024   swidth=1024 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=8 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
root@ceph-client:~# mkdir /data
root@ceph-client:~# mount /dev/rbd0 /data/
root@ceph-client:~# cp /etc/passwd /data/
root@ceph-client:~# df -hTP
Filesystem     Type      Size  Used Avail Use% Mounted on
udev           devtmpfs  462M     0  462M   0% /dev
tmpfs          tmpfs      99M  5.1M   94M   6% /run
/dev/sda1      ext4       20G  3.0G   16G  16% /
tmpfs          tmpfs     493M     0  493M   0% /dev/shm
tmpfs          tmpfs     5.0M     0  5.0M   0% /run/lock
tmpfs          tmpfs     493M     0  493M   0% /sys/fs/cgroup
tmpfs          tmpfs      99M     0   99M   0% /run/user/0
/dev/rbd0      xfs      1014M   34M  981M   4% /data
root@ceph-client:~# ll /data/
total 8
drwxr-xr-x  2 root root   20 Mar 31 21:06 ./
drwxr-xr-x 24 root root 4096 Mar 31 21:06 ../
-rw-r--r--  1 root root 1630 Mar 31 21:06 passwd

1.3.6、客户端验证

root@ceph-client:~# dd if=/dev/zero of=/data/ceph-test-file bs=1MB count=300
300+0 records in
300+0 records out
300000000 bytes (300 MB, 286 MiB) copied, 3.77551 s, 79.5 MB/s
root@ceph-client:~# file /data/ceph-test-file 
/data/ceph-test-file: data
root@ceph-client:~# ll -h /data/ceph-test-file 
-rw-r--r-- 1 root root 287M Mar 31 21:08 /data/ceph-test-file

1.4、ceph验证数据

2、Ceph-FS文件存储基本使用 

Ceph FS即ceph filesystem,可以实现文件系统共享功能,客户端通过ceph协议挂载并使用ceph集群作为数据存储服务器

Ceph FS 需要运行 Meta Data Services(MDS)服务,其守护进程为 ceph-mds,ceph-mds进程管理与 cephFS 上存储的文件相关的元数据,并协调对 ceph 存储集群的访问

2.1、创建CephFS metadata和data存储池:

使用 CephFS 之前需要事先于集群中创建一个文件系统,并为其分别指定元数据和数据相关的存储池,如下命令将创建名为 mycephfs 的文件系统,它使用 cephfs-metadata 作为元数据存储池,使用 cephfs-data 为数据存储池:

# 保存 metadata 的 pool
cephadmin@ceph-deploy:~/ceph-cluster$  ceph osd pool create cephfs-metadata 32 32
pool 'cephfs-metadata' created

# 保存数据的pool
cephadmin@ceph-deploy:~/ceph-cluster$  ceph osd pool create cephfs-data 64 64
pool 'cephfs-data' created

# ceph当前状态
cephadmin@ceph-deploy:~/ceph-cluster$ ceph -s
  cluster:
    id:     164ae280-496b-4272-8d79-04f94b9a3b5a
    health: HEALTH_OK
 
  services:
    mon: 3 daemons, quorum ceph-mon1,ceph-mon2,ceph-mon3 (age 3h)
    mgr: ceph-mgr2(active, since 3h), standbys: ceph-mgr1
    mds: 2/2 daemons up, 2 standby
    osd: 12 osds: 12 up (since 3h), 12 in (since 26h)
    rgw: 2 daemons active (2 hosts, 1 zones)
 
  data:
    volumes: 1/1 healthy
    pools:   9 pools, 297 pgs
    objects: 319 objects, 300 MiB
    usage:   1.2 GiB used, 119 GiB / 120 GiB avail
    pgs:     297 active+clean

2.2、创建cephfs并验证

cephadmin@ceph-deploy:~/ceph-cluster$ ceph fs new mycephfs cephfs-metadata cephfs-data
new fs with metadata pool 4 and data pool 5

# cephfs状态
cephadmin@ceph-deploy:~/ceph-cluster$ ceph fs status mycephfs
mycephfs - 0 clients
========
RANK  STATE      MDS        ACTIVITY     DNS    INOS   DIRS   CAPS  
 0    active  ceph-mds2  Reqs:    0 /s    10     13     12      0   
 1    active  ceph-mds1  Reqs:    0 /s    10     13     11      0   
      POOL         TYPE     USED  AVAIL  
cephfs-metadata  metadata   168k  37.4G  
  cephfs-data      data       0   37.4G  
STANDBY MDS  
 ceph-mgr2   
 ceph-mds3   
MDS version: ceph version 16.2.7 (dd0603118f56ab514f133c8d2e3adfc983942503) pacific (stable)

# cephfs服务状态
cephadmin@ceph-deploy:~/ceph-cluster$ ceph mds stat
mycephfs:2 {0=ceph-mds2=up:active,1=ceph-mds1=up:active} 2 up:standby

2.3、客户端挂载cephfs

# 客户端挂载,IP要写ceph-mon节点的IP
root@ceph-client:~# mount -t ceph 192.168.1.203:6789:/ /mnt -o name=admin,secret=AQBbNERiJXdhNxAAsveO40tjQ+su6h99LD/4vg==
root@ceph-client:~# df -hTP
Filesystem           Type      Size  Used Avail Use% Mounted on
udev                 devtmpfs  462M     0  462M   0% /dev
tmpfs                tmpfs      99M  5.1M   94M   6% /run
/dev/sda1            ext4       20G  3.0G   16G  16% /
tmpfs                tmpfs     493M     0  493M   0% /dev/shm
tmpfs                tmpfs     5.0M     0  5.0M   0% /run/lock
tmpfs                tmpfs     493M     0  493M   0% /sys/fs/cgroup
tmpfs                tmpfs      99M     0   99M   0% /run/user/0
/dev/rbd0            xfs      1014M  320M  695M  32% /data
192.168.1.203:6789:/ ceph       38G     0   38G   0% /mnt

# 测试数据写入
root@ceph-client:~# dd if=/dev/zero of=/mnt/ceph-fs-testfile bs=4M count=25
25+0 records in
25+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.28683 s, 366 MB/s
root@ceph-client:~# df -hTP
Filesystem           Type      Size  Used Avail Use% Mounted on
udev                 devtmpfs  462M     0  462M   0% /dev
tmpfs                tmpfs      99M  5.1M   94M   6% /run
/dev/sda1            ext4       20G  3.0G   16G  16% /
tmpfs                tmpfs     493M     0  493M   0% /dev/shm
tmpfs                tmpfs     5.0M     0  5.0M   0% /run/lock
tmpfs                tmpfs     493M     0  493M   0% /sys/fs/cgroup
tmpfs                tmpfs      99M     0   99M   0% /run/user/0
/dev/rbd0            xfs      1014M  320M  695M  32% /data
192.168.1.203:6789:/ ceph       38G  100M   38G   1% /mnt

验证ceph存储池数据空间

3、ceph集群维护 

3.1、ceph集群的停止或重启

重启之前,要提前设置 ceph 集群不要将 OSD 标记为 out,避免 node 节点关闭服务后被踢出ceph集群外:

# 关闭服务前设置noout
cephadmin@ceph-deploy:~$ ceph osd set noout
noout is set

# 启动服务后取消noout
cephadmin@ceph-deploy:~$ ceph osd unset noout
noout is unset

3.1.2、关闭顺序

#关闭服务前设置 noout
关闭存储客户端停止读写数据
如果使用了 RGW,关闭 RGW
关闭 cephfs 元数据服务
关闭 ceph OSD
关闭 ceph manager
关闭 ceph monitor

3.1.3、启动顺序

启动 ceph monitor
启动 ceph manager
启动 ceph OSD
关闭 cephfs 元数据服务
启动 RGW
启动存储客户端
#启动服务后取消 noout-->ceph osd unset noout

3.1.4、添加服务器

1.先配置仓库源

2. ceph-deploy install --release pacific ceph-nodex

3. 擦除磁盘
ceph-deploy disk zap ceph-nodex /dev/sdx

4.添加 osd:
sudo ceph-deploy osd create ceph-nodex --data /dev/sdx

3.1.5、删除服务器

停止服务器之前要把服务器的 OSD 先停止并从 ceph 集群删除

1 把 osd 踢出集群
ceph osd out 1

2.等一段时间

3.停止osd.x进程

4.删除osd
ceph osd rm 1

5.当前主机的其它磁盘重复以上操作

6.osd全部操作完成后下线主机

3.2、ceph配置文件

Ceph 的主配置文件是/etc/ceph/ceph.conf,ceph 服务在启动时会检查 cep.conf,分号;和#在配置文件中都是注释,ceph.conf 主要由以下配置段组成

[global] #全局配置
[osd] #osd 专用配置,可以使用 osd.N,来表示某一个 OSD 专用配置,N 为 osd 的编号,如 0、2、1 等。
[mon] #mon 专用配置,也可以使用 mon.A 来为某一个 monitor 节点做专用配置,其中 A为该节点的名称,ceph-monitor-2、ceph-monitor-1 等,使用命令 ceph mon dump 可以获取节点的名称
[client] #客户端专用配置。

ceph 文件的加载顺序:

$CEPH_CONF 环境变量
-c 指定的位置
/etc/ceph/ceph.conf
~/.ceph/ceph.conf
./ceph.conf

4、存储池、PG与CRUSH

存储池有两种类型:副本池和纠删码池

副本池(replicated):定义每个对象在集群中保存为多少个副本,默认为三个副本,一主两备,实现高可用,副本池是 ceph 默认的存储池类型。

纠删码池(erasure code): 把各对象存储为 N=K+M 个块,其中 K 为数据块数量,M 为编码快数量,因此存储池的尺寸为 K+M。

即数据保存在 K 个数据块,并提供 M 个冗余块提供数据高可用,那么最多能故障的块就是M 个,实际的磁盘占用就是 K+M 块,因此相比副本池机制比较节省存储资源,一般采用8+4 机制,即 8 个数据块+4 个冗余块,那么也就是 12 个数据块有 8 个数据块保存数据,有 4 个实现数据冗余,即 1/3 的磁盘空间用于数据冗余,比默认副本池的三倍冗余节省空间,但是不能出现大于一定数据块故障。
但是不是所有的应用都支持纠删码池,RBD 只支持副本池而 radosgw 则可以支持纠删码池。

4.1、副本池IO

将一个数据对象存储为多个副本

在客户端写入操作时,ceph使用CRUSH算法计算出与对象相对应的PG ID和primary OSD主 OSD 根据设置的副本数、对象名称、存储池名称和集群运行图(cluster map)计算出 PG的各辅助 OSD,然后由 OSD 将数据再同步给辅助 OSD

读取数据:
1. 客户端发送读请求,RADOS 将请求发送到主 OSD。
2. 主 OSD 从本地磁盘读取数据并返回数据,最终完成读请求。
写入数据:
1. 客户端 APP 请求写入数据,RADOS 发送数据到主 OSD。
2. 主 OSD 识别副本 OSDs,并发送数据到各副本 OSD。
3. 副本 OSDs 写入数据,并发送写入完成信号给主 OSD。
4. 主 OSD 发送写入完成信号给客户端 APP。

4.2、纠删码池IO

Ceph 从 Firefly 版本开始支持纠删码,但是不推荐在生产环境使用纠删码池。
纠删码池降低了数据保存所需要的磁盘总空间数量,但是读写数据的计算成本要比副本池高RGW 可以支持纠删码池,RBD 不支持
纠删码池可以降低企业的前期 TCO 总拥有成本

纠删码写:
数据将在主 OSD 进行编码然后分发到相应的 OSDs 上去。
1.计算合适的数据块并进行编码
2.对每个数据块进行编码并写入 OSD
#创建纠删码池
cephadmin@ceph-deploy:~$ ceph osd pool create erasure-testpool 16 16 erasure
pool 'erasure-testpool' created

cephadmin@ceph-deploy:~$ ceph osd erasure-code-profile get default
k=2      #k 为数据块的数量,即要将原始对象分割成的块数量,例如,如果 k = 2,则会将一个10kB 对象分割成各为 5kB 的 k 个对象
m=2     #编码块(chunk)的数量,即编码函数计算的额外块的数量。如果有 2 个编码块,则表示有两个额外的备份,最多可以从当前 pg 中宕机 2 个 OSD,而不会丢失数据
plugin=jerasure      #默认的纠删码池插件
technique=reed_sol_van 

# 写入数据
cephadmin@ceph-deploy:~$ sudo rados put -p erasure-testpool testfile1 /var/log/syslog

# 验证数据
cephadmin@ceph-deploy:~$ ceph osd map erasure-testpool testfile1
osdmap e294 pool 'erasure-testpool' (11) object 'testfile1' -> pg 11.3a643fcb (11.b) -> up ([2,4,8,11], p2) acting ([2,4,8,11], p2)

# 验证当前pg的状态
cephadmin@ceph-deploy:~$ ceph pg ls-by-pool erasure-testpool | awk '{print $1,$2,$15}'
PG OBJECTS ACTING
11.0 0 [1,4,10,8]p1
11.1 0 [10,6,2,3]p10
11.2 0 [2,6,10,5]p2
11.3 0 [6,11,4,0]p6
11.4 0 [5,9,1,6]p5
11.5 0 [11,5,1,8]p11
11.6 0 [10,1,7,5]p10
11.7 0 [5,1,9,7]p5
11.8 0 [6,0,3,11]p6
11.9 0 [2,10,8,3]p2
11.a 0 [7,3,2,11]p7
11.b 1 [2,4,8,11]p2
11.c 0 [9,2,3,6]p9
11.d 0 [2,3,6,10]p2
11.e 0 [7,9,3,2]p7
11.f 0 [3,6,9,0]p3
  
* NOTE: afterwards

# 测试获取数据
cephadmin@ceph-deploy:~$ rados --pool erasure-testpool get testfile1 -
纠删码读:
从相应的 OSDs 中获取数据后进行解码。
如果此时有数据丢失,Ceph 会自动从存放校验码的 OSD 中读取数据进行解码

4.3、PG与PGP

PG = Placement Group #归置组
PGP = Placement Group for Placement purpose #归置组的组合,pgp 相当于是 pg 对应osd 的一种排列组合关系。

归置组(placement group)是用于跨越多 OSD 将数据存储在每个存储池中的内部数据结构。
归置组在 OSD 守护进程和 ceph 客户端之间生成了一个中间层,CRUSH 算法负责将每个对象动态映射到一个归置组,然后再将每个归置组动态映射到一个或多个 OSD 守护进程,从而能够支持在新的 OSD 设备上线时进行数据重新平衡

相对于存储池来说,PG 是一个虚拟组件,它是对象映射到存储池时使用的虚拟层。

可以自定义存储池中的归置组数量。

ceph 出于规模伸缩及性能方面的考虑,ceph 将存储池细分为多个归置组,把每个单独的对象映射到归置组,并为归置组分配一个主 OSD。

存储池由一系列的归置组组成,而 CRUSH 算法则根据集群运行图和集群状态,将个 PG 均匀、伪随机(基于 hash 映射,每次的计算结果够一样)的分布到集群中的 OSD 之上。

如果某个 OSD 失败或需要对集群进行重新平衡,ceph 则移动或复制整个归置组而不需要单独对每个镜像进行寻址

4.4、PG与OSD的关系

ceph 基于 crush 算法将归置组 PG 分配至 OSD
当一个客户端存储对象的时候,CRUSH 算法映射每一个对象至归置组(PG)

4.5、PG分配计算

归置组(PG)的数量是由管理员在创建存储池的时候指定的,然后由 CRUSH 负责创建和使用,PG 的数量是 2 的 N 次方的倍数,每个 OSD 的 PG 不要超出 250 个 PG,官方是每个OSD 100个左右 

https://docs.ceph.com/en/mimic/rados/configuration/pool-pg-config-ref/

确保设置了合适的归置组大小,我们建议每个 OSD 大约 100 个,例如,osd 总数乘以 100除以副本数量(即 osd 池默认大小),因此,对于 10 个 osd、存储池为 4 个,我们建议每个存储池大约(100 * 10) / 4 = 256

1.通常,PG 的数量应该是数据的合理力度的子集。
例如:一个包含 256 个 PG 的存储池,每个 PG 中包含大约 1/256 的存储池数据
2.当需要将 PG 从一个 OSD 移动到另一个 OSD 的时候,PG 的数量会对性能产生影响。
  PG 的数量过少,一个 OSD 上保存的数据数据会相对加多,那么 ceph 同步数据的时候产
生的网络负载将对集群的性能输出产生一定影响。
  PG 过多的时候,ceph 将会占用过多的 CPU 和内存资源用于记录 PG 的状态信息
3.PG 的数量在集群分发数据和重新平衡时扮演者重要的角色作用
  在所有 OSD 之间进行数据持久存储以及完成数据分布会需要较多的归置组,但是他们的
数量应该减少到实现 ceph 最大性能所需的最小 PG 数量值,以节省 CPU 和内存资源。
  一般来说,对于有着超过 50 个 OSD 的 RADOS 集群,建议每个 OSD 大约有 50-100 个
PG 以平衡资源使用及取得更好的数据持久性和数据分布,而在更大的集群中,每个 OSD
可以有 100-200 个 PG
  至于一个 pool 应该使用多少个 PG,可以通过下面的公式计算后,将 pool 的 PG 值四舍
五入到最近的 2 的 N 次幂,如下先计算出 ceph 集群的总 PG 数:
  Total OSDs * PGPerOSD/replication factor => total PGs
  磁盘总数 x 每个磁盘 PG 数/副本数 => ceph 集群总 PG 数(略大于 2^n 次方)

  官方的计算公式:
  Total PGs = (Total_number_of_OSD * 100) / max_replication_count

单个 pool 的 PG 计算如下:
有 100 个 osd,3 副本,5 个 pool
Total PGs =100*100/3=3333
每个 pool 的 PG=3333/5=512,那么创建 pool 的时候就指定 pg 为 512

  需要结合数据数量、磁盘数量及磁盘空间计算出 PG 数量,8、16、32、64、128、256
等 2 的 N 次方。
  一个 RADOS 集群上会存在多个存储池,因此管理员还需要考虑所有存储池上的 PG 分布
后每个 OSD 需要映射的 PG 数量。
$ ceph osd pool create testpoo2 60 60
pool 'testpoo2' created
$ ceph osd pool create testpoo3 40 30
pool 'testpoo3' created
$ ceph osd pool create testpoo4 45 45
pool 'testpoo4' created

ceph 的 pg 数量推荐是 2 的整次幂,比如 2 的平方叫二次幂,立方叫三次幂,幂的大小是整数,如果不是 2 的整次方会有提示:

5、PG的状态 

PG常见的状态如下:

5.1、Peering

正在同步状态,同一个 PG 中的 OSD 需要将准备数据同步一致,而 Peering(对等)就是 OSD同步过程中的状态。

5.2、Activating

Peering 已经完成,PG 正在等待所有 PG 实例同步 Peering 的结果(Info、Log 等)

5.3、Clean

干净态,PG 当前不存在待修复的对象,并且大小等于存储池的副本数,即 PG 的活动集(Acting Set)和上行集(Up Set)为同一组 OSD 且内容一致
活动集(Acting Set):由 PG 当前主的 OSD 和其余处于活动状态的备用 OSD 组成,当前 PG内的 OSD 负责处理用户的读写请求
上行集(Up Set):在某一个 OSD 故障时,需要将故障的 OSD 更换为可用的 OSD,并主 PG内部的主 OSD 同步数据到新的 OSD 上,例如 PG 内有 OSD1、OSD2、OSD3,当 OSD3故障后需要用 OSD4 替换 OSD3,那么 OSD1、OSD2、OSD3 就是上行集,替换后 OSD1、OSD2、OSD4 就是活动集,OSD 替换完成后活动集最终要替换上行集

5.4、Active

就绪状态或活跃状态,Active 表示主 OSD 和备 OSD 处于正常工作状态,此时的 PG 可以正常处理来自客户端的读写请求,正常的 PG 默认就是 Active+Clean 状态

cephadmin@ceph-deploy:~$ ceph pg stat
313 pgs: 313 active+clean; 401 MiB data, 1.4 GiB used, 119 GiB / 120 GiB avail; 36 KiB/s rd, 0 B/s wr, 59 op/s

5.5、Degraded: 降级状态

降级状态出现于 OSD 被标记为 down 以后,那么其他映射到此 OSD 的 PG 都会转换到降级状态。
如果此 OSD 还能重新启动完成并完成 Peering 操作后,那么使用此 OSD 的 PG 将重新恢复为 clean 状态。
如果此 OSD 被标记为 down 的时间超过 5 分钟还没有修复,那么此 OSD 将会被 ceph 踢出集群,然后 ceph 会对被降级的 PG 启动恢复操作,直到所有由于此 OSD 而被降级的 PG重新恢复为 clean 状态。
恢复数据会从 PG 内的主 OSD 恢复,如果是主 OSD 故障,那么会在剩下的两个备用 OSD重新选择一个作为主 OSD

5.6、Stale: 过期状态

正常状态下,每个主OSD都要周期性的向RADOS集群中的监视器(Mon)报告其作为主OSD所持有的所有 PG 的最新统计数据,因任何原因导致某个 OSD 无法正常向监视器发送汇报信息的、或者由其他 OSD 报告某个 OSD 已经 down 的时候,则所有以此 OSD 为主 PG 则会立即被标记为 stale 状态,即他们的主 OSD 已经不是最新的数据了,如果是备份的 OSD发送 down 的时候,则 ceph 会执行修复而不会触发 PG 状态转换为 stale 状态。

5.7、undersized

PG 当前副本数小于其存储池定义的值的时候,PG 会转换为 undersized 状态,比如两个备份 OSD 都 down 了,那么此时 PG 中就只有一个主 OSD 了,不符合 ceph 最少要求一个主 OSD 加一个备 OSD 的要求,那么就会导致使用此 OSD 的 PG 转换为 undersized 状态,直到添加备份 OSD 添加完成,或者修复完成

5.8、Scrubbing

scrub 是 ceph 对数据的清洗状态,用来保证数据完整性的机制,Ceph 的 OSD 定期启动 scrub 线程来扫描部分对象,通过与其他副本比对来发现是否一致,如果存在不一致,抛出异常提示用户手动解决,scrub 以 PG 为单位,对于每一个 pg,ceph 分析该 pg 下所有的 object, 产生一个类似于元数据信息摘要的数据结构,如对象大小,属性等,叫 scrubmap,比较主与副 scrubmap,来保证是不是有 object 丢失或者不匹配,扫描分为轻量级扫描和深度扫描,轻量级扫描也叫做 light scrubs 或者 shallow scrubs 或者 simply scrubs 即轻量级扫描

Light scrub(daily)比较 object size 和属性,deep scrub (weekly)读取数据部分并通过checksum(CRC32算法)对比和数据的一致性, 深度扫描过程中的PG会处于scrubbing+deep 状态。

5.9、Recovering

正在恢复态,集群正在执行迁移或同步对象和他们的副本,这可能是由于添加了一个新的OSD 到集群中或者某个 OSD 宕掉后,PG 可能会被 CRUSH 算法重新分配不同的 OSD,而由于 OSD 更换导致 PG 发生内部数据同步的过程中的 PG 会被标记为 Recovering

5.10、Backfilling

正在后台填充态,backfill 是 recovery 的一种特殊场景,指 peering 完成后,如果基于当前权威日志无法对 Up Set(上行集)当中的某些 PG 实例实施增量同步(例如承载这些 PG 实例的 OSD 离线太久,或者是新的 OSD 加入集群导致的 PG 实例整体迁移) 则通过完全拷贝当前 Primary 所有对象的方式进行全量同步,此过程中的 PG 会处于 backfilling

5.11、Backfill-toofull

某个需要被 Backfill 的 PG 实例,其所在的 OSD 可用空间不足,Backfill 流程当前被挂起时PG 给的状态

6、存储池的操作

存储池的管理通常保存创建、列出、重命名和删除等操作,管理工具使用 ceph osd pool的子命令及参数,比如 create/ls/rename/rm 等
http://docs.ceph.org.cn/rados/ #ceph 官方运维手册

6.1、常用命令

# 创建存储池命令格式:
$ceph osd pool create <poolname> pg_num pgp_num {replicated|erasure}

# 列出存储池:
[ceph@ceph-deploy ceph-cluster]$ ceph osd pool ls [detail] #不带 pool ID
mypool
myrdb1
.rgw.root
default.rgw.control
default.rgw.meta
default.rgw.log
cephfs-metadata
cephfs-data

# 带 pool ID
[ceph@ceph-deploy ceph-cluster]$ ceph osd lspools 
1 mypool
2 myrdb1
3 .rgw.root
4 default.rgw.control
5 default.rgw.meta
6 default.rgw.log
7 cephfs-metadata
8 cephfs-data

# 获取存储池的事件信息:
[ceph@ceph-deploy ceph-cluster]$ ceph osd pool stats mypool
pool mypool id 1
nothing is going on

# 重命名存储池:
$ ceph osd pool rename old-name new-name
$ ceph osd pool rename myrbd1 myrbd2

# 显示存储池的用量信息:
cephadmin@ceph-deploy:~$ rados df
POOL_NAME                 USED  OBJECTS  CLONES  COPIES  MISSING_ON_PRIMARY  UNFOUND  DEGRADED  RD_OPS       RD  WR_OPS       WR  USED COMPR  UNDER COMPR
.rgw.root               48 KiB        4       0      12                   0        0         0      31   31 KiB       4    4 KiB         0 B          0 B
cephfs-data            301 MiB       26       0      78                   0        0         0       0      0 B      27  100 MiB         0 B          0 B
cephfs-metadata        312 KiB       41       0     123                   0        0         0     235  272 KiB     135   80 KiB         0 B          0 B
default.rgw.control        0 B        8       0      24                   0        0         0       0      0 B       0      0 B         0 B          0 B
default.rgw.log        408 KiB      177       0     531                   0        0         0   27805   27 MiB   18281   34 KiB         0 B          0 B
default.rgw.meta           0 B        0       0       0                   0        0         0       0      0 B       0      0 B         0 B          0 B
device_health_metrics      0 B       12       0      36                   0        0         0       0      0 B      12   12 KiB         0 B          0 B
erasure-testpool       1.2 MiB        1       0       4                   0        0         0       4  2.4 MiB       1  626 KiB         0 B          0 B
mypool                     0 B        0       0       0                   0        0         0       2  536 KiB       3  536 KiB         0 B          0 B
myrbd1                 890 MiB       89       0     267                   0        0         0     384  2.6 MiB     324  299 MiB         0 B          0 B

total_objects    358
total_used       1.4 GiB
total_avail      119 GiB
total_space      120 GiB

6.2、存储池的删除

如果把存储池删除会导致把存储池内的数据全部删除,因此 ceph 为了防止误删除存储池设置了两个机制来防止误删除操作。
第一个机制是 NODELETE 标志,需要设置为 false 但是默认就是 false 了。

# 创建一个测试 pool
$ ceph osd pool create mypool2 32 32
pool 'mypool2' created 

$ ceph osd pool get mypool2 nodelete
nodelete: false

如果设置为了 true 就表示不能删除,可以使用 set 指令重新设置为 fasle
[ceph@ceph-deploy ceph-cluster]$ ceph osd pool set mypool2 nodelete true
set pool 9 nodelete to true

[ceph@ceph-deploy ceph-cluster]$ ceph osd pool set mypool2 nodelete false
set pool 9 nodelete to false

[ceph@ceph-deploy ceph-cluster]$ ceph osd pool get mypool2 nodelete
nodelete: false

第二个机制是集群范围的配置参数 mon allow pool delete,默认值为 false,即监视器不允删除存储池,可以在特定场合使用 tell 指令临时设置为(true)允许删除,在删除指定的 pool之后再重新设置为 false

$ ceph tell mon.* injectargs --mon-allow-pool-delete=true
mon.ceph-mon1: injectargs:mon_allow_pool_delete = 'true'
mon.ceph-mon2: injectargs:mon_allow_pool_delete = 'true'
mon.ceph-mon3: injectargs:mon_allow_pool_delete = 'true'

$ ceph osd pool rm mypool2 mypool2 --yes-i-really-really-mean-it
pool 'mypool2' removed

$ ceph tell mon.* injectargs --mon-allow-pool-delete=false
mon.ceph-mon1: injectargs:mon_allow_pool_delete = 'false'
mon.ceph-mon2: injectargs:mon_allow_pool_delete = 'false'
mon.ceph-mon3: injectargs:mon_allow_pool_delete = 'false

6.3、存储池的配额

存储池可以设置两个配对存储的对象进行限制,一个配额是最大空间(max_bytes),另外一个配额是对象最大数量(max_objects)

$ ceph osd pool get-quota mypool
quotas for pool 'mypool':
max objects: N/A #默认不限制对象数量
max bytes : N/A #默认不限制空间大小

$ ceph osd pool set-quota mypool max_objects 1000 #限制最大 1000 个对象
set-quota max_objects = 1000 for pool mypool

[ceph@ceph-deploy ceph-cluster]$ ceph osd pool set-quota mypool max_objects
1000
set-quota max_objects = 1000 for pool mypool #限制最多 1000 个对象

[ceph@ceph-deploy ceph-cluster]$ ceph osd pool set-quota mypool max_bytes
10737418240 #限制最大 10737418240 字节
set-quota max_bytes = 10737418240 for pool mypool

[ceph@ceph-deploy ceph-cluster]$ ceph osd pool get-quota mypool
quotas for pool 'mypool':
max objects: 1 k objects #最多 1000 对象
max bytes : 10 GiB #最大 10G 空间

6.4、存储池可用参数

size:存储池中的对象副本数,默认一主两个备 3 副本。
$ ceph osd pool get mypool size
size: 3

$ ceph osd pool get mypool min_size
min_size: 2

min_size:提供服务所需要的最小副本数,如果定义 size 为 3,min_size 也为 3,坏掉一个OSD,如果 pool 池中有副本在此块 OSD 上面,那么此 pool 将不提供服务,如果将 min_size定义为 2,那么还可以提供服务,如果提供为 1,表示只要有一块副本都提供服务。

pg_num:查看当前 PG 的数量
$ ceph osd pool get mypool pg_num
pg_num: 32

crush_rule:设置 crush 算法规则
$ ceph osd pool get mypool crush_rule
crush_rule: replicated_rule #默认为副本池

nodelete:控制是否可删除,默认可以
$ ceph osd pool get mypool nodelete
nodelete: false

nopgchange:控制是否可更改存储池的 pg num 和 pgp num
$ ceph osd pool get mypool nopgchange
nopgchange: false

$ ceph osd pool set mypool pg_num 64 #修改指定 pool 的 pg 数量
set pool 1 pg_num to 64

nosizechange:控制是否可以更改存储池的大小
$ ceph osd pool get mypool nosizechange
nosizechange: false #默认允许修改存储池大小

$ ceph osd pool get-quota mypool
quotas for pool 'mypool':
max objects: 1 k objects
max bytes : 10 GiB

$ ceph osd pool set-quota mypool max_bytes 21474836480
set-quota max_bytes = 21474836480 for pool mypool

$ ceph osd pool set-quota mypool max_objects 1000
set-quota max_objects = 1000 for pool mypool

$ ceph osd pool get-quota mypool
quotas for pool 'mypool':
max objects: 1 k objects
max bytes : 20 GiB

noscrub 和 nodeep-scrub:控制是否不进行轻量扫描或是否深层扫描存储池,可临时解决
高 I/O 问题
$ ceph osd pool get mypool noscrub
noscrub: false #查看当前是否关闭轻量扫描数据,默认为不关闭,即开启

$ ceph osd pool set mypool noscrub true
set pool 1 noscrub to true #可以修改某个指定的 pool 的轻量级扫描测量为 true,即不执
行轻量级扫描

$ ceph osd pool get mypool noscrub
noscrub: true #再次查看就不进行轻量级扫描了

$ ceph osd pool get mypool nodeep-scrub
nodeep-scrub: false #查看当前是否关闭深度扫描数据,默认为不关闭,即开启

$ ceph osd pool set mypool nodeep-scrub true
set pool 1 nodeep-scrub to true #可以修改某个指定的 pool 的深度扫描测量为 true,即不执行深度扫描

$ ceph osd pool get mypool nodeep-scrub
nodeep-scrub: true #再次查看就不执行深度扫描了

scrub_min_interval:集群存储池的最小清理时间间隔,默认值没有设置,可以通过配置文
件中的 osd_scrub_min_interval 参数指定间隔时间。
$ ceph osd pool get mypool scrub_min_interval
Error ENOENT: option 'scrub_min_interval' is not set on pool 'mypool'

scrub_max_interval:整理存储池的最大清理时间间隔,默认值没有设置,可以通过配置文
件中的 osd_scrub_max_interval 参数指定。
$ ceph osd pool get mypool scrub_max_interval
Error ENOENT: option 'scrub_max_interval' is not set on pool 'mypool'

deep_scrub_interval:深层整理存储池的时间间隔,默认值没有设置,可以通过配置文件中
的 osd_deep_scrub_interval 参数指定。
$ ceph osd pool get mypool deep_scrub_interval
Error ENOENT: option 'deep_scrub_interval' is not set on pool 'mypool'

#ceph node 的默认配置:
[root@ceph-node1 ~]# ll /var/run/ceph/
total 0
srwxr-xr-x 1 ceph ceph 0 Nov 3 12:22 ceph-osd.3.asok
srwxr-xr-x 1 ceph ceph 0 Nov 3 12:22 ceph-osd.6.asok
srwxr-xr-x 1 ceph ceph 0 Nov 3 12:23 ceph-osd.9.asok

[root@ceph-node1 ~]# ceph daemon osd.3 config show | grep scrub
"mds_max_scrub_ops_in_progress": "5",
"mon_scrub_inject_crc_mismatch": "0.000000",
"mon_scrub_inject_missing_keys": "0.000000",
"mon_scrub_interval": "86400",
"mon_scrub_max_keys": "100",
"mon_scrub_timeout": "300",
"mon_warn_not_deep_scrubbed": "0",
"mon_warn_not_scrubbed": "0",
"osd_debug_deep_scrub_sleep": "0.000000",
"osd_deep_scrub_interval": "604800.000000", #定义深度清洗间隔,604800 秒=7天
"osd_deep_scrub_keys": "1024",
"osd_deep_scrub_large_omap_object_key_threshold": "200000",
"osd_deep_scrub_large_omap_object_value_sum_threshold": "1073741824",
"osd_deep_scrub_randomize_ratio": "0.150000",
"osd_deep_scrub_stride": "524288",
"osd_deep_scrub_update_digest_min_age": "7200",
"osd_max_scrubs": "1", #定义一个 ceph OSD daemon 内能够同时进行 scrubbing的操作数
"osd_op_queue_mclock_scrub_lim": "0.001000",
"osd_op_queue_mclock_scrub_res": "0.000000",
"osd_op_queue_mclock_scrub_wgt": "1.000000",
"osd_requested_scrub_priority": "120",
"osd_scrub_auto_repair": "false",
"osd_scrub_auto_repair_num_errors": "5",
"osd_scrub_backoff_ratio": "0.660000",
"osd_scrub_begin_hour": "0",
"osd_scrub_begin_week_day": "0",
"osd_scrub_chunk_max": "25",
"osd_scrub_chunk_min": "5",
"osd_scrub_cost": "52428800",
"osd_scrub_during_recovery": "false",
"osd_scrub_end_hour": "24",
"osd_scrub_end_week_day": "7",
"osd_scrub_interval_randomize_ratio": "0.500000",
"osd_scrub_invalid_stats": "true", #定义 scrub 是否有效
"osd_scrub_load_threshold": "0.500000",
"osd_scrub_max_interval": "604800.000000", #定义最大执行 scrub 间隔,604800秒=7 天
"osd_scrub_max_preemptions": "5",
"osd_scrub_min_interval": "86400.000000", #定义最小执行普通 scrub 间隔,86400秒=1 天
"osd_scrub_priority": "5",
"osd_scrub_sleep": "0.000000",

7、存储池快照

快照用于读存储池中的数据进行备份与还原,创建快照需要占用的磁盘空间会比较大,取决于存储池中的数据大小,使用以下命令创建快照

7.1、创建快照

$ ceph osd pool ls

#命令 1:ceph osd pool mksnap {pool-name} {snap-name}
$ ceph osd pool mksnap mypool mypool-snap
created pool mypool snap mypool-snap

#命令 2: rados -p {pool-name} mksnap {snap-name}
$ rados -p mypool mksnap mypool-snap2
created pool mypool snap mypool-snap2

7.2、验证快照

$ rados lssnap -p mypool
1 mypool-snap 2020.11.03 16:12:56
2 mypool-snap2 2020.11.03 16:13:40
2 snaps

7.3、快照回滚

测试上传文件后创建快照,然后删除文件再还原文件,基于对象还原。
rados rollback <obj-name> <snap-name> roll back object to snap <snap-name>

#上传文件
[ceph@ceph-deploy ceph-cluster]$ rados -p mypool put testfile /etc/hosts

#验证文件
[ceph@ceph-deploy ceph-cluster]$ rados -p mypool ls
msg1
testfile
my.conf

# 创建快照
[ceph@ceph-deploy ceph-cluster]$ ceph osd pool mksnap mypool mypool-snapshot001
created pool mypool snap mypool-snapshot001

#验证快照
[ceph@ceph-deploy ceph-cluster]$ rados lssnap -p mypool
3 mypool-snap 2020.11.04 14:11:41
4 mypool-snap2 2020.11.04 14:11:49
5 mypool-conf-bak 2020.11.04 14:18:41
6 mypool-snapshot001 2020.11.04 14:38:50
4 snaps

#删除文件
[ceph@ceph-deploy ceph-cluster]$ rados -p mypool rm testfile

#删除文件后,无法再次删除文件,提升文件不存在
[ceph@ceph-deploy ceph-cluster]$ rados -p mypool rm testfile
error removing mypool>testfile: (2) No such file or directory

#通过快照还原某个文件
[ceph@ceph-deploy ceph-cluster]$ rados rollback -p mypool testfile mypool-snapshot001
rolled back pool mypool to snapshot mypool-snapshot001

#再次执行删除就可以执行成功
[ceph@ceph-deploy ceph-cluster]$ rados -p mypool rm testfile

7.4、删除快照

ceph osd pool rmsnap <poolname> <snap>
[ceph@ceph-deploy ceph-cluster]$ rados lssnap -p mypool
3 mypool-snap 2020.11.04 14:11:41
4 mypool-snap2 2020.11.04 14:11:49
5 mypool-conf-bak 2020.11.04 14:18:41
6 mypool-snapshot001 2020.11.04 14:38:50
4 snaps

[ceph@ceph-deploy ceph-cluster]$ ceph osd pool rmsnap mypool mypool-snap
removed pool mypool snap mypool-snap

[ceph@ceph-deploy ceph-cluster]$ rados lssnap -p mypool
4 mypool-snap2 2020.11.04 14:11:49
5 mypool-conf-bak 2020.11.04 14:18:41
6 mypool-snapshot001 2020.11.04 14:38:50
3 snaps

8、数据压缩

如果使用 bulestore 存储引擎,ceph 支持称为”实时数据压缩”即边压缩边保存数据的功能,该功能有助于节省磁盘空间,可以在 BlueStore OSD 上创建的每个 Ceph 池上启用或禁用压缩,以节约磁盘空间,默认没有开启压缩,需要后期配置并开启

8.1、启用压缩并指定压缩算法

ceph osd pool set <pool name> compression_algorithm snappy #默认算法为 snappy

snappy:该配置为指定压缩使用的算法默认为 sanppy,还有 none、zlib、lz4、zstd 和 snappy等算法,zstd 压缩比好,但消耗 CPU,lz4 和 snappy 对 CPU 占用较低,不建议使用 zlib

8.2、指定压缩模式

$ ceph osd pool set <pool name> compression_mode aggressive
aggressive:压缩的模式,有 none、aggressive、passive 和 force,默认 none。
none:从不压缩数据。
passive:除非写操作具有可压缩的提示集,否则不要压缩数据。
aggressive:压缩数据,除非写操作具有不可压缩的提示集。
force:无论如何都尝试压缩数据,即使客户端暗示数据不可压缩也会压缩,也就是在所有
情况下都使用压缩。


存储池压缩设置参数:
compression_algorithm #压缩算法
compression_mode #压缩模式
compression_required_ratio #压缩后与压缩前的压缩比,默认为.875
compression_max_blob_size:
#大于此的块在被压缩之前被分解成更小的blob(块),此设置将覆盖bluestore压缩max blob*的全局设置。
compression_min_blob_size:#小于此的块不压缩, 此设置将覆盖 bluestore 压缩 min blob*的全局设置。


全局压缩选项,这些可以配置到 ceph.conf 配置文件,作用于所有存储池:
bluestore_compression_algorithm #压缩算法
bluestore_compression_mode #压缩模式
bluestore_compression_required_ratio #压缩后与压缩前的压缩比,默认为.875
bluestore_compression_min_blob_size #小于它的块不会被压缩,默认 0
bluestore_compression_max_blob_size #大于它的块在压缩前会被拆成更小的块,默认 0
bluestore_compression_min_blob_size_ssd #默认 8k
bluestore_compression_max_blob_size_ssd 默认 64k
bluestore_compression_min_blob_size_hdd #默认 128k
bluestore_compression_max_blob_size_hdd #默认 512k


到 node 节点验证:
[root@ceph-node3 ~]# ceph daemon osd.11 config show | grep compression

#修改压缩算法
[ceph@ceph-deploy ~]$ ceph osd pool set mypool compression_algorithm snappy
set pool 2 compression_algorithm to snappy

[ceph@ceph-deploy ~]$ ceph osd pool get mypool compression_algorithm
compression_algorithm: snappy

#修改压缩模式:
[ceph@ceph-deploy ~]$ ceph osd pool set mypool compression_mode passive
set pool 2 compression_mode to passive

[ceph@ceph-deploy ~]$ ceph osd pool get mypool compression_mode
compression_mode: passive

  

 

posted @ 2022-04-01 12:39  zhrx  阅读(300)  评论(0编辑  收藏  举报