云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

谷歌云_数据库性能指标_测评

小七 141 0

Netmap中的单RX队列内核旁路实现高包速率网络

在上一篇文章中,我们讨论了Linux内核网络栈的性能限制。我们详细介绍了允许用户空间程序以高吞吐量接收数据包的可用内核绕过技术。不幸的是,所讨论的开源解决方案都不支持我们的需求。为了改善这种状况,我们决定为网络地图项目捐款。在这篇博客文章中,我们将描述我们提议的改变。二元树袋熊的CC BY-SA 2.0图像我们的需求在CloudFlare,我们一直在处理大数据包洪水。我们的网络不断地接收大量的数据包,这些数据包通常来自许多同时发生的攻击。事实上,这是完全有可能的服务器刚刚为您提供这篇博客文章正在处理数百万包每秒洪水。由于Linux内核不能真正处理大量的数据包,我们需要解决它。在包泛洪期间,我们将选定的网络流(属于flood)卸载到用户空间应用程序。这个应用程序以非常高的速度过滤数据包。大多数数据包被丢弃,因为它们属于洪水。少量的"有效"数据包被注入内核,并以与正常流量相同的方式进行处理。必须强调的是,内核旁路只对选定的流启用,这意味着所有其他数据包都像往常一样进入内核。这个设置在我们使用Solarflare网卡的服务器上运行得非常好—我们可以使用ef逯vi API来实现内核绕过。不幸的是,我们在使用Intel IXGBE NIC的服务器上没有此功能。这是Netmap进来的时候。网络地图在过去的几个月里,我们一直在思考如何在非Solarflare网卡上实现对选定流的旁路(又名:分叉驱动)。我们已经考虑过PFéu RING、DPDK和其他定制解决方案,但遗憾的是,它们都接管了整个网卡。最后,我们决定最好的方法是用我们需要的功能来修补Netmap。我们选择Netmap是因为:它是完全开放源代码的,并在BSD许可下发布。它有一个很棒的与NIC无关的API。它很快:可以轻松达到线速。该项目维护良好,相当成熟。代码质量很高。驱动程序特定的修改很简单:大部分的魔法都发生在共享的Netmap模块中。添加对新硬件的支持很容易。引入单接收队列模式通常,当网卡进入Netmap模式时,所有的RX队列都与内核断开连接,并可供Netmap应用程序使用。我们不想那样。我们希望将大多数接收队列保持在内核模式,并且只在选定的RX队列上启用Netmap模式。我们称此功能为"单接收队列模式"。其目的是公开一个最小的API,它可以:在"单接收队列模式"下打开网络接口。这将允许netmap应用程序从特定的RX队列接收数据包。同时将所有其他队列附加到主机网络堆栈。按需从"单接收队列模式"中添加或删除接收队列。最终将接口从Netmap模式中移除,并将RX队列重新附加到主机堆栈。Netmap的修补程序正在等待代码审查,可从以下位置获得:https://github.com/luigirizzo/netmap/pull/87从eth3 RX queue 4接收数据包的最小程序如下所示:d=nm_打开("网络地图:eth3~4",空,0,0);同时(1){fds={fds:d->fd,事件:POLLIN};轮询(&fds,1,-1);环=网络地图环(d->nifp,4);同时(!nm环空(环)){i=响铃->cur;buf=NETMAP_buf(环,环->槽[i].buf_idx);len=环->槽[i].len;//过程(buf,len)ring->head=ring->cur=nm_ring_下一个(ring,i);}}这段代码非常接近Netmap示例程序。实际上,唯一的区别是nm_open()调用,它使用新的语法网络地图:ifname~排队号码。再次,当运行此代码时,只有到达RX队列4的数据包才会进入netmap程序。所有其他的RX和TX队列将由Linux内核网络堆栈处理。您可以在此处找到更完整的示例:https://github.com/jibi/nm-single-rx-queue隔离队列在多队列网卡中,由于RSS的存在,任何包都可能以几乎任何RX队列结束。这就是为什么在启用单接收模式之前,必须确保只有选定的流进入Netmap队列。为此,有必要:修改间接表以确保不会有新的RSS哈希包出现在那里。使用流导向专门将一些流定向到隔离队列。解决RFS-确保没有其他应用程序在运行Netmap的CPU上运行。例如:$ethtool-X eth3权重1 1 1 1 1 0 1 1 1 1 1 1$ethtool-K eth3 ntuple打开$ethtool-N eth3流类型udp4 dst端口53操作4这里我们设置了间接表,以防止流量流向RX队列4。然后我们启用流控制,将目标端口53的所有UDP通信排队到队列4中。尝试一下下面是如何使用IXGBE网卡运行它。首先抓住来源:$git克隆https://github.com/jibi/netmap.git$cd网络地图$git checkout-B单接收队列模式$./configure--drivers=ixgbe--kernel sources=/path/to/kernel加载netmap修补模块并设置接口:$insmod/LINUX/网络地图.ko$insmod./LINUX/ixgbe/ixgbe.ko公司$#分配中断:$(让CPU=0;cd/sys/class/net/eth3/device/msi_irqs/;对于IRQ in*;do\echo$CPU>/proc/irq/$irq/smp_关联性列表;让CPU+=1完成)$#启用RSS:$ethtool-K eth3 ntuple打开在这一点上,我们开始用6M短的UDP数据包淹没接口。htop显示服务器正忙于处理洪水:为了抵御洪水,我们启动了网络地图。首先,我们需要编辑间接表,以隔离RX队列#4:$ethtool-X eth3权重1 1 1 1 1 0 1 1 1 1 1 1$ethtool-N eth3流类型udp4 dst端口53操作4这导致所有的洪泛数据包都转到RX队列4。在将接口置于Netmap模式之前,必须关闭硬件卸载功能:$ethtool-K eth3 lro关gro关最后,我们启动了netmap卸载:$sudo taskset-c15./nmu卸载eth3 4[+]启动接口eth3环4上的测试02[+]UDP pps:5844714[+]UDP应用程序集:5996166[+]UDP应用程序集:5863214[+]UDP应用程序集:5986365[+]UDP应用程序集:5867302[+]UDP pps:5964911[+]UDP应用程序集:5909715[+]UDP pps:5865769[+]UDP应用程序集:5906668[+]UDP pps:5875486如您所见,netmap程序在一个RX队列上能够接收大约580万个数据包。为了完整起见,下面是一个htop,它只显示一个内核正在忙于Netmap:谢谢我们要感谢Pavel Odintsov,他建议以这种方式使用Netmap。他甚至准备了我们的工作基础上的最初的黑客攻击。我们还要感谢Luigi Rizzo,感谢他在网络地图上的工作以及对我们补丁的反馈。最后的话在CloudFlare,我们的应用程序栈基于开源软件。我们感谢这么多开源程序员的出色工作。无论何时,只要我们能为社区做出贡献,我们希望"单一RX网络地图模式"对其他人也有用。您可以在这里找到更多CloudFlare开源软件。