当前位置: 首页 > 科技观察

五分钟看懂抓包的魔力:DPDK

时间:2023-03-14 11:01:52 科技观察

我是一个网络监控软件,我开发的任务是监控进出网络的所有通信流量。一直以来,我的工作一直很好,但是随着我监控的网络越来越大,网络中的通信流量越来越大,我开始有点不堪重负,逐渐出现丢包,而且出现这种现象最近越来越严重了。一天晚上,程序员小哥把我从硬盘上叫醒了。“几点了,你还不下班吗?”,我问小弟弟。“哎,产品经理说我下个月一定要支持10G网络流量的分析,我压力很大,没办法,只能加班了。”说完,他理了理自己越来越稀疏的头发。“10Gbps?10Gbps?开什么玩笑?这节奏会要我的命的。”“是不是,我好着急,快说,你工作这么久,有什么地方不舒服吗?”或者你说说你觉得有什么可以改进的地方。”小弟弟一脸诚恳的看着我,我想了想说:“要说不开心,确实有!就是我现在花太多时间复制数据包,把数据包从内核空间复制到用户态空间。少量的数据曾经很好,现在网络流量这么大,真是要了我的命。”小哥叹了口气,“哎,这个改不了,数据包是通过操作系统的API获取的,操作系统读取的从网卡。拿去吧,我们是一个工作在用户空间的程序,我们得复制一次,没办法。想想别的?”我也叹了口气,“没关系,还有一个槽,收到的数据包能不能直接交给我,不用交给系统的协议栈和netfilter框架?”反正拿到手后还要重新分析,每次都要过一遍。他们的工作效率很低。是不是拖我的后腿了?”小弟皱了皱眉,眨了眨眼睛道:“大哥,这件事我们改不了。我的水平也有限。我没本事改造你绕过操作系统,让你直接去处理网卡。或者,你再说一个怎么样?呵呵”“好吧,我不会为难你的。有一个简单的问题,你得改一下。”“有什么问题,告诉我?”“我在线程切换上花了很多时间。再次获得定时执行后,经常发现自己换了一个CPU核。之前的缓存失效了,还得重新建立缓存,浪费很大!能不能让我的工作线程独占CPU核心,这样我的工作效率肯定能提高不少!”小哥想了想,说:“没问题,你可以有这个!”可以用threadaffinity来做,我给你画几个core,这样他们就不会参与系统的线程调度分配,专供你使用。这件事会写在Letme!”中断问题后的几天,程序员小弟给我升级了,让我的几个工作线程可以独占CPU核心,工作效率提高了很多。mega-流分析指标还是差得很远,一天晚上,程序员小哥又跟我聊了起来,“现在分析能力确实提高了,但是离目标还差得很远。”快点告诉我。说吧,你有什么改进的建议吗?”“有,但我估计你会说改不了。”我翻了个白眼。“先说吧!”“现在这个数据包是用表格ofinterrupttonotifiedread,我可以不中断自己获取吗?你不知道,每次打断都要保存上下文,从用户态切换到内核态,那么大的流量,这个成本没了!”,我激动地说。小哥听完沉默了”“你看,我说你改不了!算了,跟产品经理说,这个需求不能尽快满足,我们可以放松自在”“那不行,这个项目对我来说很重要,希望升职和升职靠你涨工资,走上人生巅峰!”小哥坚定地说,“不行就再找几台机器。”给我抄几份,软件不行,就靠硬件来发挥!”我对他使了个眼色。“你这么说,老大肯定不会同意的。”“那我也没什么事了,跟你说实话吧。好吧,如果我要能搞定10G的网络流量,我得绕过操作系统,我得自己从网卡上读取数据包,你好好研究一下,哪有什么怕困难的你要升职加薪!”,我给小弟打气。小弟弟点点头,“你说的是,我一定会做的,给我点时间。”DPDK这样一个多星期了,程序员小哥就再也没有来找过我,也不知道他的研究怎么样。向上。过了几天,他终于又来了。“出来吧!我找到办法了,明天开始改造你!”我来了兴趣,“什么方法?你要怎么改造我?”》这个新方案可以解决你之前提出的所有问题,可以让你直接去处理网卡,不需要中断通知读取数据包,不需要把数据包交给系统协议栈和netfilter框架进行处理,不用频繁切换用户态和内核态!”,小哥越说越激动啦!“你太厉害了,这些问题你都能解决!你是怎么做到的,是什么原因?”我好奇的问道。小哥有些尴尬,“我没有那个本事,其实这是别人开发出来的技术,我就拿来用。”!”,心里有些不安。“这个你别管。这种技术称为DPDK。它是英特尔开发的一项技术。靠谱!”接下来,程序员大哥给我介绍了这个叫DPDK的技术原理。有了DPDK,我可以通过操作系统的用户态来驱动UIO,可以读取网卡的数据包在用户态通过轮询,不再需要打断!直接在用户态读取,不再需要发送数据包在内核空间和用户空间之间来回移动,读取完直接分析,不用浪费时间with系统协议栈和netfilter,简直完美!”不止于此!还支持大页内存技术”,小哥得意地说。“大页内存?这是什么?”“默认情况下,系统不管理4KB大小的内存页?这个单位太小了。对于我们的服务器内存来说,会有大量的内存页。为了管理这些页,会有大量的页表项。CPU中用于内存地址转换的缓存TLB的大小是有限的,页表项过多会频繁失败,降低内存地址转换的速度!”闻言,我恍然大悟:“我知道了,加大这个单元,管理的内存页少了,页表项少了,TLB不容易失效,地址转换也能快点吧?”“对,猜猜是什么尺寸?”小哥“双倍,8KB?”见小哥摇头,我又猜了:“是16KB吗?”“太保守了,可以支持2MB和1GB两种大小!”“好大,厉害没了!”空转问题第二天,程序员小哥开始对我进行全面重构,升级后尝试运行,发现一个问题:如果数据包不多或者没有数据包接下来,我的轮询基本是浪费时间,一直闲着,自从我独占了一个核心,这个核心的占用率有一直都是100%。其他很多程序都抱怨我,占用**不**。于是,程序员小哥又给我升级了,使用了InterruptDPDK模式:当没有数据包处理的时候,会休眠,改成中断通知。也可以和其他线程共享CPU核心,不再独占,但是DPDK线程会有更高的调度优先级。一旦数据包多了,我就切换到轮询方式,可以灵活切换。程序员小哥连续两周加班。经过一番优化升级,我的数据包分析处理能力有了很大的提升。可惜经过几轮测试,面对10Gbps的流量还是有些力不从心,还是差了点。小弟弟有些气馁,“我不知道该怎么办,你觉得有什么可以改进的地方吗?”“我现在基本是满负荷工作,应该没有提升的空间了,现在只有数据竞争的时候才能喘口气,等数据锁定,线程切换的时候,就休息一下。”小弟弟想了几秒,顿时眼睛一亮,高兴地说:“有!”还没来得及问,就关机下班了~程序员小哥要对我做什么?本文转载自微信公众号“编程技术宇宙”,可以通过以下二维码关注代码,转载本文请联系编程技术宇宙公众号。