对标内核抓包极限提升udp收包率

    在海量数据的收集中,大部分网络日志都是通过udp协议传输的,所以为了保证日志的完整性,udp的收包性能显得极其重要,所以对此主题进行一系列的研究。

1.1 测试环境

操作系统:linux 3.10.0-229.el7.x86_64

网络带宽:千兆网

机器内存:32GB

处理器:4核

硬盘空间:1T

硬盘IO:实测300MB/S

JDK版本:1.8

 

1.2 测试用例

    1、报文大小:870b

测试对象:java udp,用户层抓包,内核抓包

测试结果:

速率PPSbio-udp用户层收包(tcpdump)内核收包(pf-ring)
3200100%100%100%
640099.17%100%100%
1300098.87%99.78%100%

 

从表格中可以看出在低速pps情况下,用户层收包和内核收包相差并不大,java的udp收包和tcpdump性能也比较接近,三者差距看不出来。


    2、报文大小125b

测试对象:syslog报文,不解格式收包,用户层收包,内核抓包

字节B速率PPSsyslogbio-udp用户层收包(tcpdump)内核收包(pf-ring)
125640098.91%100%100%100%
1300098.18%99.82%100%100%
2600061.89%97.44%100%100%
5000032.15%94.79%99.71%100%
60000//99.43%100%
70000//98.73%100%
100000//76.67%100%
200000//42.06%100%
500000//37.73%99.98%

 

降低报文大小,提高pps测试,可以发现:

1)收包率和报文大小关系不大,关键因素是报文发送速率。

2)syslog解析性能急速下降,大部分时间都花在解析工作上,导致丢包率非常高

3)内核收包在50Wpps下,依旧保持近100%的收包率,性能非常强劲

4)用户层抓包在7Wpps之后丢包率明显上升,可能受限于cpu中断

5)java 的udp收包和tcpdump差的并不多,其实原理是一样的,原因大概是日志的输出以及程序其他地方的性能损耗

6)此时,java 的udp收包最多做到1Wpps下逼近100%收包率

 

    3、报文大小50b

测试对象:用户层抓包,内核抓包

字节B速率PPS用户层收包(tcpdump)内核收包(pf-ring)
5067W29.74%99.46%
83W29.63%93.87%
100W29.42%79.18%

 

为了看看内核抓包性能究竟有多强悍,把速率提高到了100Wpps,发现一个有意思的事情,tcpdump的丢包率在降到30%左右,一直维持稳定,这儿我也没想明白。内核抓包在80Wpps后,收包率也有明显的下滑趋势。可能是cpu性能的原因,看来内核抓包也做不到百万级抓包,按照这个测试结果,他的性能应该就是每秒80W级别的处理速度(pf-ring的dna模式或许可以达到真正的百万级)。

 

1.2 性能优化

    通过上面的测试发现,内核抓包有着无可比拟的优势,逼近每秒百万级的性能,但是由于实际使用中,限制太大对网卡型号要求太高,需要重新编译网卡驱动,需要root的权限,c语言开发等等限制条件,导致应用到实际项目中,适用场景太少且难度较大。反观tcpdump的性能,虽然无法和pf-ring比,但是也有每秒5W的速度,然而我们的程序udp收包只有每秒4W多的速度,在5wpps收包率只有94%,这意味着每一亿条报文,就会丢失600W,还是非常吓人的,所以这方面还是非常有必要去优化提高收包率的。


优化一:

使用NIO流来处理网络消息,测试报文125b

速率PPSbio-udpnio-udp用户层收包(tcpdump)
6400100%100%100%
1300099.82%100%100%
2600097.44%99.82%100%
5000094.79%99.23%99.71%

 

优化结果:性能提升还是非常明显的,在5Wpps下,收包率提高了近5分点,意味着一亿条可以多收500W,但仍旧有几大十万的丢失,还是没有达到tcpdump的性能

 

优化二:

使用AIO流来处理网络消息,测试报文125b

速率PPSbio-udpaio-udp用户层收包(tcpdump)
6400100%100%100%
1300099.82%100%100%
2600097.44%99.76%100%
5000094.79%99.27%99.71%

 

优化结果:测试结果发现几乎和nio没差,看来收包层面已经达到极限了。与tcpdump依旧有0.5的差距,分析之后,定位是报文落地磁盘导致了收包过程有中断

 

优化三:

借鉴零拷贝的思想,落地磁盘也采用内存映射的方式,mappedByteBuffer

优化结果:有稍许提升,依旧距离tcpdump较远

 

优化四:

直接采用内存队列的方式,让收包线程完全脱离写磁盘的职责

速率PPSbio-udpaio-udp内存映射+队列+bio用户层收包(tcpdump)
6400100%100%100%100%
1300099.82%100%100%100%
2600097.44%99.76%99.99%100%
5000094.79%99.27%99.69%99.71%

 

优化结果:在26000PPS下,已经99.99%的收包率了,可以说保证能在2.5Wpps下不丢包。在5Wpps下也无限逼近tcpdump的性能,tcpdump我只测试了两次取得平均值,前者测试了6次取得平均值。先天条件如此,能用到的最新的技术全上了,到这个地步已经是极限了,不过应该可以应付99%的场景了。pf-ring以及tcpdump毕竟抓的只是pcap包,并不解析协议,所以这个已经是非常好的结果了。

 

最后附一张全测试的表格:

字节B速率PPSsyslogbio-udpnio-udp内存映射+队列+nio用户层收包(tcpdump)内核收包(pf-ring)
8693200 /100% / /100%100%
6400 /99.17% / /100%100%
13000 /98.87% / /99.78%100%
       100%
3933200 /100% / /100%100%
6400 /99.23% / /100%100%
13000 /98.75% / /99.99%100%
26000 /98.41% / /99.70%100%
        
 3200100%100%100%100%100%100%
125640098.91%100%100%100%100%100%
1300098.18%99.82%100%100%100%100%
2600061.89%97.44%99.82%99.99%100%100%
5000032.15%94.79%99.23%99.69%99.71%100%
60000// / /99.43%100%
70000// / /98.73%100%
100000// / /76.67%100%
200000// / /42.06%100%
500000// / /37.73%99.98%
        
5067W// / /29.74%99.46%
83W// / /29.63%93.87%
100W// / /29.42%79.18%
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值