将晦涩难懂的技术讲的通俗易懂
分类: LINUX
2019-07-06 17:34:32
该系列文章为本人参加2019年中国KubeCon + CloudNativeCon +开源峰会参会总结;
target侧的代码实现主要在lib/nvmf/tcp.c中。下图是SPDK支持host实现的时间线:
host侧的实现代码在lib/nvme/nvme_tcp.c中。
总的来讲,SPDK NVMe/TCP transport 的整个设计遵循了SPDK无锁,轮询,异步I/O的理念,如下表所示。根据TP8000 specification中的定义,每个TCP连接(TCP connection)对应于一个NVMe的qpair。在SPDK的实现中,我们依然采用group polling的方法来管理所有的TCP连接。每一个SPDK thread上运行一个TCP相关的polling group,每一个TCP连接只会被加入一个TCP polling group中,由这个polling group处理后续的所有事件,那么这个TCP连接将会被唯一的CPU core处理,这样就不会存在CPU的竞争情况:不同CPU竞争处理同一个TCP connection。 这样的设计在很大的层面上避免了CPU资源的竞争。另外目前存在很多用户态的TCP协议栈,为此SPDK 封装了一些socket API相关的操作。目前,NVMe/TCP的实现代码直接使用SPDK封装的API 进行socket的操作,如此一来,我们可以接入不同种类的Socket API实现,诸如VPP,mTCP,fstack,seastar等。只要能够实现SPDK socket API所定义的抽象函数,就可以整合到SPDK的sock库中。
NVMe-oF transport(传输层)的抽象
SPDK定义的NVMe-oF的框架剥离出了NVMe或者NVMe-oF处理逻辑的共同代码,然后针对所有的transport提供了一个统一的抽象接口。那么每个transport只需要实现这个接口里面的函数或者数据结构即可。对于TCP transport也是一样,target端和host端完全遵循这个设计。下图给出了目前SPDK软件库实现的或者将要实现的transport。其中Fibre Channel的支持的patch还在review 过程中,TCP transport和VPP的stack可以整合,但是由于VPP stack的一些稳定性原因,所以也标记为“在整合过程中”。
关于其实现细节可以参考这篇文章:。这里不再展开。