笔记是边读边写的旁注,比较乱,没有整理就丢上来了。
可以说不仅要说fast packet process servey,也同时是一篇packet process的综述了。packet processing,放在传统协议栈的视角中看,也就是L2、L3的一个小部分,但是细看,里面也是有特别多的内容的,在这一小点上深究,也有特别大的意义。
Introduction
Intent的流量水平上去了,而且一直都是增长的势头;网卡硬件的速度上去了(在如今的数据中心,网口都有40Gbps的速率);pkt process algorithm 也升级了;为了降低网络硬件的缺点(复杂性,周期长,贵重),为了方便编排、灵活性、可编程、移植性等,VNF也出现了;
网卡硬件的速率发展到 40Gbps的今天,包处理速率(反映在吞吐量上)却没能有效的提升。这是为什么呢?深层原因就是 protocol stack architecture 和 operating system machanism 的设计了,已经严重限制了硬件性能提升所带来的好处。
一个pkt从wire到application的时间可能比从网卡上发出去的时间超过十到二十倍。也就是说,在系统中,在内核中,在协议栈中的时间,实在是太长了。以前硬件慢的时候,还能匹配,限制硬件快起来了,软件和内核就成了一个桎梏。在10Gbps以上,kernel就很难以线速了支持 pkt process。
UIO就是为了 bypass kernel 思想的设计。加入了对NIC的多队列特性的软件支持。
如果要引入programmable 又有 high performance,基本方法有两种。
- 定制化硬件,例如OpenFlow。
- 从软件方面着手,优化包处理性能。软件本来就是可编程的。而且,这第二种方法可以使程序员在通用的计算机、硬件环境下编程。更加友好。
一种“半专业”方案:NP 网络处理器和传统通用处理器相结合。NP是专门为处理数据包而定制的可编程通用处理器(就像传统处理器一样,但添加了专门为了处理pkt的部分)。
深入浅出DPDK上描述NP的局限性:成本和特定领域的特性限制了其市场规模(只能用于通信设备)。且不同厂商不同架构的NPU的遵循的架构、编码规范不尽相同,相比DPDK采用的通用化处理器和C语言,开发人员的成长,生态环境的构建都比较困难。
现场可编程门阵列 FPGA,更加多才多艺。利用GPU来加速网络包处理,例如 PacketShader。
底层硬件是CPU、GPU、FPGA各有优缺点。
GPU对于多线程的应用登峰造极。
在CPU上写程序更容易,CPU有更好的API(相比GPU和FPGA)
FPGA相比其他两者更加节能,处理时延也更低,但由于要使用硬件语言,编程不容易。
此外,FPGA提供确定性时序,延迟比GPU低一个数量级
上述解决方案适合用于虚拟化环境,尤其因为虚拟化环境带来的不可避免的性能损失(更要想方设法提高pkt process速率了)
Background
路由器的操作分为两类:time-critical 和non-time-critical,前者对应 fath path,后者对应 slow path。大概就是时延敏感类型。fath path 对应的大多数pkt的处理,要以比较低的时延和比较高的吞吐量处理pkt,达到Gb的数据率。后者就是用于management, error handling and maintenance 目的,数据率不高。在某些语境下,fast path 也可以表示传输高优先级的pkt。fast path 相比 slow path 就要引进特定的优化措施和指令等。在包处理系统中,内核协议栈是典型的 slow path,fast path就要特定优化,或者在硬件上实施来加速等。
Time-critical 操作:转发和头部处理。fast path 在传统路由器中都是要用硬件去做的,因为对于一个个pkt,在这部分的时延要求很严格。流分类、QoS服务差异化、目的地址查找、checksum计算、packet 有效性验证、lifetime control(TTL-1),经常都是设计在硬件中的。
Non-Time-critical 操作,也就是 slow path 处理的是:
- 出错的包,发送ICMP消息
- TCP keep alive消息
- 路由协议,路由表的更新的包
- 管理协议的消息,SNMP
可以看出,slow path 就是这种不那么要紧的操作。
分片被配置成了slow path,由于分片给router带来额外的复杂性(丢失某个分片需要重传),这也会导致在相同吞吐量的情况下,实际传输的数据要少。而且,路径MTU发现的机制运用的很广泛,例如,对于IPv4,要收到PDU>MTU的,就丢包并返回ICMP消息带上MTU大小。所以,IP分片基本上是配置在slow path中的。
以上就是 packet processing 的传统过程。
历史上的原因来讲,层次型的网络模型,导致了链路的数据率,与包处理速率,这两者有一种contest。包处理的时间是每一个包都要一定的时间处理。所以对于确定的吞吐量,包长越小,会有越多的overhead。
当处理每个包的开销比(相对)较小时,包处理速率的限制是NIC的速度。当处理每个包的开销(相对)较大时,包处理的限制就是在于CPU和OS的架构的短板。
深入浅出DPDK有一个模型。bps是一个衡量链路速度的参数,而衡量包处理性能使用的是每秒包转发率pps。当说到以太网的接口带宽例如10Gbps时,指的是数据率(比特每秒),而因为不可能每个比特都是有效数据,所以pps肯定有一个由bps所决定的理论上限:bps /( 帧的其他部分:间隔、前导、检验码)+(包长))。越小的包,理论上限越大。有一个数据:对于64B的包,40Gbit/s的链路,pps为59.5M,倒数就是对于一个packet,允许的process时间为16.8ns。这个时间,对于一个主频为2GHz的CPU,只有33个时钟周期。再考虑到一个现实:一次cache miss的主存的读取就需要上百个时钟周期。理论的天花板要达到,是一件很难的事情。传统协议栈和OS内核的模式,会给每一个pkt带来固定的overhead。这也就解释了为什么当网卡的线速上身到Gbps级别时,传统包处理模式的overhead和bottleneck了。
高吞吐量,一定要求低包处理时间!因为如果在网卡硬件线速很快时,但包处理时间过高,必然会导致包到达的速率超过包被转发出去的速率,这样必然会导致Rx queue(或者说buffer)不足以handle input traffic而导致overflow,总体 throughput 下降。OS与网卡的差异性:网卡只需要负责传包就完事了,物理设备的速率随着时代的发展越来越快。对于OS,协议栈、OS高层的软件部分与硬件隔得很远。上下文切换、锁、mutex等要引入很多开销。差异大到一定情况时,就会因为木桶效应而导致问题了。
软件packet processing的五步:
- NIC接受到packet -> DMA
- CPU 处理
- 将包进入目标网口的队列
- 改写队列有关数据结构
- 发包。DMA->NIC
从这五步考虑优化传统OS模型,可以优化的很多:bypass kernel、cache align、batch、hugepage、userspace、parallelism、affinity……这些在了解DPDK之后都不会不熟悉。
关于流水线、利用CPU的多核能力进行并行处理方面,文章指出仅仅把packet process分成多个部分的并行操作,仅在这方面优化是不够的。因为操作系统的机制就不适合高数网络流量的处理。为了有效利用多核,也就引入了多张网卡。网卡被分成 RX/TX queues,举例来说,特定的Rx queue 分配特定的中断号,然后由特定的core来负责执行。queue的个数由网卡硬件,CPU核数限制。接收侧扩展(RSS)就像是一种利用网卡多队列技术的负载均衡技术。分配packet process到不同的core上工作。
SOFTWARE IMPLEMENTATIONS
click是第一个软件模块化路由器。先前,路由器是固有的固件,不灵活,很难扩展功能。click把每一个模块都视为一个element,然后由element组成workflow的形式,完成pkt processing。
RouterBricks 一款软件路由器框架,运行在多核服务器或多个服务器上。目的是优化pkt processing性能,达到与标准硬件路由器相同的处理速率。
FastClick将DPDK或Netmap应用在click
Netmap是硬件的框架,主要移出了三个方面的开销:
- 对于每一个pkt动态内存分配,取而代之是的是preallocating resources
- 系统调用开销,amortized over large batches)
- 内存copy,sharing metadata and buffers between kernel and userspace
NetSlice 提供一种OS抽象,在userspace处理pkt,达到与核心数线性相关的包处理速率。粗粒度的空间上划分硬件,细粒度的硬件控制API。硬件的空间划分导致了网络流量的划分,一个划分称为一个slice。一个NetSlice包括软硬件,task,traffic等有多队列,并行;没有使用零拷贝。实验达到9.7Gbps的速度
PF_RING (DNA) 高性能包捕获框架,让商用PC变身成网络测量工具,可以分析实时流量。大部分传统的网络工具(tcpdump、ethtool等)基于libpcap,Berkeley Packet Filtering,中断机制限制了包捕获的效率。mmap改进版本的libpcap 减少了内核与用户控件的pkt移动时间,但没有减少从NIC到Kernel的时间。这是引PFRING的原因。PFRING有内存池机制,应用程序工作在用户态,减少了系统调用的开销。PFRING也是从NIC轮询pkt到ring,app直接从ring读取pkt。NIC 寄存器和主存都映射到用户空间,NIC就可以直接完成将pkt -> ring的操作而不需要经过Linux NAPI。CPU只需要处理PKT本身而不需要负责在NIC和CPU之间转移PKT。
DPDK,不用多说了,一句 provided support for Intel x86 CPUs 就比其他 solution 屌不知道多少。
(基于GPA和FPGA的solution暂时跳过没看)
INTEGRATION POSSIBILITIES IN VIRTUALIZED ENVIRONMENTS
本章介绍虚拟化环境中结合以上几种solution的integration。主要看的就是OVS-DPDK
传统OVS中,fastpath传输流表命中的pkt,从内核中快速通道发包。slowpath传输没有命中流表的pkt,传给userspace的守护进程,守护进程更新内核的流表,然后后续的pkt(属于同一个流)就可以进入fastpath被转发了。
OVS-DPDK就利用了DPDK的PMD旁路内核的特质,fastpath被配置在了用户态,加速效能,减弱了内核网络协议中带来的开销。缺点呢,就是OVS-DPDK很耗CPU的性能。
根据某篇论文得出的结论:DPDK的效率是真的牛批。
LATEST APPROACHES AND FUTURE DIRECTIONS
这一部分也非常有用,提供下一步继续的方向。
VPP是 linux foundation 下属FD.io的一个项目,是一个可扩展平台框架,提供开箱即用的交换机、路由器功能。利用了DPDK,提升了通用CPU上的包处理速率。
在OpenDataPlane集合VPP实现SmartNIC。ODP是一组开源、多平台API,用于软件定义的数据平面。ODP三个目标:在多平台实现便携的应用;允许数据平面APP无需特定于平台的专门编程;允许应用程序扩展自动支持多核架构。
OpenFastPath:开源高效的TCPIP协议栈,同样 based on DPDK
[152] P4程序编译器,生成DPDK的C代码,有点意思哦。 “High Speed Packet Forwarding Compiled from Protocol Independent Data Plane Specifications,” in Proceedings of the 2016 ACM SIGCOMM Conference, ser. SIGCOMM ’16.
OpenState,交换机内部的功能控制,无需外部控制器的交互和控制。
BESS (Berkeley Extensible Software Switch) 伯克利可扩展软件交换机。