Ineedle驱动方式dpdk测试性能

这次主要是测试在dpdk方案下,ineedle的处理包的性能。

发包工具:使用立永当时写的一个发包工具:linux_pcap

做法:

大概是从网上抓取了一些数据包,将源ip替换为随即ip,sip替换为要监控的ip地址。然后用pcap工具进行发包

设备:

这次发包工具运行在测试机上,也就是这次跑ineedle的DELLR430设备,用em2端口发包,用p1p4接口来接收包。

注意:

要打开网卡的混杂模式。

说明:

这个设备性能比较好,发包正常的包最大速度能够达到:75M/s。单包发送(排除IO干扰)情况下速度:96M/S,转化为bps大概有800MBPS。
如果在普通设备上的速度是比较小的,具体数值忘记了。

其它因素:

发包工具发的报文是从网络上抓的一些包作为样本,然后对源ip和和目的ip进行替换,源ip随机替换,目的ip替换为服务器配置要监控的域名和ip,进行发包;
包中可能会有错误,貌似会有点影响正常测试的准确性。

有时间可以再优化一下发包的工具,看看能不能提高一下测试速度,主要是想排除一下IO等待的干扰。

 

暂时分为2个步骤:

1、单独测试dpdk的抓包能力

最大速度 96M/S 的时候打到DPDK网口上时候,由于dpdk只与ineedle做了简单的包传递,ineedle并没有实际处理包,因此ineedle对其影响不大,可以准确测试dpdk底层的性能。
由于发包工具最大发包的速度也就是这个速度,因此现在只能测试到这个速度了。在这个速度下dpdk比较稳定,在ineedle和dpdk的相互通信情况下完全没有丢包现象;其实也差不多快达到千兆网口的极限了。

2、ineedle和dpdk正常交互时用正常数据包测试

这次是让ineedle正常处理数据包,走完全的流程;其实说是完全的流程也不太准确,因为发包工具发的包好多可能是错误的、不正常的或者说不能完全走ineedle全程的数据包,好多从中间部分就被处理掉了。当然这些包可能会影响到我们测试的速度,但是也没办法,现在只有这一个工具。大概测试过程:

每组数据测试5min,发包速度是从低到高:

13M/S————————不丢
20M/S————————不丢
30M/S————————不丢
38M/S————————不丢
48M/S————————不丢
53M/S————————不丢
58M/S————————不丢
63M/S————————不丢
66M/S————————不丢
72M/S————————不丢
80M-82M/S——————丢包

测试结果,暂时为这个样子。

————————————————————— 我是分割线 ———————————————————————————————

下边要总结出ineedle和dpdk系统中处理包、丢包情况;主要也分为2部分进行统计:

一、驱动层dpdk

包总数:从dpdk网卡进去的包的总数量。
下边的情况我们会将这些报文进行丢弃:
【1】DPDK程序启动后,在ineedle程序启动开始处理数据包之前的这些包将会被丢掉,调试信息中会给予显示。
【2】初次根据mac过滤的报文,包括:广播报文、组播报文、本地报文等将会被丢掉。
【3】根据协议类型将一些arp报文、vlan报文、非支持链路类型报文等将会被丢掉。
【4】根据配置服务器ip来进行过滤,那些不在web中配置的要监控的sip列表之中的报文也将会直接过滤掉。
【5】如果进入网卡数据报文速度太快,ineedle来不及处理过来,在DPDK程序中将会队列溢出情况,溢出部分报文将 会被丢掉。

二、Ineedle系统

包总数:经过DPDK程序过滤丢球相应报文后copy进入iNeedle系统的报文总数。
下边的情况我们也会将这些报文进行丢弃:
【1】ineedle系统可以设置报文的最大速率,如果超过这个速率,这些报文就将会被丢弃。当然这个一般情况下没有做设置,暂时不考虑这种情况。
【2】packet_main中初次判断,若接收的报文长度比抓取的还长,这是种错误的情况。这些报文会被丢弃,这种情况平时应该会很少吧。
【3】对IP层分片的报文,因为后面的分片不带TCP、UDP信息,暂时不处理。
【4】ineedle系统中再次对目的ip进行过滤,非目的sip的报文将会被丢弃。
【5】根据传输过来的报文方向进行判断,非SESS_DIRECT_S2C、SESS_DIRECT_C2S、SESS_DIRECT_INIT的报文视为错误的报文,将会被丢掉。
【6】对于获取到5元组后,进行简单计算如果报文长度-ip头-tcp头/udp头长度,结果小于0的报文将会被丢弃。
【7】对于长度不为0的报文,但是携带了SYN、RST、FIN标记的,是不正常的报文视为错误报文,将会被丢弃。
【8】对于创建sess_tbl表失败的或者是syn重复,类似syn flood攻击的报文视为错误报文,将会被丢弃。
【9】对于非TCP或非HTTP报文当然状态置为packet_fsm_type_over,视为不处理报文,将会被丢弃。
【10】对于HTTP报文长度小于0的报文视为错误报文,将会被丢弃。
【11】对于TCP分片报文经过组合一次后,仍然是分片报文或者分片太大超过程序设置缓存,视为错误,将会被丢弃。
【12】对于C2S方向的HTTP报文,判断出不是GET、POST等方法,设置状态机为over,视为不处理报文,将会被丢弃。
【13】对于HTTP层面报文进行分析,非REQUEST或RESPONSE报文的,状态设置为packet_fsm_type_over,视为不处理报文,将会被丢弃。
【14】对上述情况进行统计,并可以通过调试信息打印出来这些报文处理情况。

     

