管中窥豹SPDK RBD bdev 模块

作者:杨子夜
文章来源:DPDK与SPDK开源社区

杨子夜 ,Intel 存储软件开发工程师

Ceph[1] 作为一个开源很久的分布式文件系统,至今依然被广泛使用。各种Linux 发行版本也都集成了Ceph相关的软件包, 用户可以非常方便地安装、配置以及搭建Ceph集群,从而对外提供各种存储相关的服务。目前在Ceph社区也有很多工作在继续优化Ceph这个开源的解决方案。在这篇文章中, 我们的重点不是介绍怎么优化Ceph,而是介绍SPDK [2]项目中的RBD bdev (RBD块设备模块)。这个模块主要是利用Ceph的librados/librbd的客户端软件库,把Ceph集群的RBD pool中的image file (镜像文件),转化为SPDK 定义的块设备。最终这个块设备可以被各类SPDK的target 程序使用(诸如SPDK NVMe-oF target, Vhost target, iSCSI target),充当Ceph的存储网关服务,对真正的客户端应用提供块设备服务。

一SDPK RBD bdev module介绍

SPDK RBD bdev 模块属于SPDK的bdev 这个系统(SPDK bdev subsystem),需要根据SPDK bdev相关头文件定义的接口实现需要的功能,比如对于块设备READ/WRITE/FLUSH等操作的支持。图1给出了RBD 模块的典型使用场景。作为SPDK BDEV模块的一员,它可以被SPDK iSCSI/vhost-scsi/NVMe-oF target使用。另外这个模块负责连接到Ceph集群中,主要依赖于Ceph的librbd/librados 软件库。


图 1 SPDK Ceph RBD bdev桥接Ceph和 各类SPDK target 程序

在SPDK RBD bdev 模块中,我们采用了和其他应用程序一样的4个调用步骤来进行一个Ceph的rbd image打开操作(如表一所示)。

1)Rados_cluster object (数据结构:rados_t)的创建。
2)Rados_cluster object的配置和连接。可以采用rados_conf_set 函数来进行相应的配置,或者使用rados_conf_read_file读取相应的配置文件,然后调用rados_connect 进行连接。
3)Rados cluster context的(数据结构:rados_ioctx_t)创建。调用rados_ioctx_create 函数。根据rados cluster object 以及rbd pool的名字。
4)打开一个RBD image 文件(打开的image的handler数据结构: rbd_image_t)。调用函数rbd_open, 需要使用rados_ioctx_t 这个对象以及rbd image 的名字。

表1 RBD image的打开

然后把打开的image_t的handler绑定在一个file descriptor上,调用rbd_set_image_notification函数实现。接着对image file的读写,可以采用rbd_aio_read(v)/rbd_aio_write(v)/rbd_aio_flush提交请求, 在SPDK RBD bdev module中采用rbd_poll_io_events来收割请求。

对于RBD image以及cluster 的关闭采用以下1-3的操作(如表2所示)。

1)Rbd 文件的关闭(rbd_image_t) 。调用 rbd_close函数。
2)Rados context 的销毁(rados_ioctx_t) 。调用 rados_ioctx_destroy函数。
3)Rados cluster 的销毁 (rados_t) 。调用rados_shutdown函数。

表2 RBD image的关闭

似乎在SPDK RBD bdev模块中的实现和其他应用程序相比没有特别的地方,但是这里有两个注意点:

SPDK thread和librados/rbd thread之间的竞争

使用SPDK application framework的应用程序,都需要用CPU的亲和性(CPU Affinity)绑定某几个CPU。但是对于librados/rbd这个库,可能需要创建一些后台的线程,比如在创建Rados的cluster_t 或者rados_ioctx_t对象的时候,这就在实际运行过程中造成了SPDK的线程和librados/rbd线程之间的竞争。为了解决这一个问题,我们引入了

spdk_call_unaffinitized 函数。这个函数的作用主要是:

1)首先得到当前SPDK 绑定了哪几个CPU 核(比如CPU 0 到3)
2)然后重新调用亲和性绑定函数,设定绑定为除了SPDK 绑定的CPU 核(比如CPU 0到3)以外的其他CPU 核心,然后执行完相应的函数(比如rados_create)。
3)再重新调用亲和性绑定函数,恢复原来SPDK APP应用的CPU核心的设置(比如刚才例子中的CPU 0 到3)。

