一种基于数据面开发套件DPDK的内存分配方法和装置
文献发布时间:2023-06-19 11:52:33
技术领域
本发明涉及数据发送管理技术领域,具体涉及一种基于DPDK(DataPlaneDevelopment Kit,数据面开发套件)的内存分配方法和装置。
背景技术
在公有云计算业务中,计算节点的CUP资源需要最大化的售卖给用户,而用来将用户虚拟机的数据转发给后端存储系统的组件则只能在有限的CPU上运行。为了追求系统的极限性能,将用户态IO的延迟降到最低、每秒请求数提升到最高,广泛使用用户态协议栈替代内核协议栈。
现有技术中的RPC零拷贝方法一般过程如下:首先RPC层设置注册内存池,由注册内存池保存大小不一的内存块,可在传输中反复使用;应用层从内存池分配的空间,在RPC各组件中无拷贝地传输;最后采用DMA模式发送给对端。前文提到的RPC零拷贝方法中,应用层的内存块可以在各模块使用DMA传递,做到无拷贝,但具有如下缺点:(1)内存块在模块间传递时无生命周期防护,在未释放时不可复用,即应用层数据要重试时,要重新分配新的内存块并填充;(2)应用层生成的RPC消息,所有内存都要从内存池分配,否则无法做零拷贝,即不能兼容拷贝和零拷贝内存同时存在。
发明内容
本发明提供了一种基于数据面开发套件DPDK的内存分配方法和装置,实现基于DPDK的发包零拷贝内存分配。
为了实现上述发明目的,本发明采取的技术方案如下:
第一方面,本发明提供一种基于数据面开发套件DPDK的内存分配方法,包括:
在应用层从零拷贝内存池分配zbuf内存用于存储虚拟机VM输入输出IO请求数据,从系统内存分配内存用于存储请求的上下文信息;
在应用层将所述VM IO请求数据与所述请求的上下文信息组装成远程服务调用RPC消息;
在协议栈分配计算机的中央处理单元pbuf保存VM IO请求数据的内存地址和长度信息;
在协议栈以链表的形式组装以太网报文,将所述以太网报文发送到网络。
优选地,所述方法之前还包括:配置零拷贝内存池,所述零拷贝内存池为在内存空间预留的连续的zbuf内存;
优选地,所述的方法,还包括:
在协议栈发送报文结束时,发送应答包,在应用层依据所述应答包释放对所述zbuf内存的使用权。
优选地,所述的方法,还包括:
同一个zbuf内存在协议栈上尚未发完时,通过维护引用计数多次写入到协议栈。
优选地,上下文信息包括:本次IO请求数据的长度、版本号、偏移量、请求识别码。
优选地,在协议栈以链表的形式组装以太网报文包括:
分配用户态DPDK收发报文的内存mbuf存储所述以太网报文,所述以太网报文中携带报文信息,所述报文信息包括:报文链表的数据长度、TCP序列号和以太网头信息;
分配mbuf内存分别指向发送缓冲区和zbuf内存;
将串联成的mbuf链表传递给DPDK,由DPDK根据最大传输单元对链表数据进行拆分,拆分成独立的以太网报文后转发给网卡。
优选地,所述的方法,还包括:
接收查询报文的消息,将所述查询报文的消息中的查询地址与零拷贝内存池的起止地址进行比较,判断所述查询地址是否属于零拷贝内存池,若不属于零拷贝内存池,将应用层RPC消息数据拷贝到协议栈的发送缓存区;
在协议栈分配pbuf保存所述RPC消息数据在发送缓存区的内存地址和长度信息;
顺序地从发送缓冲区拷贝所述RPC消息数据到用户态DPDK收发报文的内存mbuf;
由DPDK依次将存储于mbuf的RPC消息数据发送到网络。
优选地,应用层或者协议栈第一次操作所述zbuf内存时对引用计数加一,应用层或者协议栈不再操作所述zbuf内存时对引用计数减一,将引用计数减为0时释放zbuf的内存。
第二方面,本发明提供一种基于数据面开发套件DPDK的内存分配装置,包括:
分配模块,设置为在应用层从零拷贝内存池分配zbuf内存用于存储虚拟机VM输入输出IO请求数据,从系统内存分配内存用于存储请求的上下文信息;
组装模块,设置为在应用层将所述VM IO请求数据与所述请求的上下文信息组装成远程服务调用RPC消息;
协议模块,设置为在协议栈分配计算机的中央处理单元pbuf保存VM IO请求数据的内存地址和长度信息;
发送模块,设置为在协议栈以链表的形式组装以太网报文,将所述以太网报文发送到网络。
本发明与现有技术相比,具有如下有益效果:
本发明实施例实现RPC消息重试时内存复用、应用层生成的RPC消息能同时存在拷贝和零拷贝内存;本发明实施例使用一块连续的空间作为零拷贝内存池,每个zbuf内存带引用计数,维护在不同模块之间传递时的生命周期;本发明实施例中,应用层数据转发给协议栈时,协议栈从pbuf队列分配一个pbuf,保存应用层数据的地址和长度,这样可以将多个连续的内存块组成链表,通过接口传递给网卡驱动;当应用层写多个zbuf到协议栈时,由于zbuf之间不连续,使用pbuf队列保存不同zbuf的地址和长度;当应用层数据不是来自zbuf内存池时,协议栈预先分配一块zbuf,并将应用层数据拷贝进去,pbuf则指向新分配的zbuf即可。从pbuf队列上顺序取出数据封装成mbuf链表,转发给网卡;这种模式不仅可处理应用层数据全是拷贝内存或者全是zbuf零拷贝内存场景,同时也可处理拷贝和零拷贝并存的场景。
本发明的其它特征和优点将在随后的说明书中阐述,并且,部分地从说明书中变得显而易见,或者通过实施本发明而了解。本发明的目的和其他优点可通过在说明书、权利要求书以及附图中所特别指出的结构来实现和获得。
附图说明
附图用来提供对本发明技术方案的进一步理解,并且构成说明书的一部分,与本申请的实施例一起用于解释本发明的技术方案,并不构成对本发明技术方案的限制。
图1为本发明实施例的基于DPDK的内存分配方法的流程图图;
图2为本发明实施例的基于DPDK的内存分配装置的结构示意图;
图3为相关技术中的内存分配过程的示意图;
图4为本发明实施例的内存分配过程的示意图。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚明白,下文中将结合附图对本发明的实施例进行详细说明。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互任意组合。
在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行。并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。
如图1所示,本发明实施例提供一种基于数据面开发套件DPDK的内存分配方法,所述分配方法包括:
在应用层从零拷贝内存池分配zbuf内存用于存储虚拟机VM输入输出IO请求数据,从系统内存分配内存用于存储请求的上下文信息;
在应用层将所述VM IO请求数据与所述请求的上下文信息组装成远程服务调用RPC消息;
在协议栈分配计算机的中央处理单元pbuf保存VM IO请求数据的内存地址和长度信息;
在协议栈以链表的形式组装以太网报文,将所述以太网报文发送到网络。
本发明实施例中,所述方法之前还包括:提供零拷贝内存池,所述零拷贝内存池为在内存空间预留的连续的zbuf内存;
所述的方法还包括:
在协议栈发送报文结束时,发送应答包,在应用层依据所述应答包释放对所述zbuf内存的使用权。
本发明实施例中,所述的方法还包括:
同一个zbuf内存在协议栈上尚未发完时,通过维护引用计数多次写入到协议栈。
本发明实施例中,上下文信息包括:本次IO请求数据的长度、版本号、偏移量、请求识别码。
本发明实施例中,在协议栈以链表的形式组装以太网报文包括:
分配用户态DPDK收发报文的内存mbuf存储所述以太网报文,所述以太网报文中携带报文信息,所述报文信息包括:报文链表的数据长度、TCP序列号和以太网头信息;
分配mbuf内存分别指向发送缓冲区和zbuf内存;
将串联成的mbuf链表传递给DPDK,由DPDK根据最大传输单元对链表数据进行拆分,拆分成独立的以太网报文后转发给网卡。
本发明实施例中,所述的方法还包括:
接收查询报文的消息,将所述查询报文的消息中的查询地址与零拷贝内存池的起止地址进行比较,判断所述查询地址是否属于零拷贝内存池,若不属于零拷贝内存池,将应用层RPC消息数据拷贝到协议栈的发送缓存区;
在协议栈分配pbuf保存所述RPC消息数据在发送缓存区的内存地址和长度信息;
顺序地从发送缓冲区拷贝所述RPC消息数据到用户态DPDK收发报文的内存mbuf;
由DPDK依次将存储于mbuf的RPC消息数据发送到网络。
本发明实施例中,应用层或者协议栈第一次操作所述zbuf内存时对引用计数加一,应用层或者协议栈不再操作所述zbuf内存时对引用计数减一,将引用计数减为0时释放zbuf的内存。
如图2所示,本发明实施例提供一种基于数据面开发套件DPDK的内存分配装置,
提供零拷贝内存池,所述零拷贝内存池为在内存空间预留的连续的zbuf内存;
所述装置包括:
分配模块,设置为在应用层从零拷贝内存池分配zbuf内存用于存储虚拟机VM输入输出IO请求数据,从系统内存分配内存用于存储请求的上下文信息;
组装模块,设置为在应用层将所述VM IO请求数据与所述请求的上下文信息组装成远程服务调用RPC消息;
协议模块,设置为在协议栈分配计算机的中央处理单元pbuf保存VM IO请求数据的内存地址和长度信息;
发送模块,设置为在协议栈以链表的形式组装以太网报文,将所述以太网报文发送到网络。
实施例1
结合图3和图4说明本实施例的内存分配过程:
如图3所示,用户态协议栈中拷贝模式的发包流程如下:
首先应用层组装RPC消息时,从系统申请两块内存,一块用于保存VM IO作为payload,一块用于构造RPC请求的上下文信息;然后写给协议栈时,将RPC消息拷贝到发送缓冲区(send buffer);协议栈组装以太网报文时,根据传输窗口,顺序地从发送缓冲区拷贝数据到mbuf,每个mbuf的地址事先已注册到网卡驱动;最后由DPDK依次将准备好的mbuf报文发送到网络。
为了去除用户态协议栈中应用层到协议栈缓存空间和协议栈到网卡报文的两次拷贝操作,本发明实施例采用基于DPDK的发包零拷贝方式,提供zbuf的生命周期维护机制,用于应用层数据重试,且支持应用层拷贝内存和零拷贝内存同时下发。图4是本发明设计的基于DPDK的发包零拷贝模型,为了适配RPC消息场景,该模型可处理应用层拷贝内存和零拷贝zbuf并存。分布式系统使用的RPC消息一般分为两部分,用户的真实数据和软件层的请求上下文。其中用户数据的内存在IO完成之前,内存不可更改,而上下文信息则包括本次IO的长度、版本号、偏移量、请求识别码等。特别地,在IO出现超时需要重试时,用户的数据保存不变,而软件层的上下文信息如版本号、请求识别码则需要重新生成。应用层首先分配zbuf内存保存用户的IO数据,从系统分配内存保存请求的上下文信息,组装成RPC消息。将真实数据和上下文信息写到协议栈时,对于拷贝内存,协议栈预先准备好一块zbuf空间作为发送缓存send buffer,将应用层数据拷贝进去,再从pbuf队列中分配pbuf来保存数据在sendbuffer的首地址和长度;对于zbuf内存,则直接分配pbuf来保存zbuf的首地址和长度。由于TCP协议是保序协议,协议栈缓存的数据需要顺序发送,而send buffer和zbuf指向的内存不连续,所以只能以链表的形式组装以太网报文。基于DPDK组装的报文称为mbuf,首先是报文头部(mbuf header),用来保存报文链表的数据长度、TCP序列号和以太网头等,再分配新的mbuf分别指向发送缓冲区和zbuf内存,最后将串联成的mbuf链表传递给DPDK,由DPDK根据最大传输单元对链表数据进行拆分,拆分成独立的以太网报文后转发给网卡。zbuf内存池是一块内存连续的空间,通过判断内存块是否在空间内,即可区分zbuf和系统内存。每个zbuf带引用计数,在各模块间传递期间,当某个模块会对zbuf进行操作时,则计数加一;某个模块不再访问zbuf时,则计数减一,这样保证zbuf的生命周期。在应用层需要重试zbuf时,无论zbuf是否还存在于协议栈模块中,依然可重复传递给协议栈,只用对计数加一,此时协议栈的不同pbuf指向同一zbuf。
虽然本发明所揭露的实施方式如上,但所述的内容仅为便于理解本发明而采用的实施方式,并非用以限定本发明。任何本发明所属领域内的技术人员,在不脱离本发明所揭露的精神和范围的前提下,可以在实施的形式及细节上进行任何的修改与变化,但本发明的专利保护范围,仍须以所附的权利要求书所界定的范围为准。
- 一种基于数据面开发套件DPDK的内存分配方法和装置
- 一种基于DPDK的大页内存动态迁移的方法与装置