介绍

有时,人们正在寻找能够带来高吞吐量和低延迟的sysctl 货物崇拜(cargo cult)值,而无需进行权衡,并且这种值在任何情况下都能工作。这是不现实的,尽管我们可以说新的内核版本在默认情况下已经进行了很好的调优。事实上,如果乱用默认值,可能会影响性能。

这个简短的教程展示了一些最常用和引用最多的sysctl/网络参数在Linux网络流中的位置,它深受Linux网络堆栈的插图指南和Marek Majkowski的许多帖子的启发。

请随意发送更正和建议!:)

Linux网络队列概述

将sysctl变量装入Linux网络流中

进来了,数据来了

  • 数据包到达网卡(NIC)
  • NIC将验证 MAC (如果不是在混杂模式)和 FCS,并决定放弃或继续
  • NIC将DMA数据包到RAM中,在一个由驱动程序预先准备(映射)的区域内
  • NIC将在接收环形缓冲(ring buffer)队列rx对数据包的引用排队,直到rx-usecs超时或达到rx-frames个数
  • NIC将提出一个硬中断 (hard IRQ)
  • CPU将运行中断处理程序(IRQ handler), 即运行驱动程序代码
  • 驱动程序将安排一次NAPI调用 (schedule a NAPI),清除硬中断并返回
  • 驱动程序引发一个软中断 (soft IRQ) (具体讲是 NET_RX_SOFTIRQ)
  • NAPI将从接收环缓冲区轮询数据,直到netdev_budget_usecs超时或达到 netdev_budgetdev_weight个包
  • Linux也将分配内存给 sk_buff
  • Linux填充元数据:协议,接口,setmacheader (设置 MAC 头),移除以太网头
  • Linux将把skb传递给内核堆栈 (netif_receive_skb)
  • 它将设置网络报头,克隆 skb 窃听点(taps 即 tcpdump),并将其传递给tc入口
  • 数据包通过 default_qdisc 定义的算法处理到 qdisc 大小的netdev_max_backlog
  • 它调用 ip_rcv,数据包被传递到 IP 层
  • 它调用 netfilter (PREROUTING)
  • 它查看路由表,是转发的 (forwarding ) 还是本地的 (local)
  • 如果是本地的,则调用 netfilter (LOCAL_IN)
  • 它调用第4层 (L4) 协议(例如 tcp_v4_rcv)
  • 它找到了正确的socket
  • 它进入tcp有限状态机
  • 将包放入接收缓冲区并按 tcp_rmem 规则设置大小
  • 如果启用了 tcp_moderate_rcvbuf,内核将自动调优接收缓冲区
  • 内核会通知有数据可用到应用程序( epoll 或任何轮询系统)
  • 应用程序唤醒并读取数据

出口,数据出发了

  • 应用程序发送消息(send或其他)
  • TCP发送消息到分配的skb_buff
  • 它将skb排到tcp_wmem大小的套接字(socket)写缓冲区
  • 构建TCP报头(src和dst端口,校验和)
  • 调用第3层(L3)处理程序(在本例中是ipv4的tcp_write_xmittcp_transmit_skb)
  • L3 (ip_queue_xmit)完成它的工作: 构建ip头并调用 netfilter (LOCAL_OUT)
  • 调用输出路由动作
  • 调用 netfilter (POST_ROUTING)
  • 将数据包分片(ip_output)
  • 调用第2层(L2)发送函数
  • txqueuelen长度的输出(QDisc)队列输入其算法default_qdisc
  • 驱动程序代码在环形缓冲区 (ring buffer) tx 处使数据包排队
  • tx-usecs超时或tx-frames个帧之后,驱动程序将执行一个软中断 soft IRQ (NET_TX_SOFTIRQ)
  • 重新启用硬中断 (hard IRQ) 到NIC
  • 驱动程序将所有的包(要发送)映射到一些DMA区域
  • NIC从RAM中(通过DMA)获取数据包进行传输
  • 在传输NIC之后,会发出一个硬中断来表示传输完成
  • 驱动程序将处理这个硬中断并关闭它
  • 并对NAPI poll 系统进行调度(发出软中断)
  • NAPI将处理数据包的信号并释放RAM

是什么,为什么和如何做 - 网络和sysctl参数

Ring Buffer - rx,tx

是什么 - 驱动接收/发送队列。一个或多个固定大小的队列,通常实现为FIFO,它位于RAM

