APP下载

基于GPU加速的NFV系统的框架设计和性能优化

2022-02-19郭良琛

计算机应用与软件 2022年2期
关键词:流水线数据包虚拟化

郭良琛 张 凯

1(复旦大学软件学院 上海201203) 2(复旦大学计算机科学技术学院 上海 201203) 3(上海市数据科学重点实验室 上海 200433)

0 引 言

网络功能虚拟化(NFV)系统将企业网络基础设施中的关键部分——网络功能进行软件实现,从而使得其维护、部署及管理更加容易。大部分NFV系统将网络功能运行在CPU上。这种部署方案门槛不高,但是它相比传统使用专有硬件实现的网络功能在执行效率上有一定的牺牲。相比CPU,图形处理器(GPU)在并行计算方面具有突出的性能优势。研究指出,部分具备计算和访存密集特征的网络功能使用GPU进行加速可显著提高性能[1-4]。因此,使用GPU对网络系统进行加速成为当前高性能网络处理领域的研究热点。

在NFV系统中,多个网络功能实例通常组合成服务链,对网络流量提供复杂的处理功能。在同一套NFV系统中部署的多个网络功能实例需要共享软件和硬件基础设施。在基于GPU加速的NFV系统中,网络功能在系统中共存并组合成服务链的方式主要分为两种。一种需要网络功能利用NFV系统API将其功能完全使用GPU核函数实现,这样NFV系统能够实现执行的高度集成化,减少网络功能之间的通信开销,有助于提高性能。但是,这种方式仅允许网络功能开发者使用有限的GPU算子,在网络功能的实现方面有较多的限制。并且,高度集成的方案对网络功能的独立运维、资源分配和数据安全隔离等方面也有不便之处。另一种系统则需要将网络功能部署在具备独立运行时的虚拟机或容器中,网络功能可以使用虚拟化的CPU和GPU计算资源对网络数据包进行处理。这种方案有效解决了网络功能在实现和运维方面的挑战。

但是,将GPU加速的网络功能使用虚拟化方式独立部署也带来了一些问题。一方面,为保证部署独立性,这些网络功能在CPU-GPU执行流水线的CPU处理部分有额外的开销,例如协议栈处理与有状态网络功能的状态管理等。由于GPU处理部分本身较为高效,流水线中的CPU处理的低效对整体性能的负面影响很大。另一方面,相比于集成化的方案,独立部署的网络功能需要自行实现大量有关网络数据包预处理的基础逻辑。这样的工作增加了网络功能开发者的负担。

基于以上问题,本文提出一种针对GPU加速的NFV系统的框架设计和实现。该框架在允许GPU加速的网络功能以容器的形式独立部署在NFV系统中的前提下,利用服务链中网络功能之间共享数据和流状态的特性,引入了共享式流状态管理机制,以减少网络功能CPU-GPU处理流水线中CPU阶段与协议栈处理和状态管理相关的开销,并降低网络功能开发者的开发负担。对原型系统的实验评估表明,相比于现有的系统框架设计方案,该框架能够显著降低GPU加速的NFV系统中网络功能处理流水线中的CPU阶段的开销,并在常见的网络功能服务链上达到了最多2倍的吞吐量提升。

1 背景介绍

1.1 网络功能与NFV系统

网络功能是企业网络基础设施的基本组成单元。常见的网络功能包括防火墙、网络入侵检测系统(NetworkIntrusionDetectionSystem, NIDS),IPsec网关和路由器等。在常见的网络基础设施中,网络功能通常会相互连接形成完整的服务链来提供相对灵活可定制的网络流量处理系统。传统上,网络功能由专门设计的网络硬件设备提供,但这种方式对于服务链的部署、运维、扩展方面有较多限制。NFV系统利用软件和自动化替代专用网络设备来定义、创建和管理网络功能,从而实现网络功能在通用硬件上部署,并达到了较高的灵活性和可扩展性[5]。

NFV系统将多个网络功能集成在同一个平台下,合并对外提供网络服务。在一般的NFV系统中,各个网络功能被标准化的虚拟机或容器包装,NFV系统可以允许不同供应商提供的、依赖不同软件环境的网络功能实现共存在一个运行环境中。虚拟化技术的使用使得系统中不同网络功能的独立资源分配、运行时隔离、在线创建和热更新等操作都成为可能。

