Linux网络性能参数

介绍

有时,人们正在寻找能够带来高吞吐量和低延迟的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 - 分布式实时性能和健康监控系统

文章来源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值