为什么 - 缓冲来平稳地接受突发的连接而不丢弃它们,当你看到丢弃(drop)或溢出(overrun)时,你可能需要增加这些队列,也就是说,有更多的包来超过内核能够消耗它们,副作用可能是延迟增加。

怎样做:
检查命令: ethtool -g ethX
修改命令: ethtool -G ethX rx 新值 tx 新值
如何监控: ethtool -S ethX | grep -e "err" -e "drop" -e "over" -e "miss" -e "timeout" -e "reset" -e "restar" -e "collis" -e "over" | grep -v "\: 0"

中断合并(IC) - rx-usecs, tx-usecs, rx-frames, tx-frames(硬件IRQ)

是什么——在发起一个硬中断之前需要等待多少微秒/帧,从NIC的角度来看,它将DMA数据包直到这个超时或达到帧数
为什么——减少cpu的使用,硬IRQ,可能会以延迟为代价增加吞吐量。
怎样做:
检查命令: ethtool -c ethX
修改命令: ethtool -C ethX rx-usecs 新值 tx-usecs 新值
如何监视: cat /proc/interrupts

中断合并(软 IRQ)和入口 QDisc

是什么——一个 NAPI 轮询周期中的最大微秒数。当轮询周期netdev_budget_usecs超时或处理的数据包数量达到 netdev_budget 时,轮询将退出。
为什么——驱动程序没有对大量的软中断做出反应,而是不断地轮询数据;密切关注dropped(因为超过 netdev_max_backlog 而丢弃的数据包数)和squeezed(ksoftirq 用完 netdev_budget 或剩余工作的时间片的次数)。
如何做
检查命令:sysctl net.core.netdev_budget_usecs
更改命令:sysctl -w net.core.netdev_budget_usecs 新值
如何监控:cat /proc/net/softnet_stat;或者更好的工具

是什么 - netdev_budget 是在一个轮询周期(NAPI 轮询)中从所有接口获取的最大数据包数。在一个轮询周期中,注册到轮询的接口以循环方式进行探测。此外,轮询周期可能不会超过 netdev_budget_usecs 微秒,即使 netdev_budget 尚未用尽。
如何做
检查命令:sysctl net.core.netdev_budget
更改命令:sysctl -w net.core.netdev_budget 新值
如何监控:cat /proc/net/softnet_stat;或者更好的工具

是什么 - dev_weight 是内核可以在 NAPI 中断上处理的最大数据包数,它是关联到每个 CPU 变量(per-CPU variable)。对于支持 LRO 或 GRO_HW 的驱动程序,硬件聚合数据包在此计为一个数据包。
如何做
检查命令:sysctl net.core.dev_weight
更改命令:sysctl -w net.core.dev_weight 新值
如何监控:cat /proc/net/softnet_stat;或者更好的工具

是什么 - netdev_max_backlog 是在 INPUT 端(入口 qdisc)排队的最大数据包数,当接口接收数据包的速度超过内核处理它们的速度时。
如何做
检查命令:sysctl net.core.netdev_max_backlog
更改命令:sysctl -w net.core.netdev_max_backlog 新值
如何监控:cat /proc/net/softnet_stat;或者更好的工具

出口 QDisc - txqueuelen 和 default_qdisc

是什么 - txqueuelen 是在 OUTPUT 端排队的最大数据包数。
为什么 - 一个缓冲区/队列面对连接突发并应用 tc(流量控制)。
如何做
检查命令:ifconfig ethX
更改命令:ifconfig ethX txqueuelen 新值
如何监控:ip -s link

是什么 - default_qdisc 是用于网络设备的默认排队规则。
为什么 - 每个应用程序都有不同的负载和需要流量控制,它也用于对抗缓冲膨胀
如何做
检查命令:sysctl net.core.default_qdisc
更改命令:sysctl -w net.core.default_qdisc 新值
如何监控:tc -s qdisc ls dev ethX

TCP 读写缓冲区/队列

定义什么是内存压力的策略在 tcp_memtcp_moderate_rcvbuf 中指定。

是什么 - tcp_rmem - min(在内存压力下使用的大小),default(初始大小),max(最大大小) - TCP 套接字使用的接收缓冲区大小。
为什么 - 应用程序缓冲区/队列来写入/发送数据,了解其后果会有很大帮助。
如何做
检查命令:sysctl net.ipv4.tcp_rmem
更改命令:sysctl -w net.ipv4.tcp_rmem="min default max";更改默认值时,请记住重新启动您的用户空间应用程序(即您的 Web 服务器、nginx 等)
如何监控:cat /proc/net/sockstat

