美文网首页
网卡网络驱动监控---网络数据包流程监控一

网卡网络驱动监控---网络数据包流程监控一

作者: 白馨_1114 | 来源:发表于2020-05-09 17:26 被阅读0次

    这一系列的目标是为了让我们的监控更全面,帮助我们优化和发现潜在问题。它涉及到很多方面,比如连接池的优化,系统层面的监控优化,网络方面,应用本身的监控。我们将先从网络这层去体系化的做这件事情。
    关注网络整个流程,最终目的是为了知道哪些地方会造成性能问题,哪些地方会造成数据丢失,以及如何通过工具或者监控指标来发现这些异常。帮助发现隐藏网络问题以及提升故障排查以及运维效率。

    本文将整理整体的流程框架,详细介绍网卡和驱动的细节以及围绕网卡和驱动采取的监控手段(图片来自网络)。
    (在整理的整个过程中,我也不断在想这些指标的意义,是否确实对我们有意义。但我们不仅仅应该从监控的角度去考虑,我们也要考虑当问题发生时,能否清晰流程,让我们知道到底在哪层出现问题。所以在整理过程中,将围绕vip集群迁移延时问题,去思考底层需要知道些什么,能帮助去排查这种不了了之的问题。)

    接受网络数据包与发送网络数据包是一个复杂的过程,涉及到庞杂的底层技术细节。
    从应用编程的角度看:
    NIC (网卡)->内核->user space
    从网络协议的角度看:
    物理层->链路层->ip->tcp->应用层
    很难将我们熟悉的概念合在一起去讨论这个问题,比如内核中的网络驱动,你最多只能说它工作在数据链路层而不能说它实现了数据链路层。
    http://bbs.chinaunix.net/thread-1924872-1-1.html
    所以在描述整个过程,将用程序流程的角度去描述。

    先梳理接受数据包的过程,大概分为以下几步:

    1. 网卡(NIC)收到数据包。
    2. 将数据包从网卡硬件缓存转移到内核管理的内存sk_buf中。
    3. 硬中断通知内核处理。
    4. 内核网卡驱动将sk_buf交给内核协议栈处理。
    5. 经过TCP/IP协议栈逐层处理。
    6. 应用程序通过read()从socket buffer读取数据。
    

    图一:


    image.png

    下面我们具体看下各个流程,
    步骤1.关于网卡网络故障方面的问题
    这个交给网络工程师。如果你对此感兴趣,可参考 https://www.cnblogs.com/Security-Darren/p/4700387.html

    步骤2.将数据包从网卡硬件缓存转移到内核管理的内存
    网卡接收到数据包之后,首先需要将数据发送到内核中,这中间的桥梁是rx ring buffer。它是由NIC和驱动程序共享的一片区域。事实上,rx ring buffer存储的并不是实际的packet数据,而是一个描述符,这个描述符指向了它真正的存储地址,具体流程如下:
    1). 系统启动NIC驱动首先在内存中分配一片缓冲区来接收数据包,叫做sk_buffer
    2). 将上述缓冲区的地址和大小(即文件描述符),加入到rx ring buffer
    3). 驱动通知网卡有一个新的描述符。
    4). 网卡从rx ring buffer中取出描述符,从而获知缓冲区的地址和大小。
    5). 网卡收到新的数据包。
    6). 网卡将新数据包通过DMA直接写到sk_buffer中:

    image.png

    经过以上的过程,NIC接受的数据就转移到内核管理的内存sk_buf中。

    当驱动处理速度跟不上网卡收包速度时,驱动来不及分配缓冲区,NIC接收到的数据包无法及时写到sk_buffer,就会产生堆积,当NIC内部缓冲区写满后,就会丢弃部分数据,引起丢包。这部分丢包为rx_fifo_errors,在/proc/net/dev中体现为fifo字段增长,在ifconfig中体现为overruns指标增长,ethtool -S em1中体现为rx_fifo_errors

    通过ethtool -S em1来查看这个错误(em1为物理网卡,逻辑网卡无效):

    image.png

    可以看出这里面的err很多。其中TX表示的是发送数据,RX表示的是接受数据。这个命令可以帮助我们更详细的去定位错误,但一般监控通过/proc/net/dev关注 dropfifo即可。实际落地过程中,我们需要区分物理网卡,虚拟网卡,docker网络去确定时间监控目标。

    image.png

    如果我们确实要调优,一方面是看是否需要调整一下每个队列数据的分配,或者是否要加大Ring Buffer的大小。由于修改以上参数需要重启才能有意义,我们对这个参数主要是监控,以方便我们排查错误。

    调整 Ring Buffer 队列数量

    
    [root@ ~ ]$ ethtool -l em1
    Channel parameters for em1:
    Pre-set maximums:
    RX:        0
    TX:        0
    Other:        1
    Combined:    8
    Current hardware settings:
    RX:        0
    TX:        0
    Other:        1
    Combined:    8
    
    Combined = 8,说明当前 NIC 网卡会使用 8 个进程处理网络数据。
    更改 eth0 网卡 Combined 的值:
    ethtool -L eth0 combined 8
    需要注意的是,ethtool 的设置操作可能都要重启一下才能生效。
    

    调整 Ring Buffer 队列大小,查看当前 Ring Buffer 大小

    
    [root@ ~ ]$ ethtool -g em1
    Ring parameters for em1:
    Pre-set maximums:
    RX:        4096
    RX Mini:    0
    RX Jumbo:    0
    TX:        4096
    Current hardware settings:
    RX:        256
    RX Mini:    0
    RX Jumbo:    0
    TX:        256
    

    看到 RXTX 最大是 4096,当前值为256。队列越大丢包的可能会小,但数据延迟会增加.
    设置 RXTX 队列大小:

    ethtool -G em1 rx 4096
    ethtool -G em1 tx 4096
    

    步骤4.内核网卡驱动将sk_buf交给内核协议栈处理
    当NIC把数据包通过DMA复制到内核缓冲区sk_buffer后,NIC立即发起一个硬件中断。CPU接收后,首先进入上半部分,网卡中断对应的中断处理程序是网卡驱动程序的一部分,之后由它发起软中断,进入下半部分,开始消费sk_buffer中的数据,交给内核协议栈处理。

    image.png

    当内核开始消费sk_buffer中的数据,交由协议栈(如IPTCP)处理之前存在一个缓冲队列。每个CPU核都有一个backlog队列,当接收包的速率大于内核协议栈处理的速率时,CPUbacklog队列不断增长。当达到设定的netdev_max_backlog值时,数据包将被丢弃。这主要是由于中断处理的速度低于sk_buffer增长的速度。这部分丢包可以在cat /proc/net/softnet_stat的输出结果中进行确认。
    待补CPU中断亲缘关系、调优以及监控。。。

    相关文章

      网友评论

          本文标题:网卡网络驱动监控---网络数据包流程监控一

          本文链接:https://www.haomeiwen.com/subject/urxlnhtx.html