pre-split-filestore-diir-when-create-pool

背景

使用filestore的ceph是将最终的object存在带文件系统的磁盘上的,这样就有一个单目录下文件数的问题需要处理:在文件系统场景下,目录下的文件数过大会影响在操作该目录下文件的性能。

因此ceph针对这个提出了split和merge的概念来应对,即当一个pg下的object数超过设置的阈值的时候,执行split操作:

  • 在pg的根目录下新建一定数量的子目录
  • 将根目录下的所有object根据一定规则移动到上述新建的子目录中
  • pg执行分裂期间是会block对该pg的操作请求的

从上述过程很容易知道在分裂期间,集群的性能是会大打折扣的,我在实际场景下就碰到过很多次这种情况,一旦分裂期间client端也有比较大负载的时候会有大量的slow request出现,这样业务会有明显的性能降低感知,甚至直接导致业务超时。对此我们还专门做了告警,一旦检测到有pg开始分裂,我们会格外关注这个集群,同时跟业务做好沟通,能迁移的先迁移部分负载,不能迁移的调大超时时间。

另外一个merge其实就是split的逆过程,也就是当object低于阈值时,回收子目录,object转移到上一级数据目录。

对策

其实早在4年前就有人提到这个问题,当时Sage也有提到响应的解决方法,详情见:Disk saturation during PG folder splitting

主要的解决办法其实也很明确:提前分裂,一旦分裂即使object数下降也不执行merge。

至于这个解决方案,社区有两种方法:(两种方法都需要的前提条件:设置filestore merge threshold为一个负数,即不合并)

  1. 手动为某一个osd执行分裂,使用工具ceph-objectstore-tool,找到一个issue见:https://tracker.ceph.com/issues/21366
  2. 在新建pool的时候添加一个参数expected_num_objects,该pool所有相关的osd按照这个object总数去预先执行split

