Ceph,作为一个高度可扩展的分布式存储系统,已经成为云计算和大数据时代的关键基石。随着企业和组织对数据存储的需求日益增长,Ceph 通过其强大的特性,如可靠性、伸缩性和性能,满足了这些需求。然而,随着集群规模的扩大和工作负载的多样性,如何确保资源的有效分配和性能隔离成为了一个重要议题。在这个背景下,Ceph 的 Quality of Service (QoS) 功能显得尤为重要。
QoS 在 Ceph 中的实现,特别是在其 RADOS Block Device (RBD) 模块中,提供了一种机制来控制和限制存储资源的使用,如 IOPS(每秒输入输出操作次数)和带宽。这对于在多租户环境中维持服务质量,防止资源过度使用或“邻居噪音”问题至关重要。通过精确地配置 QoS 参数,管理员可以为不同的虚拟机、容器或应用分配适当的存储资源,确保系统的整体性能和响应性。
在本文中,我们将深入探讨 Ceph RBD 的 QoS 特性,重点关注如何验证和量化 RBD QoS 设置的效果。通过一系列的测试和分析,我们将展示 QoS 参数如何影响 RBD 性能,以及如何根据特定的工作负载和性能要求调整这些参数。无论是对于 Ceph 新手还是资深用户,了解和应用 RBD 的 QoS 功能都是提高存储系统效率和可靠性的关键步骤。
在ceph 14版本开始支持rbd的qos 详细配置参数可以参考https://docs.ceph.com/en/latest/rbd/rbd-config-ref/
ceph rbd的qos是在librbd上进行限制的。
查看当前镜像的qos配置
rbd -p libvirt-pool config image ls scan.img|grep qos
查看存储池的qos配置,存储池的qos限制的是所有镜像总的qos不超过设置的值
rbd config pool ls libvirt-pool|grep qos
可以看到默认不设置的时候bps和iops都为0,表示默认不限速。rbd_qos_schedule_tick_min=50表示qos的最小调度间隔是50毫秒,每隔50毫秒检查一次当前的io操作是否符合qos配置。这里解释下rbd_qos_write_iops_burst_seconds=1表示在达到写入 IOPS 限制(由 rbd_qos_write_iops_limit 参数设置)之后,RBD 图像可以以突发模式继续写入操作的时间长度。这个突发模式允许 IOPS 短时间内超过设定的限制值,为的是处理短暂的高负载情况,而不是持续的高速写入。这个参数的值设定为 1 秒,意味着在触发 IOPS 限制后,写入操作可以在接下来的 1 秒内保持较高的 IOPS,之后将被限制回设定的 rbd_qos_write_iops_limit 值,同样对bps的burst_seconds的意义也是一样。
解释下相关参数:
fio 是一个灵活的 I/O 性能测试工具,广泛用于评估磁盘和文件系统的性能。以下是一个基本的示例,展示如何使用 fio 进行随机读写测试:
fio --name=randrw_test --ioengine=libaio --iodepth=1 --rw=randrw --rwmixread=50 --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting
参数解释
在不进行qos限速的情况下,我使用fio在rbd镜像存储的虚拟机里进行随机读写测试
rbd perf image iostat --pool libvirt-pool
image.png
rbd -p libvirt-pool config image set scan.img rbd_qos_iops_limit 100
再次在scan.img所在的虚拟机上进行随机读写测试
fio --name=randrw_test --ioengine=libaio --iodepth=1 --rw=randrw --rwmixread=50 --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting
查看iops限速后的结果
rbd perf image iostat --pool libvirt-pool
可以看到效果很明显,iops读写不超过100
rbd -p libvirt-pool config image set scan.img rbd_qos_iops_limit 0
rbd -p libvirt-pool config image set scan.img rbd_qos_bps_limit 100000
再次在scan.img所在的虚拟机上进行随机写测试
fio --name=randrw_test --ioengine=libaio --iodepth=1 --rw=randwrite --rwmixread=50 --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting
查看bps限速后的结果
rbd perf image iostat --pool libvirt-pool
可以看到效果很明显,写吞吐不超过100KiB/s
后面单独对读写的iops和bps各进行了测试,发现符合预期。
rbd -p libvirt-pool config image set scan.img rbd_qos_bps_limit 0
rbd config pool set libvirt-pool rbd_qos_iops_limit 200
再次在scan.img所在的虚拟机上进行随机读写测试
fio --name=randrw_test --ioengine=libaio --iodepth=1 --rw=randrw --rwmixread=50 --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting
这里发现对于pool层面的iops限速没什么效果
rbd config pool set libvirt-pool rbd_qos_iops_limit 0
rbd config pool set libvirt-pool rbd_qos_bps_limit 1000000
再次在scan.img所在的虚拟机上进行随机写测试
fio --name=randrw_test --ioengine=libaio --iodepth=1 --rw=randwrite --rwmixread=50 --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting
这里发现对于pool层面的bps限速也没什么效果
后面单独对pool层面分别进行读、写的iops和bps,发现限速也没什么效果
可以通过下面命令查看当前虚拟机的qos,这里查看scan虚拟机vdb磁盘的qos,也就是我们刚才测试rbd qos的那个磁盘,0表示不限速
virsh blkdeviotune scan vdb
对scan虚拟机的vdb进行bps限制为5MiB/s
virsh blkdeviotune scan vdb --total-bytes-sec 5000000 --live
查看bps限速后的结果,iops实际不超过5MiB/s
对scan虚拟机的vdb进行iops限制
virsh blkdeviotune scan vdb --total-bytes-sec 0 --live
virsh blkdeviotune scan vdb --total-iops-sec 1000 --live
在scan虚拟机里对其进行随机读写测试
fio --name=Test --ioengine=libaio --iodepth=64 --rw=randrw --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting
查看iops限速后的结果,iops实际不超过1000
再次在scan.img所在的虚拟机上进行随机读写测试
fio --name=Test --ioengine=libaio --iodepth=64 --rw=randrw --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting
image.png
对于ceph rbd qos的使用,还是建议在image层面进行bps和iops的限速,pool层面的限速效果不明显。当然也可以使用qemu在块设备上做虚拟机磁盘的io限制,使用qemu做qos的优点是本地硬盘也可以进行限速,而ceph rbd的qos对象只是ceph集群中的rbd镜像。