《Linux开源网络全栈详解》学习笔记——高性能数据平面——内核旁路
高性能数据平面数据平面的性能很大程度上取决于网络I/O的性能,而网络数据包从网卡到用户空间的应用程序需要经历多个阶段。当数据包到达网卡后,通过DMA复制到主机内存空间并触发中断,网络协议栈处理数据分组后再交由用户空间的应用程序进行处理,整个过程的多个阶段都存在着不可忽视的开销,主要有以下几点。网卡中断网卡中断:轮询与中断是操作系统与硬件设备进行I/O通信的两种方式。一般情况下,网络数据包的到来都是
高性能数据平面
数据平面的性能很大程度上取决于网络I/O的性能,而网络数据包从网卡到用户空间的应用程序需要经历多个阶段。
当数据包到达网卡后,通过DMA复制到主机内存空间并触发中断,网络协议栈处理数据分组后再交由用户空间的应用程序进行处理,整个过程的多个阶段都存在着不可忽视的开销,主要有以下几点。
-
网卡中断
网卡中断:轮询与中断是操作系统与硬件设备进行I/O通信的两种方式。一般情况下,网络数据包的到来都是不可预测的,若采用轮询模式,则会造成很高的CPU负载,因此主流操作系统都会采用中断的方式来处理网络的请求。
随着网络I/O速率不断提升,网卡面对大量的高速数据分组将会引发频繁的中断,每次中断都会引起一次上下文切换(从当前正在运行的进程切换到因等待网络数据而阻塞的进程),操作系统都需要保护和恢复相应的上下文,造成较高的时延,并引起吞吐量下降。
-
内存拷贝
处理网络数据时,内核从内核空间将数据拷贝到用户空间。发送数据时,需要从用户空间拷贝到内核空间。每次拷贝都会占用大量的CPU、内存带宽等资源,代价昂贵。
-
锁
Linux内核的网络协议栈实现中,存在大量的共享资源访问。当多进程需要访问同一共享资源时,为共享资源上锁或者去锁过程通常需要几十纳秒。此外,锁的存在也降低了整个系统的并发性能。
-
缓存未命中
当造成频繁缓存未命中,会严重削弱数据平面的性能。
针对这些开销,主要有以下的优化技术手段和项目。
高性能数据面基础
对于数据包处理而言,使用的主流平台一般大致可分为硬件加速器、网络处理器及通用处理器。
硬件加速器和网络处理器的优点是高性能、低成本
通用处理器在复杂多变的数据包处理上更有优势
接下来主要是对通用处理器上高性能数据包处理做一些介绍。
内核旁路
内核旁路,即绕过内核中的低效模块,直接操作硬件资源。
-
内核的性能问题
由于使用硬件抽象和硬件隔离的方法,给上层应用程序的开发带来了简便性,但也导致了一些性能的下降。
网络方面:吞吐量减少和报文延迟的增加。
数据包从网卡到应用程序要经过内核中的驱动、协议栈处理,然后从内核的内存复制到用户空间的内存中,加上系统调用要求的用户到内核空间的切换,都会导致内核性能的下降。
-
内核旁路技术
应用程序不通过内核直接操作硬件。
把网络驱动从内核移到用户空间后,即使出问题也不会像之前在内核中那样使操作系统崩溃。
-
开源方案
内核旁路之后,应用程序直接和硬件打交道,但也需要解决硬件的抽象接口、内存分配和CPU调度等问题,甚至还有网络协议栈的处理。
这方面有DPDK、Netmap、OpenOnload及XDP等开源框架。在一定程度上起到了硬件抽象和隔离功能,简化了应用程序开发。
DPDK是一个全面的网络内核旁路解决方案,不仅支持众多网卡类型,也有多种内村和CPU调度的优化方案。
Netmap是一个高效的收发报文的I/O框架,已经集成在FreeBSD内部,也可以在Linux下编译使用。和DPDK不同的是,Netmap并没有彻底地从内核接管网卡,而是采用一个巧妙的Netmap ring结构来从内核管理的网卡上直接接收和发送数据。
OpenOnload是一个开源的、高性能Linux应用程序加速器,可为TCP和UDP应用提供更低的、可预测的延迟和更高的吞吐率。和DPDK与Netmap不同的是,前两者都是高性能I/O框架,而OpenOnload更多的是一个内核旁路的协议栈。
OpenOnload在用户空间实现了TCP和UDP的协议处理,又通过和内核共享部分协议栈信息的方式较好地解决了应用程序的兼容问题。
OpenOnload的底层I/O主要通过EF_VI技术来实现。EF_VI绕过内核协议栈把网卡中部分网络流量发送到用户空间的协议栈中。每个EF_VI实例可以访问一条特定的RX队列,RX队列对内核是不可见的。
另一部分流量仍然保留在内核中处理,这种技术能够灵活地利用内核和旁路方案两方面的优势,在DPDK社区称为“分叉驱动”。要使用这种技术,需要一个支持多队列的网卡,同时也需要支持流控制和SR-IOV。
有了这种网卡,可以实现如下功能:
-
正常启动网卡,让内核管理一切。
-
创建一个SR-IOV中的虚拟网卡(VF)
-
把特定接收(RX)队列如1号加入VF中
-
通过流控制规则将一个特定的网络流引入到1号RX队列中。
完成这些,剩下的步骤就是利用DPDK用户空间的API,从1号RX队列上接收数据包并处理。同时,其他任何队列在内核中的正常处理都不会受到任何影响。
XDP是针对内核在I/O和协议栈两个方面的性能问题提出的解决方案之一。XDP绕过了内核的协议栈部分,在继承内核I/O部分的基础上,提供了介于原有内核和完整内核旁路之间的另一种选择。
更多推荐
所有评论(0)