是什么 - tcp_wmem - min(在内存压力下使用的大小),default(初始大小),max(最大大小) - TCP 套接字使用的发送缓冲区大小。
如何做
检查命令:sysctl net.ipv4.tcp_wmem
更改命令:sysctl -w net.ipv4.tcp_wmem="min default max";更改默认值时,请记住重新启动您的用户空间应用程序(即您的 Web 服务器、nginx 等)
如何监控:cat /proc/net/sockstat

是什么 - tcp_moderate_rcvbuf - 如果设置,TCP 执行接收缓冲区自动调整,尝试自动调整缓冲区大小。
如何做
检查命令:sysctl net.ipv4.tcp_moderate_rcvbuf
更改命令:sysctl -w net.ipv4.tcp_moderate_rcvbuf 新值
如何监控:cat /proc/net/sockstat

荣誉奖 - TCP FSM 和拥塞算法

Accept 和 SYN 队列由 net.core.somaxconnnet.ipv4.tcp_max_syn_backlog 管理。现在 net.core.somaxconn 限制了两个队列大小。

  • sysctl net.core.somaxconn - 为传递给 listen() 函数的 backlog 参数的值提供上限,在用户空间中称为 SOMAXCONN。如果您更改此值,您还应该将您的应用程序更改为兼容的值(即 nginx backlog)。
  • cat /proc/sys/net/ipv4/tcp_fin_timeout - 这指定在强制关闭套接字之前等待最终 FIN 数据包的秒数。这严格违反了 TCP 规范,但需要防止拒绝服务攻击。
  • cat /proc/sys/net/ipv4/tcp_available_congestion_control - 显示已注册的可用拥塞控制选项。
  • cat /proc/sys/net/ipv4/tcp_congestion_control - 设置用于新连接的拥塞控制算法。
  • cat /proc/sys/net/ipv4/tcp_max_syn_backlog - 设置尚未从连接客户端收到确认的排队连接请求的最大数量;如果超过这个数字,内核将开始丢弃请求。
  • cat /proc/sys/net/ipv4/tcp_syncookies - 启用/禁用同步 cookie (SYN cookies) ,用于防止同步洪水攻击 (SYN flood attacks)。
  • cat /proc/sys/net/ipv4/tcp_slow_start_after_idle - 启用/禁用 tcp 慢启动。

如何监控:

  • netstat -atn | awk '/tcp/ {print $6}' | sort | uniq -c - 按状态汇总
  • ss -neopt state time-wait | wc -l - 按特定状态计数:established, syn-sent, syn-recv, fin-wait-1, fin-wait-2, time-wait, closed, close-wait, last-ack, listening, closing
  • netstat -st - tcp 统计摘要
  • nstat -a - 人性化的 tcp 统计摘要
  • cat /proc/net/sockstat - 汇总的socket统计信息
  • cat /proc/net/tcp - 详细统计信息,请参阅内核文档中的每个字段含义
  • cat /proc/net/netstat - ListenOverflowsListenDrops 是需要关注的重要字段
    • cat /proc/net/netstat | awk '(f==0) { i=1; while ( i<=NF) {n[i] = $i; i++ }; f=1; next} \ (f==1){ i=2; while ( i<=NF){ printf "%s = %d\n", n[i], $i; i++}; f=0} ' | grep -v "= 0 是人类可读的 /proc/net/netstat

图片来源:https://commons.wikimedia.org/wiki/File:Tcp_state_diagram_fixed_new.svg

用于测试和监控的网络工具

iperf3 - 网络吞吐量
vegeta - HTTP 负载测试工具
netdata - 分布式实时性能和健康监控系统

文章来源

