Linux网络优化

1. 检查是否单核软中断太高

2. 检查是否开启 RPS,报文是否适合 RPS 算法

RPS 的工作原理

  • 多核处理器环境:当服务器具有多个 CPU 核心时,默认情况下,所有的网络数据包可能会被发送到单个核心进行处理。这会使得该核心承担所有的网络负载,导致性能瓶颈。
  • 数据包分配:RPS 的主要目的是在多个处理核心之间分配接收到的网络数据包。这是通过将数据包根据特定的哈希算法分配到不同的 CPU 核心,从而实现负载均衡。
  • 提升性能:通过将网络数据包分散到多个核心处理,RPS 可以提高整体网络性能和数据处理能力,降低单个核心的负载,从而防止拥塞。

RPS 的配置

在 Linux 系统中,RPS 可以通过以下步骤进行配置:

  1. 检查 RPS 是否启用:可以通过查看 /proc/sys/net/core/rps_sock_flow_entries 文件来检查 RPS 的状态。
  2. 设置 RPS
    • 通过写入特定的值到 /proc/sys/net/core/rps_sock_flow_entries 文件,可以调整 RPS 的行为。
    • 还可以通过设置网卡的 RX (接收) 处理队列,将接收到的数据包引导到不同的 CPU 核心。
  3. 使用 tc 命令:可以使用 tc 命令进行高级流量控制,以便更精细地控制 RPS。

3. 绑核设置是否正确

4. 网卡参数检查调整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看队列 buff
ethtool -g enp1s0
# 设置队列 buff
ethtool -G enp1s0 max

# 查看网卡 offload
ethtool -k enp1s0
# 设置网卡特性
ethtool -K enp1s0 rx on

# RSS 队列查看
ethtool -x enp1s0
# RSS 队列设置
ethtool -X enp1s0 xxx

5. 检查网卡中断配置是否正确

1
2
3
4
cat /proc/interrupts

# 调整 irqbalance
echo mask > /proc/irq/xxx_number/smp_affinity

6. CPU和网卡队列个数配置

1
2
3
4
5
6
# CPU 数量大于网卡队列个数,需要协议栈开启RPS并设置RPS
echo mask(根据CPU配置) > /sys/class/net/enp1s0/queues/rx-$i/rps_cpus
echo 4096(网卡buff) > /sys/class/net/enp1s0/queues/rx-$i/rps_flow_cnt

# CPU小于网卡队列个数, 绑中断就可以, 关闭RPS
echo 0 > /sys/class/net/enp1s0/queues/rx-$i/rps_cpus

7. 根据 NUMA 配置 CPU

1
2
3
4
5
6
ethtool -i enp1s0 | grep bus-info
lspci -s $bus-info -vv | grep node

# 重新配置 irqbalance 和 RPS mask
echo mask > /proc/irq/xxx_number/smp_affinity
echo mask > /sys/class/net/enp1s0/queues/rx-$i/rps_cpus

8. 是否可以设置中断聚合

1
2
3
4
5
# 查看是否支持
ethtool -c enp1s0

# 配置
ethtool -C enp1s0 adaptive-rx on

9. 查看软中断队列是否溢出

1
cat /proc/net/softnet_stat

net.core.netdev_max_backlog 是一个控制 Linux 网络栈中软中断(softirq)处理的参数。它定义了当内核接收网络数据包时,网络设备驱动程序在网络缓冲区中缓存数据包的最大数量。如果此值被设置得过低,当数据包到达但不能及时处理时,可能会导致数据包丢失。合适地设置这个值有助于提高网络性能,尤其是在高流量情况下。

通过以下步骤来设置该参数:

  1. 查看当前值
    使用以下命令查看当前的 netdev_max_backlog 值:

    1
    sysctl net.core.netdev_max_backlog

  2. 临时设置
    可以使用 sysctl 命令临时设置此参数,直到下一次重启:

    1
    sudo sysctl -w net.core.netdev_max_backlog=<desired_value>
    <desired_value> 替换为你想要设置的数字。例如,如果想设置为 5000:
    1
    sudo sysctl -w net.core.netdev_max_backlog=5000

  3. 永久设置
    如果你想要在系统重启后仍然保持这个配置,可以将设置添加到 /etc/sysctl.conf 文件中。打开文件并添加以下行:

    1
    net.core.netdev_max_backlog = <desired_value>
    然后保存并关闭文件。接下来,使用以下命令应用更改:
    1
    sudo sysctl -p