大多数针对NFV系统的研究[6-8]使用最常见的通用处理器——CPU进行网络流量的处理。尽管CPU的计算资源常见、易获得,但其处理网络流量的性能通常无法与配备了专用集成电路(ASIC)的专用网络设备相提并论。为了提升性能,有一类研究尝试将通用计算中常用的计算加速器硬件,尤其是图形处理器(GPU)应用在NFV领域。相比于CPU,GPU具有较高的内存带宽和大量的计算执行单元,适用于网络功能中的数据密集型和计算密集型网络流量处理任务。已经有研究表明,一些网络功能可以使用GPU加速从而获得显著的性能提升,例如NIDS模式匹配[3,9]、加密/解密[2]和路由[1]等。

1.2 基于GPU的NFV系统设计

为了在NFV系统中便捷和高效地集成使用GPU加速的网络功能,研究者设计了多种专用于GPU加速的网络数据包处理系统。根据将多个GPU加速的网络功能部署在服务链中的形式的区别,这类系统的设计主要分为两类。

纯GPU实现。GASPP[9]、GPUNFV[10]和FlowShader[11]等系统将网络系统服务链中各个网络功能的全部功能都用适用于GPU的并行代码实现。通过将网络处理的功能高度集成化地执行在GPU上,这类系统减少了网络功能之间数据传输的开销。但是,高度的集成化不可避免地带来了一些弊端:开发者在实现网络功能时可利用的算子有限,而且因为服务链中用来加速网络功能的GPU核函数作为一个整体部署在GPU上,因此单个网络功能的独立运维、资源动态分配和数据安全隔离都无法保证。

CPU-GPU流水线实现。G-NET[12]和Grus[13]等GPU加速的NFV系统采用了虚拟化设计,并针对GPU加速计算的场景进行了优化。这类系统要求网络功能开发者分别实现网络功能在CPU和GPU上的处理逻辑,并最终在NFV系统上以流水线的方式执行。一个典型的GPU加速的网络功能流水线如图1所示。首先,流量从网络功能所部署在的虚拟机(或容器)的虚拟网络接口中流入,并被暂存在主内存的缓冲区中,进而分别被开发者自定义的预处理(Pre-processing)模块、GPU核函数(GPUKernelFunction)与后处理(Post-processing)模块进行处理。网络流量需要首先经PCIe通道从主机到设备(Hostto Device, HtoD)传输到GPU显存中,GPU处理完成的结果同样需要从设备到主机(Device to Host, DtoH)传回主内存。在NFV系统中,多个这样的流水线共存从而形成网络功能的服务链,而每个网络功能的CPU执行部分(Pre-processing和Post-processing)与GPU执行部分(Kernel Function)都分别被虚拟化并共享硬件资源。这类切分网络功能各个步骤的执行职责并分别进行虚拟化的方式使得GPU加速的网络功能在实现上更加灵活。

图1 一个典型的使用GPU加速的网络功能流水线

2 相关工作

许多研究致力于提升NFV系统的性能。OpenBox[14]、SNF[15]、Metron[7]和NetBricks[8]一类基于CPU的NFV系统与GASPP[9]、FlowShader[11]等基于GPU的NFV系统通过放弃虚拟化,将网络功能中核心逻辑与I/O操作进行合并的方式提高了NFV的网络流量处理性能。尽管其中NetBricks[8]能够利用API抽象层为各网络功能提供单独的运行时环境,但是虚拟化的其他优势,包括灵活部署、灵活资源分配等都将不复存在。

网络协议栈处理和状态管理是网络功能执行中的重要开销。许多系统实现了在多个网络功能组成的服务链中设计协议栈共享的机制,以简化网络功能的开发,并减少不同网络功能之间重复性协议栈处理的开销,如MiddleClick[16]、Microboxes[17]和基于GPU的GASPP[9]等。这类系统中的协议栈功能提供了数据包分片重组、TCP流重组等一系列高级功能,并提供了针对多种协议层级的API。但这类系统中系统基础设施和网络功能之间存在高耦合度的问题,并不能良好地支持网络功能的隔离部署。