Linux网络性能参数相关推荐

  1. Linux 网络性能的 15 个优化建议【转自微信公众号菜鸟教程】

    Linux 网络在性能方面有哪些优化手段可用呢? 本文将给出一些开发或者运维中的 Linux 网络性能优化建议. 要注意的是,每一种性能优化方法都有它适用或者不适用的应用场景,应当根据当前的项目现状灵 ...

  2. 用m ip衡量的计算机性能指标是,ip网络技术要求网络性能参数与指标.pdf.pdf

    YU 中华人 民共和 国通信行业标准 YD/T 1171- 2001 IP网络技术要求 - 网络性能参数与指标 IPNetworkSpecification - NetworkPerformanceP ...

  3. Linux网络性能评估工具iperf

    Iperf介绍 iperf是一个基于TCP/IP和UDP/IP的网络性能测试工具,用于检测网络带宽使用率和网络质量,能测试最大TCP和UDP带宽性能,可以报告带宽.网络延迟抖动.数据包丢失率和最大传输 ...

  4. jperf linux运行,Linux网络性能评估工具iperf

    Iperf介绍 iperf是一个基于TCP/IP和UDP/IP的网络性能测试工具,用于检测网络带宽使用率和网络质量,能测试最大TCP和UDP带宽性能,可以报告带宽.网络延迟抖动.数据包丢失率和最大传输 ...

  5. Linux网络性能评估工具iperf 、CHARIOT测试网络吞吐量

    目录 一. Iperf能做什么 1.TCP方面 2.UDP方面 二. Iperf的安装与使用 1.安装iperf 2.iperf参数介绍 三. Iperf应用实例 1.测试TCP吞吐量 2 . 测试U ...

  6. 使用 iperf 工具测试 Linux 网络性能

    在 Linux 网络设备开发过程中,我们常常需要测试网络性能指标参数,找出网络性能瓶颈,从而优化我们的软件或者硬件设计.在 Linux 环境中,我们可以使用 iperf 命令工具测试网络性能,包括网络 ...

  7. 性能之巅:Linux网络性能分析工具-netstat,ifconfig,nicstat,traceroute,tcpdump

    原文地址:http://www.infoq.com/cn/articles/linux-networking-performance-analytics 本文介绍基于Linux操作系统的网络性能分析工 ...

  8. 性能之巅:Linux网络性能分析工具

    编者按:InfoQ开设新栏目"品味书香",精选技术书籍的精彩章节,以及分享看完书留下的思考和收获,欢迎大家关注.本文节选自格雷格著<性能之巅:洞悉系统.企业与云计算>中 ...

  9. Linux 网络性能的 15 个优化建议

    建议1:尽量减少不必要的网络 IO 我要给出的第一个建议就是不必要用网络 IO 的尽量不用. 是的,网络在现代的互联网世界里承载了很重要的角色.用户通过网络请求线上服务.服务器通过网络读取数据库中数据 ...

最新文章

  1. 设计模式学习笔记(一)之工厂模式、单例模式
  2. python删除文件夹无法访问_零基础小白必看:python基本操作-文件、目录及路径
  3. 基于大数据的用户行为预测
  4. 深入理解javascript原型和闭包(17)——补this
  5. codeforce 1311 C. Perform the Combo 前缀和
  6. tomcat源码 Connector
  7. SPOJ 694/705 后缀数组
  8. 第14章 系统异常情况记录
  9. 教大家如何下载百度文库文档
  10. MTK山寨机个性化DIY移植MRP初步探讨
  11. 打印机简体打出繁体、乱码解决办法
  12. C++[USACO06NOV] Fence Repair G合并果子
  13. 奇虎360 php t5级别,奇虎360凭什么估值3800亿?核心价值只是他而已!
  14. python字典第一个元素_如何获取python字典中的第一个值
  15. windows 无法停止ics_Win10系统ICS服务启动后停止怎么办
  16. 使用脚本批量上传内购商品
  17. Egret:一个简单的打砖块游戏
  18. 单字节的乘法指令设计汇编程序11*12
  19. IE8和IE7下js的兼容性问题
  20. Hadoop第五天--HDFS详解

热门文章

  1. 关于NG-ZORRO的历史
  2. 一文学会Spring,Spring最简单的入门教程(万字好文)
  3. 详细安装使用教程】店侦探 - 跟踪店铺数据,学习运营技巧,引流关键词,电商人必备工具
  4. 使用腾讯位置服务制作个性化地图(视频教学)
  5. 2020年最好用的手机是哪一款_2020年所有的好手机你用上了哪一款?这3款各方面让人满意...
  6. JavaScript原型和原型链(详细解读)
  7. 高通量筛选——离子化合物
  8. bindtap和catchtap的区别
  9. 论文笔记:Honor of Kings Arena: an Environment forGeneralization in Competitive Reinforcement Learning
  10. 无法加载 DLL“xxxx.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。