在选择 net.core.netdev_max_backlog 的值时,需要根据你的网络负载、系统资源以及具体应用场景进行调整。通常,服务器的网络负载越大,这个值需要设置得越高。 设置得过高可能会导致内存占用增加,尤其是在流量波动时,可能会导致潜在的资源浪费。 如果出现高丢包率或延迟,可能需要分析网络性能,以确定这个值是否需要调整。 建议在监控网络流量和系统负载的同时进行调整,以找到一个合适的值。

10. 检查邻居表大小

1
2
3
4
5
sysctl -a lgrep gc_thresh

# net.ipv4.neigh.default.gc_thresh1 = 128
# net.ipv4.neigh.default.gc_thresh2 = 512
# net.ipv4.neigh.default.gc_thresh3 = 4096

将 net.ipv4.neigh.default.gc_thresh1 增大

1
2
3
4
5
sudo sysctl -w net.ipv4.neigh.default.gc_thresh1=<desired_value>

# `/etc/sysctl.conf`
net.ipv4.neigh.default.gc_thresh1 = <desired_value>
# sudo sysctl -p

  • 在选择 gc_thresh1 的值时,需要考虑到系统的内存和网络负载。如果设置得过高,可能会增加系统的内存使用。
  • 除了 gc_thresh1,还可以考虑调整其他相关参数,比如 gc_thresh2gc_thresh3,以便更全面地优化邻接缓存的行为。

11. 查看连接跟踪大小

1
cat /proc/sys/net/netfilter/nf_conntrack_max

12. TCP 参数检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 检查 TIME_WAIT 状态是否太多
netstat -s | grep -i wait
# 对应调整
# net.ipv4.tcp_max_tw_buckets
# net.ipv4.tcp_tw_recycle = 1
# net.ipv4.tcp_tw_reuse = 1

# 检查syn 队列是否太小
netstat -s | grep -i Syn
# 对应调整
# net.ipv4.tcp_max_syn_backlog=<desired_value>

# 检查 accept 队列
ss -lnt
# 对应调整
# net.core.somaxconn
# C语言接口中,调整 int listen(int sockfd,int backlog);
# 最后结果为 min(somaxconn, backlog)

另外 net.ipv4.tcp_abort_on_overflow=1 ,内核将会在 TCP 接收缓冲区溢出并丢失数据包时直接中止连接,可以用于缓解服务器压力

13. 检查协议栈内存分配大小

1
2
3
4
5
6
# 内核应如何为TCP内存分配资源进行限制。参数是三个数字,代表低水位线、压力阈值和失败值
cat /proc/sys/net/ipv4/tcp_mem
# 显示TCP使用的最小接收窗口缓冲区大小、默认接收窗口缓冲区大小和最大接收窗口缓冲区大小
cat /proc/sys/net/ipv4/tcp_rmem
# TCP发送窗口缓冲区的大小设置
cat /proc/sys/net/ipv4/tcp_wmem

相应调整: net.ipv4.tcp_mem net.ipv4.tcp_wmem net.ipv4.tcp_rmem 调整方法见上文。

缓冲区最佳大小随具体情况而不同。在数据通信中,带宽时延乘积 bandwidth-delay product,指的是一个数据链路的能力(每秒比特)与来回通信延迟(单位秒)的乘积。其结果是以比特(或字节)为单位的一个数据总量,等同在任何特定时间该网络线路上的最大数据量 -- 已发送但尚未确认的数据。 \(BDP = 带宽 * RTT\)

BONUS

1
2
3
4
5
6
7
8
9
10
# 粗粒度监控
iftop -i enp1s0

nload enp1s0

nethogs

watch -n 1 ifconfig

ifconfig | grep wlp2s0 -n -C 10

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!