基于GPU加速并实现了网络功能隔离部署的NFV系统包括G-NET[12]和Grus[13]。其中G-NET[12]通过利用现代GPU的并行核函数执行(CKE)特性提高GPU计算资源的利用效率。但是,这类系统的计算流水线中存在CPU阶段低效的问题。

3 现有系统的问题

尽管使用虚拟化技术进行网络功能封装的GPU加速的NFV系统能够达到可观的性能和部署灵活性,但是其中依然有性能方面的问题,从而限制了这类系统在生产环境中的广泛部署。

部分网络功能处理流水线中,计算密集型和数据密集型任务是网络功能性能的主要瓶颈,这也是业界采用GPU进行加速的主要原因。当这类任务转移到高性能的GPU之后,系统的性能瓶颈可能会随之转移。为了探索常见GPU加速的网络功能的性能瓶颈,我们使用CPU-GPU异构方式实现了几个常见的网络功能,并测量了执行流水线中各个关键处理步骤的相对时间开销,结果如图2所示。可以看出,网络功能中GPU处理的总时间开销(包括核函数执行和PCIe数据传输)相对较小,一般不超过总处理时间的一半。在这种情况下,GPU处理部分具有充分的并行性,因此网络功能中CPU处理部分成为了影响总体性能的重要因素之一。

图2 一些GPU加速的网络功能批处理时间的分解

通常,GPU加速的网络功能中CPU处理部分负责网络数据包解析和状态维护。例如,网络功能在处理每个数据包之前,都需要对包的元信息进行提取,包括读取包头和定位负载位置等,这个过程包括数次随机内存访问。对于需要维护连接状态信息的网络功能,它们还需要自行实现完整的高层协议栈,以实现基于流的状态管理。此外,网络功能还需要根据流的处理情况对其状态进行实时读取和更新。从图2可以看出,基于有状态的网络功能中,协议栈处理和状态维护工作最多占据了网络功能总处理时间的一半以上,是CPU-GPU工作流水线中的重要开销。

尽管协议栈处理和状态维护的开销在网络系统中普遍存在,但是在GPU加速的NFV系统中,这部分开销尤为突出。这主要有两方面原因:(1)在基于虚拟化的网络系统中,网络功能模块大多是独立的,它们自身包含完整的协议栈实现。当多个此类网络功能部署在同一个服务链中后,服务链中流过的数据包需要经过多次重复的协议栈处理,浪费了大量的CPU计算资源。(2)为了最大化流水线中GPU的资源利用效率,GPU核函数会一次性并行处理整批数据包,因此上游数据包需要积累至一定批量才会被送入GPU核函数。在这种情况下,部分数据包需要在待处理的缓冲区中等待一段时间,这导致CPU处理阶段平均时延被进一步放大。因此,CPU处理阶段的低效会极大程度上影响整个CPU-GPU处理流水线的效率,从而让GPU加速的性能优势不复存在。

4 系统设计

针对以上问题,本文提出一种适用于GPU加速的NFV系统的框架。该系统框架一方面使用CPU和GPU上的虚拟化技术将网络功能运行时独立开来,以简化网络功能的开发、运维和资源分配;另一方面利用共享的状态管理机制,通过减少CPU-GPU流水线中CPU部分的计算开销,提升整体运行效率。

4.1 总体框架

本文提出的系统总体框架如图3所示。与传统NFV一致,本系统主要包括基础设施和网络功能两大部分。其中基础设施负责支持网络功能所需的基础服务,例如网络I/O、状态管理与GPU虚拟化等,运行在独立的进程中。由供应商开发的网络功能则被部署在具备独立运行时环境的容器中,负责执行具体的网络数据包处理功能。系统中允许同时部署多个网络功能组成的服务链。同时,系统分配了多个共享内存区域,并使用无锁环形队列等数据结构实现网络功能之间、网络功能与NFV基础设施之间的通信。

图3 系统架构