但是兜兜转转的,一直没能真正实现,我是直到jewel的10.2.11和Luminous的12.2.7才实现上面的第二种方法:建pool时提前分裂。(中间有些小版本没测试,看官方的release,在Luminous12.2.5已经修复这个问题:pool create cmd’s expected_num_objects is not correctly interpreted

实际测试

  • 在global段设置如下参数:
1
filestore merge threshold = -10
  • 重启所有服务:重启mon和osd服务
  • 执行新建pool的命令,添加预期的object总数,我设置的是3亿,请根据实际修改
1
ceph osd pool create .rgw.buckets.data 16384 16384 replicated site1_sata_replicated_ruleset 300000000
  • 查看效果
1
2
3
4
5
6
root@cld-osd1-48:/home/ceph/var/lib/osd/ceph-0/current/49.111b_head# ls DIR_B/DIR_1/DIR_1/
DIR_1 DIR_5 DIR_9 DIR_D
root@cld-osd1-48:/home/ceph/var/lib/osd/ceph-0/current/49.111b_head# ls DIR_B/DIR_1/DIR_1/DIR_1/
DIR_0 DIR_1 DIR_2 DIR_3 DIR_4 DIR_5 DIR_6 DIR_7 DIR_8 DIR_9 DIR_A DIR_B DIR_C DIR_D DIR_E DIR_F
root@cld-osd1-48:/home/ceph/var/lib/osd/ceph-0/current/49.111b_head# ls DIR_B/DIR_1/DIR_1/DIR_1/DIR_1/
root@cld-osd1-48:/home/ceph/var/lib/osd/ceph-0/current/49.111b_head#

其他问题

  1. 如果pg设置过小的话,很容易出现split,因为这意味着单pg下需要承载的object会更多,但是也不能为了防止分裂,将pg数设置过高。
  2. ceph-objectstore-tool工具看起来是只能修改一个osd的分裂,没有继续测试是否生效
  3. 碰到过偶发性的,部分osd分裂不完全,即一部分已经移到pg子目录了,一部分还是pg根目录,这时性能大大降低,该osd上会有大量的slow request。
  4. 从L版开始这个问题看起来就不存在了,因为是使用裸设备直接存取。

个人浅见,不准确的地方欢迎指正。

using-libvirt-create-vm-combine-rbd

前情提要

在一台没有桌面环境的远程服务器上需要新建虚拟机测试ceph,中间涉及桥接网络的配置、使用ISO镜像安装系统的xml文件、

操作流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 确保qemu,libvirt相关的包已经安装,

## 一步,准备iso镜像,准备硬盘
qemu-img create -f raw debian9.4Template.raw 2G

# 第二步,配置桥接网络
## ---------注意:一旦将某一个网口绑定到桥接网卡,这个口的IP将失效,
## ---------直到IP信息下沉到桥接网卡,下属操作使用其他网卡连接后执行-----------
## 新建br0,再查询桥接网络
root@test-vm:~# brctl addbr br0
root@test-vm:~# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000000000000 no
## 绑定网口
root@test-vm:~# brctl addif bond1
## 查询br0信息
root@test-vm:/home/zhoulin/vmxml# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.fe5400b23c01 no vnet0
## 激活br0
ifconfig br0 up
ip link set br0 up
## 将IP信息下沉到br0
ip addr del 192.168.1.198/24 dev bond1
ip addr add 192.168.1.198/24 dev br0
ip route add default via 192.168.1.254 #route add default gw 192.168.1.254
## -----注意:上述所有动作都在当前环境有效,配置都没有固化的,一旦重启就全部失效-------

# 第三步,使用最后附件的最精简xml新建虚拟机
virsh create debian9.4Template.xml

# 第四步,查询vnc端口,使用vnc连接,安装系统,然后测试网络,登入后做好配置,删除网卡udev信息,删除网络配置信息,删除虚拟机,作为镜像
netstat -tlp|grep qemu
virsh destroy debian9.4Template

# 第五步,根据上一步制作的模板生成新虚拟机磁盘文件
## 这里参考CeTune给的方法直接在本地挂载复制出来的盘,直接修改配置,实现新建虚拟机后即可用。
## 查看磁盘文件的分区结构
root@test-vm:~# fdisk -lu test-vm.img
Disk test-vm.img: 2.5 GiB, 2684354560 bytes, 5242880 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0009a368

Device Boot Start End Sectors Size Id Type
debian9.4Template1 * 2048 5240831 5238784 2.5G 83 Linux
##由上可知,真实的磁盘文件数据是从 (2048*512) 开始的,跳过前面这部分挂载到本地
root@test-vm:~# mount -o loop,offset=1048576 debian9.4Template.raw /mnt
##此时可以安心做任何文件级别的修改了,比如主机名、网络配置
root@test-vm:~# echo ${hostname} > /mnt/etc/hostname
root@test-vm:~# echo "auto eth0" >> /mnt/etc/network/interfaces
root@test-vm:~# echo "iface eth0 inet static" >> /mnt/etc/network/interfaces
root@test-vm:~# echo "address "${ip} >> /mnt/etc/network/interfaces
root@test-vm:~# echo "netmask 255.255.255.0" >> /mnt/etc/network/interfaces
root@test-vm:~# echo "gateway 10.200.53.254" >> /mnt/etc/network/interfaces

# 第六步,libvirt对接ceph
ceph auth get-or-create client.admin mon 'allow *' osd 'allow *' -o /etc/ceph/ceph.client.admin.keyring
keyring=`cat /etc/ceph/ceph.client.admin.keyring | grep key | awk '{print $3}'`
ceph_cluster_uuid=`ceph -s | grep cluster | awk '{print $2}'`
echo "<secret ephemeral='no' private='no'>" > secret.xml
echo " <uuid>$ceph_cluster_uuid</uuid>" >> secret.xml
echo " <usage type='ceph'>" >> secret.xml
echo " <name>client.admin secret</name>" >> secret.xml
echo " </usage>" >> secret.xml
echo "</secret>" >> secret.xml
virsh secret-define --file secret.xml
virsh secret-set-value $ceph_cluster_uuid $keyring

# 第七步,生成新虚拟机的xml文件
## 在附件xml文件的基础上作如下修改:
## 1.mac地址
## 2.mem,cpu根据需要修改
## 3.去掉 <boot dev="cdrom"/>
## 4.去掉有关cdrom部分,即<disk type='file' device='cdrom'>部分
## 5.添加ceph rbd块作为其中一个disk,xml部分间附件2

附件

附件1:libvirt新建开机自动iso安装系统最精简的xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<domain type="kvm">
<name>test-vm</name>
<memory>524288</memory>
<vcpu>1</vcpu>
<cputune>
<vcpupin vcpu="0" cpuset="1"/>
</cputune>
<os>
<type>hvm</type>
<boot dev="cdrom"/>
<boot dev="hd"/>
</os>
<features>
<acpi/>
</features>
<clock offset="utc">
<timer name="pit" tickpolicy="delay"/>
<timer name="rtc" tickpolicy="catchup"/>
</clock>
<cpu mode="host-model" match="exact"/>
<devices>
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" cache="none"/>
<source file="/home/zhoulin/vmxml/vm1.i.nease.net.qcow2" />
<target bus="virtio" dev="vda"/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/debian-9.4.0-amd64-xfce-CD-1.iso'/>
<target dev='hdb' bus='ide'/>
<readonly/>
</disk>
<interface type="bridge" >
<source bridge ="br0"/>
<mac address ="52:54:00:b2:3c:01"/>
</interface>
<serial type="pty"/>
<input type="tablet" bus="usb"/>
<graphics type="vnc" autoport="yes" keymap="en-us" listen="0.0.0.0"/>
</devices>
</domain>

附件2:vm添加rbd作为硬盘的xml

1
2
3
4
5
6
7
8
<disk type='network' device='disk'>
<driver name='qemu' type='raw' cache='none'/>
<auth username='admin'>
<secret type='ceph' uuid='${ceph_uuid}'/>
</auth>
<source protocol='rbd' name='${pool_name}/${rbd_name}' />
<target dev='vdb' bus='virtio'/>
</disk>

其他问题

1.莫名操作libvirt挂了

错误如下,试了一些办法,无效,重启才恢复

1
2
3
4
5
6
root@test-vm:/home/zhoulin/vdbs# /etc/init.d/libvirtd restart
[ ok ] Restarting libvirt management daemon: /usr/sbin/libvirtd.
root@test-vm:/home/zhoulin/vdbs# virsh list
error: failed to connect to the hypervisor
error: no valid connection
error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory

2.单纯virsh create在destroy后vm消失

1
2
virsh define XXX.xml
virsh list --all

上述方法注册之后,即使destroy也只是强关vm,还是依然在的,重新start可以拉起vm

Ceph-krbd-discard

Ceph的rbd块是精简制备的,只有真正有数据才会占用空间,但是存在上层文件系统删除文件,但是rbd占用空间不变的问题。Ceph的krbd模块的discard支持可以解决这个问题,实现前后端空间一致。上层文件系统删除文件后,ceph会清理底层对应的对象。
,