到队列内存的分配可以看下上图,很早之前的网卡都是单队列的机制,但现代的网卡大多都是多队列的。好处就是机器网卡的数据接收可以被负载均衡到多个 CPU 上,因此会提供多个队列,这里先有个概念后面会详细说明。
下面来详细介绍启动过程中的第二步 NAPI,这是现代网络数据包处理框架中非常重要的一个扩展。之所以现在能支持 10G、20G、25G 等非常高速的网卡,NAPI 机制起到了非常大的作用。当然 NAPI 并不复杂,其核心就两点:中断、轮循。一般来说,网卡在接收数据时肯定是收一个包,产生一个中断,然后在中断处理函数的时候将包处理掉。处在收包、处理中断,下一个收包,再处理中断,这样的循环中。而 NAPI 机制优势在于只需要一次中断,收到之后就可以通过轮循的方式,把队列内存中所有的数据都拿走,达到非常高效的状态。
网卡驱动-监控
接下来就是在驱动这层可以做的监控了,需要去关注其中一些数据的来源。
$ sudo ethtool -S eth0 NIC statistics: rx_packets: 597028087 tx_packets: 5924278060 rx_bytes: 112643393747 tx_bytes: 990080156714 rx_broadcast: 96 tx_broadcast: 116 rx_multicast:20294528 ....首先非常重要的是 ethool 工具,它可以拿到网卡中统计的数据、接收的包数量、处理的流量等等常规的信息,而我们更多的是需要关注到异常信息。
$ cat /sys/class/net/eth0/statistics/rx_dropped 2通过 sysfs 的接口,可以看到网卡的丢包数,这就是系统出现异常的一个标志。
三个途径拿到的信息与前面差不多,只是格式有些乱,仅做了解即可。
上图是要分享的一个线上案例。当时业务上出现异常,经过排查最后是怀疑到网卡这层,为此需要做进一步的分析。通过 ifconfig 工具可以很直观的查看到网卡的一些统计数据,图中可以看到网卡的 errors 数据指标非常高,明显出现了问题。但更有意思的一点是, errors 右边最后的 frame 指标数值跟它完全相同。因为 errors 指标是网卡中很多错误累加之后的指标,与它相邻的 dropped、overruns 这俩个指标都是零,也就是说在当时的状态下,网卡的错误大部分来自 frame。
当然这只是瞬时的状态,上图中下面部分是监控数据,可以明显看到波动的变化,确实是某一台机器异常了。frame 错误一般是在网卡收到数据包,进行 RCR 校验时失败导致的。当收到数据包,会对该包中的内容做校验,当发现跟已经存下来的校验不匹配,说明包是损坏的,因此会直接将其丢掉。
这个原因是比较好分析的,两点一线,机器的网卡通过网线接到上联交换机。当这里出现问题,不是网线就是机器本身的网卡问题,或者是对端交换机的端口,也就是上联交换机端口出现问题。当然按第一优先级去分析,协调运维去更换了机器对应的网线,后面的指标情况也反映出了效果,指标直接突降直到完全消失,错误也就不复存在了,对应上层的业务也很快恢复了正常。
网卡驱动-调优
说完监控之后来看下最后的调优。在这个层面能调整的东西不多,主要是针对网卡多队列的调整,比较直观。调整队列数目、大小,各队列间的权重,甚至是调整哈希的字段,都是可以的。
$ sudo ethtool -l eth0 Channel parameters for eth0: Pre-set maximums: RX: 0 TX: 0 Other: 0 Combined: 8 Current hardware settings: RX: 0 TX: 0 Other: 0 Combined: 4上图是针对多队列的调整。为了说明刚才的概念,举个例子,比如有个 web server 绑定到了 CPU2,而机器有多个 CPU,这个机器的网卡也是多队列的,其中某个队列会被 CPU2 处理。这个时候就会有一个问题,因为网卡有多个队列,所以 80 端口的流量只会被分配到其中一个队列上去。假如这个队列不是由 CPU2 处理的,就会涉及到一些数据的腾挪。底层把数据接收上来后再交给应用层的时候,需要把这个数据移动一下。如果本来在 CPU1 处理的,需要挪到 CPU2 去,这时会涉及到 CPU cache 的失效,这对高速运转的 CPU 来说是代价很高的操作。