(1) 数据平面。系统的基础设施部分为网络数据包在其整个生命周期中的存储和传递提供支持。当系统的接收线程(RX)从网卡收到数据包之后,会直接将其保存在由基础设施和网络功能共享的内存区域——数据包缓存中,并同时生成对应的包描述符(descriptor),进而将其指针添加至网络功能实例的接收队列。包描述符是包含数据包元信息的小型数据结构,其中也包括指向该数据包在缓存区中位置的指针。因此,网络功能通过读取包描述符便能够访问、修改数据包信息,包括元信息以及数据包内容。这样,数据包在系统内部的转发只要通过拷贝包描述符指针即可完成。因为包描述符指针的大小(通常8 B)远远小于数据包内容(64 B~1 500 B),数据平面中数据包传递的内存拷贝开销可以大幅度降低。对于已被处理完成的数据包,发送线程(TX)会根据其描述符指针从数据包缓存中提取出包内容,并发送至网卡的输出端。

(2) 网络功能。系统支持遵循CPU预处理-GPU核函数处理-CPU后处理流水线的网络功能。对于CPU处理阶段,系统提供的API允许网络功能直接访问、维护数据包所在流的状态信息,以平摊多个网络功能中的相关开销。对于GPU处理阶段,系统也提供了GPU虚拟化API,允许网络功能向GPU拷贝数据、执行核函数等。

(3) GPU虚拟化。网络功能通过调用GPU虚拟化API,可以利用共享内存信道与GPU虚拟化层进行通信。网络功能会将执行请求添加到共享内存中的队列来通知GPU虚拟化层执行相应功能。为了在不同网络功能之间共享GPU计算资源,GPU虚拟化层在运行时只创建一个执行上下文(executioncontext),并将不同网络功能的核函数执行请求或内存管理请求提交到此上下文中。此外,虚拟化层还利用了现代GPU中的并行核函数执行(CKE)的特性,允许不同网络功能的多个核函数在GPU中并行执行,以实现GPU计算资源的空间共享,提高GPU计算资源的利用效率。

4.2 协议栈处理与状态管理

网络协议栈处理和状态管理是网络功能执行中的重要开销。为降低此类开销对网络功能中GPU加速效果的影响,本文提出基于流的共享式状态管理机制,以在服务链中分摊网络功能的状态管理开销。同时,与之对应的API也有助于简化网络功能的开发。

共享式状态管理的核心思想是利用不同网络功能之间协议栈处理和流状态管理的相似性,将大部分该类计算集中在NFV系统的基础设施部分,并将计算结果向各个网络功能共享。系统基础设施层的协议栈模块负责预处理数据包并管理流状态,而流状态存储模块则允许网络功能对这类状态进行访问。下文将对共享状态管理中的一些关键步骤进行详细介绍。

(1) 数据包解析。网络功能对入站流量处理的第一步是解析数据包,并根据其实际结构提取一些关键字段。系统的协议栈模块会首先对数据包进行解析,并将其结构记录下来,这样后续的网络功能就可以直接读取数据包中的关键字段从而跳过解析步骤。如图4所示,数据包中各层协议栈对应的包头指针可被协议栈模块解析取得,并保存在数据包描述符中。而网络功能开发者只需要调用相关API,即可直接读取所需的信息,包括数据包传输层协议的类型与其头部的位置等,而无须再自行实现协议栈进行解析。

图4 流的共享状态管理

(2) 流状态管理。网络包所在流的状态(例如TCP连接状态)是网络功能进行有状态处理所需要的关键信息。例如,有状态防火墙通常情况下会根据数据包所属连接的状态,拒绝那些并不属于已成功建立的TCP连接的数据包。为加速网络功能流状态的获取,系统协议栈模块处理入站数据包之后,会将其流状态添加或更新到流状态存储表中,并同时写入数据包描述符的特定元信息字段,供后续网络功能进行快速访问。以图4所示的流状态表为例,表中的主键是由网络层和传输层的关键信息组成的五元组,另外表中还存储有该五元组所对应流的状态信息。协议栈模块在处理数据包时,会首先在表中查找到数据包所对应的流在表中的位置,进而获取当前流的状态。协议栈模块会基于数据包的内容及其流状态,生成更新的状态,并覆盖保存至原流状态信息表以及数据包描述符中。因此,网络功能无须自行实现协议栈并维护连接状态,而只需要读取数据包描述符便可获得相应流的状态值。

