在上一期,我们留下了一个问题:如何通过让专业的人做专业的事,提升虚拟化网元vSwitch的性能?
我们给出了两个选项:
先介绍选项A:使用DPDK,让OVS进化为OVS-DPDK。
在过去的专题中,我们对DPDK已经做了一定的介绍。DPDK是Data Path Development Kit的缩写,是Intel为了优化x86+Linux组合的数据平面处理性能,消除内核态-用户态切换、数据拷贝、缓存行乒乓、缺页-换页和资源互锁等性能卡点而在2013年推出的一个Linux下的开发套件。
针对这些性能卡点,DPDK做了以下改进:
关于DPDK,可以在 https://www.dpdk.org/ 的文档中详细学习。
利用DPDK重构的OVS,叫做OVS-DPDK,其性能大大高于OVS原有的版本。
先让我们重温一下OVS的架构图:
图中可以看出,传统的OVS有两个明显的性能卡点:
OVS-DPDK通过利用DPDK重构OVS解决了这两个性能卡点。OVS-DPDK的架构如下图:
OVS的虚拟交换端口netdev在OVS-DPDK中,通过netdev-dpdk实现。它可以通过组件librte_eth驱动物理网卡,同时通过librte_vhost与虚拟机打通零拷贝的高速数据通道。来自netdev-dpdk的数据在dpif-netdev中实现基于DPDK的高速转发处理。
DPDK的引入在解决了虚拟交换机的性能卡点同时,还可以利用网卡的硬件加速特性来进一步提升数据平面的处理性能。
我们在前面提到,为了降低线程切换的开销,DPDK会独占若干个处理器逻辑核(Hyper Thread, HT),并将每个HT绑定到若干网卡的队列,如下图所示:
图中,queue_0, queue_1, queue_2和queue_3是网卡的四个队列,来自外部的数据包会被均分到这四个队列中。CPU的ht28, ht29, ht30和ht31被Linux分配给DPDK使用,DPDK将这四个HT绑定到四个队列中,各自处理所属队列的数据包。
那么,网卡是依据什么把数据包分发到队列中的呢?最简单的分发方式是进行轮询(round-robin)或随机分发。但是,这种行为的后果可能是数据包的乱序。
如图,有属于同一条流的1,2,3,4四个数据包逐个进入if_eth2:
if_eth2将其均匀分配到四个队列,并由4个HT进行处理:
由于各CPU是并发处理的,最后送到出方向if_eth3的时间有前后差别:
最后发送出去的次序和接收的次序就不一致了:
这叫做数据包乱序。数据包乱序的后果是什么呢?
方老师想起了一个故事。
方老师有个朋友叫小H,小H虽然是个妹子,但小时候很调皮,懒得写作业,经常把同学们的作业拿过来抄一遍交差。
有一天,老师布置的作业是作文:写身边最熟悉的一个人。小H自己写了个开头,就把同桌的拿过来抄了。
第二天,老师让小H上台念作文。
小H甩着辫子走上讲台,高声朗读:
我的作文题目:我的爸爸
我的爸爸,今年四十三……,
他的名字叫兰兰,头扎两只羊角辫,戴着领巾是队员。
台下哄堂大笑,小H灰溜溜地逃回了座位。等待小H的将是……
网络数据包出现乱序的后果,也与此类似,会引起应用层的数据错误。
因此,解决这个问题的办法,是避免网络数据包乱序,把一条流只送到一个HT上进行处理。这种机制叫做流分类。
流分类的思想是从数据包中提取出标志着这条流的字段,计算出hash值,根据hash值除以队列的余数(mod模运算)。显然,在网卡中,这种运算是需要硬件辅助完成的。
从网卡的硬件辅助流分类开始,开启了一扇通往新世界的大门……
这个新世界就叫做:智能网卡。
请看下回分解。