这样就可以把librados/rbd相关的函数执行产生的线程放到SPDK thread 占据的CPU 核以外的CPU 核之上,并且不影响原来SPDK 应用程序对CPU的设定。当然对于这个问题的发现和解决,我们最初也是收到了使用SPDK RBD bdev module客户的反馈。在最开始的时候, 我们只是隔离了rbd image 以及rados_context 创建的函数。随着librados 库的改进,我们发现对于Rados cluster 的创建也要放到另外的线程上。

共享Rados cluster对象, 提高扩展性

从表1我们可以看到,一个RBD image 文件的打开,可以分为4个步骤。其中第一步和第二步是rados_t对象的创建。于是客户有Rados cluster 共享的需求:

针对同一个Ceph的集群的RBD 的使用,一般有两种用法,他们分别是“连接不同的rbd pool中的不同rbd 文件”和“连接同一个rbd pool中的不同rbd 文件”。我们看到对于使用librados/librbd 库的通常的做法都是创建单独的Rados cluster object,例如FIO库中的RBD Engine[3]。那么对于每打开一个RBD image文件,就会增加一个额外的线程(因为我们又打开了一个新的Ceph cluster 对象)。如果可以共享cluster,那么就可以减少很多额外的librados/librbd所产生的后台线程,最终就可以增加SPDK RBD bdev 模块的可扩展性。减少了额外的线程,可以提高整个系统的利用率。这个是一个非常好的建议,于是我们目前也在改造这个模块。使得可以满足可扩展性的需求。这个共享Rados cluster的特性会在SPDK 21.07甚至以后的版本中出现。

二SPDK RBD bdev module的主要应用场景

SPDK BDEV RBD module的主要应用场景,就是采用SPDK 的块设备服务作为Ceph 集群的块设备网关服务(Block Gateway Service)。当然用户依然可以采用其他的方式提供类似的服务,比如使用LIO (Linux I/O target),那么所涉及到的RBD 客户端的模块,就是KRBD;比如客户也可以使用QEMU + LIBRBD来连接Ceph集群。

使用SPDK BDEV module的解决方案还是有以下的好处,比如:

1)完善SPDK vhost解决方案从而提高通用性。SPDK vhost 应用主要是加速虚拟机中的I/O。如果SPDK vhost可以利用SPDK RBD bdev 模块 + SPDK NVMe Bdev模块,就可以既使用本地盘以及Ceph集群提供的远端盘。也就是有了这个模块以后,可以使得SPDK vhost的解决方案做到通用,完全替换原来的QEMU + kernel vhost的解决方案。

2)使得基于SPDK 的智能网卡可以卸载Ceph相关的客户端请求。有了这个模块以后,我们可以把在主机上采用librados/librbd 连接Ceph cluster的服务,完全卸载到智能网卡中,这个毫无疑问卸载了主机上对Ceph服务的CPU 资源消耗。

三总结和后续

这篇文章中主要介绍了SPDK 中的RBD bdev module的实现细节以及使用场景。对于采用Ceph集群的存储服务商或者用户,我们可以采用SPDK的vhost/iSCSI/NVMe-oF target 作为中间件服务。得益于 SPDK RBD bdev模块,这些SPDK服务可以作为Ceph的网关服务给前端应用提供块设备存储。此外对SPDK RBD bdev的使用或者性能有问题的客户,可以在SPDK的mailing list,Slack或者SPDK github[4]的相关页面联系我们,以进行相关的讨论。

四References

[1] https://ceph.io
[2] http://spdk.io
[3] https://github.com/axboe/fio/blob/master/engines/rbd.c
[4] https://github.com/spdk/spdk/issues


  • 本站原创文章仅代表作者观点,不代表SDNLAB立场。所有原创内容版权均属SDNLAB,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用,转载须注明来自 SDNLAB并附上本文链接。 本站中所有编译类文章仅用于学习和交流目的,编译工作遵照 CC 协议,如果有侵犯到您权益的地方,请及时联系我们。
  • 本文链接https://www.sdnlab.com/25330.html
分享到:
相关文章
条评论

登录后才可以评论

SDNLAB君 发表于21-09-10
0