(3) 网络功能自定义状态管理。除了流本身的状态,一些网络功能也需要维护其自定义的状态,如网络入侵检测中模式识别所用到的自动机状态,以及加解密中的密钥等。类似于流状态,维护网络功能的自定义状态同样是网络功能中的重要开销。在本文系统中,网络功能自定义状态管理使用了类似于流状态管理的方法,它将主要状态信息保存在共享的流状态表中。如图4所示,状态表中为每个网络功能预留了存储自定义状态的内存空间。网络功能在处理数据包时,只要使用描述符中的流指针便可获取其对应流的状态存储位置,因此网络功能可以在此方便地维护自定义状态,无须预先创建和维护额外的状态表。在流状态表中,系统为每个流中的每个网络功能的自定义状态预留了64 bit的空间。该大小对于绝大多数网络功能已经足够。但如果网络功能开发者希望使用更大的存储空间,可将状态存储空间分配到网络功能私有的内存空间中,并将该位置的指针保存在公有的状态表中。基于以上方法,网络功能只需要进行一到两次指针访问,便可以获取到数据包对应流的自定义状态,而无须自行维护流状态表。

(4) 超时机制。流生命周期的终止(例如TCP连接关闭)会使得流状态存储的空间被释放,以便为新的流存储状态提供空间。但是,由于NFV系统中的网络功能服务链通常有一定长度,可能会出现协议栈检测到流已经终止,而服务链中的网络功能依然在处理该流的数据包的现象,如果在此刻该流的状态存储空间被即时回收,那网络功能可能会访问到不正确的状态。为了避免该问题,本文系统使用超时机制,在流终止后仅记录当前的时间戳,以便让系统在足够长时间(例如10 ms)后再对该流状态的存储空间进行回收。

5 实 验

5.1 实验环境

1) 实验平台。本文实验服务器采用18核Intel Xeon E5-2695v4 CPU和128 GB的DDR4 ECC内存,并配备有NVIDIATitanX (Pascal) GPU(共有3 584个CUDA核心)。该服务器的网络接口使用具有双SPF插槽的IntelXL710 40GbENIC网卡。软件配置方面,服务器安装有Ubuntu 16.04,Linux kernel版本为4.15.0-43-generic。

2) 系统实现。我们的原型系统基于IntelDPDK(Data Plane Development Kit) 18.02实现了用户态的网络I/O。系统使用Docker 18.09.3容器平台,每个网络功能的进程运行在单独的Docker容器中。与此同时,原型系统的基础设施部分运行在独立的进程中,并使用共享内存与网络功能进行通信。为了使系统性能尽可能高效,我们将原型系统基础设施和网络功能中的每个线程与一个物理CPU核心使用sched_setaffinityAPI进行绑定,以消除操作系统上下文切换可能带来的性能开销。在流状态管理方面,系统基于libnids 1.24实现协议栈相关功能,并在此基础上实现了共享状态机制。为了便于比较,我们还实现了另一套不具备共享状态机制的对照系统。在对照系统中,除了原系统基础设施部分的协议栈和状态存储需要由各个网络功能自行实现,其他部分与原型系统完全相同。

3) 网络功能。我们实现了4个GPU加速的网络功能,以对系统在实际负载中的性能表现进行评估。我们实现的网络功能包括:(1)Firewall:针对包在TCP/IP层的五元组进行过滤[18],CPU上执行有状态过滤,GPU上执行无状态过滤。(2)IPsec网关:使用HMAC-SHA1 和AES-128 (CTR mode)进行网络包的加解密,有状态。(3)NIDS:使用Aho-Corasick算法[19]执行网络入侵检测,有状态。需要注意的是,各个已经实现的网络功能的GPU加速部分实现并不是高度优化、性能领先的最先进方案。本节的讨论重点在于使用共享状态管理机制是否能带来系统的整体性能提升,而不在于性能的绝对值大小。

4) 测试流量。使用基于IntelDPDK实现了一个网络流量生成器,并将其部署在一台配备Intel XL710 40GbE网卡的服务器上,以便提供实验中所需要的网络流量。这台机器与部署NFV系统的实验服务器使用速度为40 Gbit/s的光纤相连。在实验中,网络流量生成器可以连续不断地生成具有不同目的IP地址的TCP包,从而模拟包含大量TCP连接的网络流量。

5.2 网络功能中CPU时间开销

