【前言】
使用DPDK开发的朋友应该都了解使用dpdk的fwd线程的工作模式是polling模式,即100%轮询的方式去加速网络IO,这样我们在操作系统层面上来观察目标processer会发现usage一直为100%,但是这真的是系统的真实负载么?很显然并不是,本文给出一种方法来计算dpdk的fwd线程的真实负载的方法。
【场景】
使用DPDK头痛的一点就是DPDK的fwd线程工作在polling模式,会直接消耗一整个processer的计算资源,有的时候为了性能考虑,往往还会给当前processer设置isolcpus,将当前processer从内核的CFS调度器中“剥离”出来,防止有其他的task被“不长眼”的CFS调度器调度到和fwd线程同一个processer上,出现context switch,引起性能下降。
而工作在polling模式的fwd线程会出现非常蛋疼的一点就是面临“无法有效的感知当前processer的压力”的问题。查看操作系统的相关信息,会发现这个processer的usage一直处于100%,但是真实情况真的是这样么?并不是,在流量处于低谷的时候,这个processer往往会出现空转的情况,就是调用dpdk的api收包函数调100次,次次收包个数都是0,因为根本就没有流量,所以需要一种新的方法来计算使用dpdk fwd线程的负载情况。
额外多说一点,为了防止fwd线程出现空转,目前有不同种方法来“尽量”解决这种空转问题,主流的通常有两种:
- 利用sleep函数,简单粗暴,结合内核的NAPI策略,设定一个期望收包个数值,当实际收包个数小于这个数值就判断当前流量不大,sleep一下。
- 利用dpdk的rsc中断来解决,由于uio驱动只有一个中断号,因此这种方法在uio驱动基本没法用,只能在vfio场景下用。
当然怎么防止dpdk fwd线程出现空转的解决方法不是这篇文章想讨论的主题,我后续会写我个人的解决方案,本篇文章更多的会聚焦在如何估算负载情况。
【分析】
这里首先说明一下,这个方法里面有一部分是来自于dpdk社区的一篇文章,由intel专家ilia所写,这里是文章原文地址,本文中会有不少部分来自于这篇文章原文,但是本篇文章在实际应用中仍然是有些地方需要注意的。
https://software.intel.com/en-us/vtune-cookbook-core-utilization-in-dpdk-apps
接下来我会结合实际应用和ilia的文章来阐述怎么“估算”dpdk fwd线程的负载情况。
先直接说结论:
在不同的流量压力下,dpdk fwd线程对某个网卡队列的收包行为实际上是存在一定的分布的
这句话怎么理解呢?实际上这句话就是intel专家ilia那篇文章的主要思想。
这句话完整的解释是这样的:
在不同的流量压力下,dpdk fwd线程对某个网卡的某条队列进行收包操作,单位时间内的收包次数中,收到数据包的个数存在一定的分布
举个例子:
我在10s内,执行了1000次收包操作,在满载的流量压力下,1000次收包可能次次收包都能收上来32个数据包;在50%压力下,我可能只有300次收包是一次调用收上来32个包;在10%的压力下,我可能只有不到100次的收包是一次性收上来32个包。
如果能明白这个例子,就能明白前面所说的结论,关于这个结论可以直接看【测试结果】一章,观察测试结果是否符合结论。
以收包个数为0的次数为基准,那么可以推导出一个公式:
【测试结果】
【结论】
【另一个问题:DPDK应用怎么“预见”即将可能发生的丢包】