Linux内核参数(sysctl.conf)极限高并发调优实战

高并发场景下Linux默认内核参数远不能满足需求。本文从网络、内存、文件系统、进程调度四个维度,详解sysctl.conf的核心参数调优原理、推荐值及验证回滚方法,帮助你安全榨干服务器性能。

Linux内核参数(sysctl.conf)极限高并发调优实战
封面图:ZuCDN · ZuCDN 原创

默认内核参数成了性能瓶颈

当业务流量飙升到每秒数万个连接、数十万数据包时,Linux的默认sysctl配置会最先暴露出短板。文件句柄耗尽、TIME_WAIT堆积、TCP缓冲区不足、OOM……这些问题一出现,即使CPU和内存仍有富余,整个服务也会瞬间雪崩。与其盲目堆硬件,不如先把手头的内核参数调到位。

这篇文章直接围绕网络层(net.core、net.ipv4)、内存管理(vm)、文件系统(fs)、进程调度(kernel)四个维度展开。每个参数都会告诉你:为什么调、调到多少、怎么验证、如何回滚。

网络层调优:扛住百万并发连接

net.core.somaxconn & net.ipv4.tcp_max_syn_backlog

这两个参数控制TCP连接请求队列的深度。默认somaxconn=128,在高并发下,新连接直接丢包,客户端收到Connection refused。Nginx、Redis等产品自身也有backlog设置,但最终上限由这个内核参数决定。

net.core.somaxconn = 65536
net.ipv4.tcp_max_syn_backlog = 65536

为什么是65536?这个值是经验上限,再大不会提升性能反而浪费内存。尤其是SYN backlog,每个半连接占用约256字节,65536大约占用16MB,完全可接受。

net.ipv4.tcp_tw_reuse & tcp_tw_recycle(慎用)

TIME_WAIT状态在高并发短连接场景下数量惊人。解决办法:

  • tcp_tw_reuse:允许客户端重用处于TIME_WAIT的socket用于新连接。对服务器端无效。可安全开启。
  • tcp_tw_recycle:对NAT环境有严重副作用(可能丢弃来自NAT后的请求)。内核已不建议使用,Linux 4.12+已移除。不要设置。
net.ipv4.tcp_tw_reuse = 1
# 不要设置 tcp_tw_recycle

更稳妥的做法是开启tcp_timestamps并用tcp_tw_reuse。如果延迟敏感业务,可考虑调整tcp_fin_timeout缩减TIME_WAIT存活时间(默认60秒,可改为30秒或15秒)。

net.ipv4.tcp_fin_timeout = 15

TCP读写缓冲区 & 窗口缩放

默认缓冲区大小是为低速网络设计的。万兆网卡下,调大缓冲区能显著提升吞吐量。核心参数:

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

解释:三个值分别表示最小值、默认值、最大值。TCP根据BDP自动调整。最小值设为4KB保证基本通信,默认值保持适中,最大值16MB保证突发大包吞吐。同时开启TCP窗口缩放:

net.ipv4.tcp_window_scaling = 1

net.core.netdev_max_backlog & 网卡队列

网卡中断到来时,数据包先进入内核的backlog队列。默认为1000,高并发下极易丢包。建议翻倍:

net.core.netdev_max_backlog = 65536

同时检查网卡多队列(RSS/RPS)是否开启,这是CPU层面的调优,不在sysctl但很关键。

内存管理调优:避免OOM与页抖动

vm.swappiness

默认60意味着内核在内存还有剩余时就开始换页。对于高并发服务,任何磁盘IO都是灾难。建议降低到10甚至0:

vm.swappiness = 10

注意:如果应用程序本身有内存泄漏风险,swappiness过低会导致OOM无法提前释放。需要结合监控平衡。

vm.vfs_cache_pressure & vm.dirty_ratio

文件系统缓存(dentry、inode)回收速度由vfs_cache_pressure控制,默认100。高并发下频繁文件操作,调大回收力度:

vm.vfs_cache_pressure = 200

脏页比率:dirty_ratio默认20%(占用内存百分比),高IO写场景下调小可防止写突发卡顿:

vm.dirty_ratio = 10
vm.dirty_background_ratio = 5

vm.max_map_count

每个进程能拥有的内存映射区域数量。Elasticsearch、Java等进程在内存中频繁mmap,默认65530太低。建议:

vm.max_map_count = 262144

文件系统与进程调度

fs.file-max & fs.nr_open

最大文件句柄数。高并发意味着大量socket(也是文件),必须提高:

fs.file-max = 2097152
# 同时设置系统级限制
fs.nr_open = 2097152

别忘了同时修改/etc/security/limits.conf中的软硬限制,否则即使内核允许,进程仍会受到ulimit限制。

kernel.sem & kernel.msgmax

信号量和消息队列在高并发分布式日志、中间件场景下需要调整:

kernel.sem = 250 32000 100 1024
kernel.msgmax = 65536
kernel.msgmnb = 65536

kernel.pid_max

默认32768,如果进程数(包括线程)接近此值,新进程无法创建。建议设为最大:

kernel.pid_max = 4194304

实战步骤:配置、验证与回滚

第一步:备份当前配置

cp /etc/sysctl.conf /etc/sysctl.conf.bak.$(date +%Y%m%d)

第二步:写入新配置

将上述参数按需写入/etc/sysctl.conf。只写你真正需要的,别一股脑全复制。例如:

# 网络层
net.core.somaxconn = 65536
net.ipv4.tcp_max_syn_backlog = 65536
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_window_scaling = 1
net.core.netdev_max_backlog = 65536

# 内存
vm.swappiness = 10
vm.vfs_cache_pressure = 200
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
vm.max_map_count = 262144

# 文件与进程
fs.file-max = 2097152
fs.nr_open = 2097152
kernel.pid_max = 4194304

第三步:生效并验证

sysctl -p

检查是否有错误(比如参数名拼写、值超出范围)。逐一确认新值已写入:

sysctl net.core.somaxconn
# 输出应为 65536

生产环境建议分批次应用,每次重启一个服务测试,观察监控指标:连接数、TIME_WAIT、内存使用、swap IO、错误日志。

第四步:回滚方案

如果调优后出现异常(比如TCP连接失败增多、OOM),立即复原:

cp /etc/sysctl.conf.bak.$(date +%Y%m%d) /etc/sysctl.conf
sysctl -p

对于单参数临时回滚,可以直接用sysctl -w var=old_value,但重启后会恢复,需一并修改配置文件。

调优不是万能药

内核参数调优只能释放操作系统层面的瓶颈。真正的极限高并发还需要应用层无阻塞IO、合理的线程模型、数据库连接池以及网络架构(如LVS、DPDK)配合。每改一个参数,必须在压测环境下做对比测试,观察CPU软中断、上下文切换、drop计数等指标。

以上配置基于Linux 4.x/5.x内核,更低版本参数可能不同(例如tcp_tw_recycle)。始终以当前内核文档为准。

延伸阅读