首先验证使用共享式管理机制时,网络功能处理数据包时CPU开销的变化。本实验中,使用Firewall、IPsec和NIDS三个GPU加速的网络功能,分别在原型系统与对照系统中测量了这些网络功能处理每批数据包时,CPU处理时间的平均占比。实验结果如图5所示,其中原型系统在以上各类网络功能中均有效地减少了CPU处理部分的时间开销占总开销的比重,在批数量为1 024时,三个网络功能的CPU处理时间的比重分别减少了26.7%、26.5%和24.0%。这是因为在原型系统中,网络功能可以利用共享式状态管理特性,节省大量协议栈处理和状态管理的计算,从而降低CPU-GPU计算流水线中CPU部分的开销。

图5 网络功能中CPU执行时间比例

另外,从实验结果可以看出,随着批处理数量的增长,网络功能中的CPU处理的开销占总处理开销的比例也显著增加。这是由于网络功能的CPU和GPU处理流水线中,CPU部分的并行度较低,因此其处理时间受到批数量的影响相比于GPU更大,最终体现在随着批数量增大,CPU处理时间比例也随之增长。这种效应在能够于GPU中大量并行处理数据包载荷的IPsec和NIDS两个网络功能中尤为突出。这类网络功能中,共享式状态管理对CPU处理开销的优化更为明显,因此,使用共享式状态管理后,后两种网络功能在CPU上开销降低的效果更为显著。

5.3 服务链上的吞吐量

本节分别在原型系统和对照系统上部署由多个网络功能组成的服务链,以评估共享式状态管理机制对系统吞吐量的影响。本实验中,我们使用的服务链由三个网络功能构成:Firewall-NIDS-IPsec网关。由于在GPU加速的网络功能中,通常可以通过调节每次传入GPU的数据包批数量(batchsize)来增加数据包处理延迟的代价换取吞吐量的提升,为了公正对比两系统,我们在GPU资源调度中实现了动态批数量调节机制,以确保两个系统中各个网络功能的延迟均相同(均为1 ms)。在此实验条件下,使用具有不同TCP流数量的网络流量分别原型系统和对照系统中测量了系统的最高吞吐量的相对差异,实验结果如图6所示。从实验结果可以看出,当数据包大小为512 B时,本文的原型系统实现了最多达2倍的吞吐量提升,而其中的主要原因在于网络功能中协议栈处理和状态管理开销的大大降低。原型系统中使用3.2节的状态管理方法,可以允许网络功能在无须实现协议栈的情况下,利用框架提供的包描述符实现流状态和自定义状态的快速维护,网络功能中CPU处理的时间开销降低,在网络功能处理总延迟一定的情况下,GPU资源调度器可以进一步通过调整GPU批数量提升GPU处理阶段计算效率,从而提升整个服务链数据包处理吞吐量。另外,从图6可以看出,本文原型系统相比对照系统获得的性能提升随着网络流量中流数量的增加而增长。这是因为流数量的增加可以显著增大协议栈处理和状态管理中的内存访问开销,而共享式状态管理有效地分摊了额外的开销,从而降低了网络功能中的CPU负载并防止其成为系统的性能瓶颈。

图6 服务链上共享式状态管理带来的吞吐量提升

6 结 语

本文对GPU加速的NFV系统中,利用虚拟化方式独立部署网络功能的一类系统中存在的问题进行了分析,发现这类系统存在网络功能的CPU处理阶段性能低效的问题。针对以上问题,本文提出一个新的针对GPU加速的NFV系统框架,通过共享式状态管理机制,减少网络功能中重复性的协议栈处理和流状态管理开销,以提升GPU加速的效果。通过对原型系统进行实验评估,本文验证了该机制有效地降低了GPU加速的NFV系统网络功能处理流水线中CPU阶段的开销,使得整个处理流水线更加高效,并在常见的网络功能服务链上达到了最高2倍的吞吐量提升。

猜你喜欢

流水线数据包虚拟化
二维隐蔽时间信道构建的研究*
熨烫女工
奇思妙想
C#串口高效可靠的接收方案设计
流水线
流水线上的神奇转换
网络数据包的抓取与识别
浅谈虚拟化工作原理
用户怎样选择虚拟化解决方案
虚拟化整合之势凸显