三、日志功能

测试功能可以正常使用。但是存在问题,web端配置ip等信息时,只能添加一个ip区间段,再次添加就没有反应,只能从数据库手动添加;日志下载功能似乎也是有bug的,选择条件后点击下载后一直在web端显示正在生成文件,就是生成不了,可能是web的一些bug。

四、磁盘存储说明

总共3块磁盘:300GB、600GB、600GB
300GB:系统盘 + /var/dz_resource + ineedle基本环境
600GB:数据库mysql
600GB:日志

五、简单总结

【测试问题】
1、发包工具:
发包工具不是自己亲自写的,不太熟悉;发包工具发的包很多有错误的包,影响了测试的准确性;测试速度提不上来,必须到性能比较好的设备上才能勉强可以达到测试的条件;其实也可能存在发包的效率问题,抽时间修改一下。
2、调试信息:
dpdk当时仅仅是完成底层数据包的抓取,然后向上ineedle提供包的拷贝功能。并没有实现一些调试信息的接口,导致后续测试时调试信息不完整;后续又临时采用了文件记录的方法,暂时先用着吧。ineedle调试信息这块,虽然可以通过./shell程序来查看ineedle实时包统计情况,但感觉总计的信息不完整;ineedle调试信息统计包的函数中记得有个bug,后来临时修改了一下,原因是当时添加dpdk时忘记修改关于调试show_packet_cmd函数的一些关于底层信息,每次只要在shell中执行show packet_num就会导致程序崩溃。暂时解决办法是将其相关底层驱动相关信息统计代码给注释掉了,只统计报文情况。
3、日志功能:
日志功能模块,对这一块代码读得太少了,测试的时候有点手忙脚乱的。日志功能需要在日志web界面进行相关配置,配置完成之后,才能实现日志的记录功能,最后在配置日志功能后重启一下ineedle;记得ineedle当时设置的是对每个主机的日志记录最大上限是1GB;日志存储目录:/var/dz_resouce/ineedle/release/data/ilog/logs,似乎会定时将此日志文件拷贝的wapp程序共享目录/var/dz_resource/shared;
4、日志程序:
之前可能好久都没有使用过日志功能,这次看代码和测试中发现read和write通信的逻辑有点问题;write端独立不管read是否读取,一直晕着头往共享内存队列中写数据,read端也是不加控制的一直循环从队列中读取数据;一直默认情况是write端的速度比较快,read端可能要写IO速度会稍慢,但即使这样也会存在很多中问题比如数据覆盖等;这次稍微修改了下read端的代码,在write端数据实在是速度非常快的情况下,丢包也是在所难免的,若是read端比较快的情况下要控制read端读取包的进度,不能盲目一直往下读取,因为可能会读取到错误的或者重复的数据包(上次循环write的包),这样就是不对的,导致错误比较严重。程序中添加了几个字段来控制read端的读取行为。现阶段只能这样处理,因为write端暂时不能够等待read,在write端持续高速写入的情况下是无法实现等待的。结果在后续测试中能够保持write和read上的同步。

【代码修改】
1、调试代码修改
这些是在测试过程中进行调试时添加的一些printf语句,打印一些变量执行的情况,这个在测试完毕都已经进行删除
2、dpdk端
添加了包统计的调试信息,在dpdk代码中添加的,没有使用多线程,添加了time等的系统调用来计时,即使是1s中进行一次io写操作,但是系统调用是每次都进行的,可能会导致dpdk的效率问题。但是在调试过程中又是必须的,就暂且保留在代码中,可以在后续稳定的实际生产环境中要将调试信息给关闭掉。
3、ineedle端
同样是针对ineedle报文统计的调试信息做了一些简单修改。具体在show_packet_num函数中作了简单修改。

 

上一篇:VIM使用技巧总结


下一篇:C语言基本类型之long long int