一、概述
1.1 背景介绍
线上问题一来,很多人第一反应是改 sysctl。连接慢改 somaxconn,内存紧张改 swappiness,磁盘抖动改 dirty_ratio,网卡丢包改各种 net.core.*。参数不是不能改,问题是很多改法只在某个场景下成立,一旦脱离上下文,最容易把局部最优改成全局事故。
这篇文章只讲一个原则:先明确问题在哪一层,再动对应参数。如果还没确认是网络、调度、内存、回写还是连接队列问题,先别碰 sysctl。参数调优最大的坑不是“改了没效果”,而是“短期看起来有效,后面把故障放大了”。
1.2 技术特点
不追求参数大全:只讲生产里最容易被误改、最容易造成副作用的项。
强调适用前提:每个参数都给“什么时候该看、什么时候别动”。
覆盖回滚与验证:参数改前备份、改后验证、异常时如何回退。
1.3 适用场景
场景一:业务刚上线,想做基础内核参数基线。
场景二:线上出现 backlog、swap、回写卡顿、丢包、conntrack 压力,准备做针对性调优。
场景三:团队里经常直接复制网上的 sysctl.conf,需要一份能落地的避坑清单。
1.4 环境要求
| 组件 | 版本要求 | 说明 |
|---|---|---|
| 操作系统 | Ubuntu 20.04+ 、Debian 11+、CentOS 7、Rocky Linux 8/9 | 不同内核参数是否存在会有差异 |
| 权限 | root | 修改 sysctl 需要 root |
| 配套工具 | sysstat 、ss、conntrack-tools、ethtool、procps-ng | 调优前后需要验证 |
| 变更流程 | 有维护窗口 | 关键参数别在业务高峰直接改 |
二、详细步骤
2.1 准备工作
2.1.1 系统检查
cat /etc/os-release uname -r sysctl -a 2>/dev/null | head -20 ss -s free -h vmstat 1 5
2.1.2 安装依赖
Ubuntu / Debian:
sudo apt update sudo apt install -y sysstat conntrack ethtool procps iproute2
CentOS / Rocky / RHEL:
sudo yum install -y sysstat conntrack-tools ethtool procps-ng iproute
2.1.3 先备份当前参数
sudo mkdir -p /srv/ops/sysctl-backup sudo sysctl -a 2>/dev/null | sort > /srv/ops/sysctl-backup/sysctl-$(date +%F-%H%M%S).txt sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog vm.swappiness vm.dirty_ratio vm.dirty_background_ratio
2.2 核心配置
2.2.1 第一步:先定义生产基线
# 文件路径:/etc/sysctl.d/99-prod-baseline.conf net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.ip_local_port_range = 10240 65000 net.netfilter.nf_conntrack_max = 262144 vm.swappiness = 10 vm.dirty_background_ratio = 5 vm.dirty_ratio = 20 fs.file-max = 2097152 kernel.pid_max = 4194304
这些值不是通用真理,只是一个更稳的起点。真正上线前,还得结合连接数、磁盘吞吐、内存大小和业务模型验证。
2.2.2 第二步:准备回滚和验证脚本
# 文件路径:prometheus/rules/linux-sysctl-risk.yml groups: - name: linux-sysctl-risk rules: - alert: NodeConntrackUsageHigh expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8 for: 5m labels: severity: warning - alert: NodeSwapActivityHigh expr: rate(node_vmstat_pswpin[5m]) + rate(node_vmstat_pswpout[5m]) > 100 for: 3m labels: severity: warning - alert: NodeDiskWritebackPressure expr: node_memory_Dirty_bytes / node_memory_MemTotal_bytes > 0.1 for: 5m labels: severity: warning
2.2.3 第三步:按问题类型动参数
网络连接积压时先看:
ss -lnt ss -s sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog
内存和 swap 时先看:
free -h vmstat 1 10 sysctl vm.swappiness vm.overcommit_memory
磁盘回写时先看:
cat /proc/meminfo | egrep 'Dirty|Writeback' sysctl vm.dirty_ratio vm.dirty_background_ratio
2.3 启动和验证
2.3.1 启动服务
sudo sysctl --system sudo systemctl restart systemd-sysctl sudo systemctl status systemd-sysctl --no-pager
2.3.2 功能验证
sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog vm.swappiness vm.dirty_ratio vm.dirty_background_ratio ss -s free -h cat /proc/meminfo | egrep 'Dirty|Writeback'
三、示例代码和配置
3.1 完整配置示例
3.1.1 主配置文件
# 文件路径:/etc/sysctl.d/99-prod-baseline.conf net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.ip_local_port_range = 10240 65000 net.netfilter.nf_conntrack_max = 262144 vm.swappiness = 10 vm.dirty_background_ratio = 5 vm.dirty_ratio = 20 fs.file-max = 2097152
3.1.2 辅助脚本
#!/usr/bin/env bash set -euo pipefail BACKUP_DIR="/srv/ops/sysctl-backup" mkdir -p "$BACKUP_DIR" STAMP="$(date +%F-%H%M%S)" BACKUP_FILE="$BACKUP_DIR/sysctl-$STAMP.txt" sysctl -a 2>/dev/null | sort > "$BACKUP_FILE" echo "backup saved to $BACKUP_FILE" echo "current key values:" sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog net.netfilter.nf_conntrack_max vm.swappiness vm.dirty_ratio vm.dirty_background_ratio
3.2 实际应用案例
案例一:把 vm.dirty_ratio 调太高,结果把数据库写抖了
场景描述:为了追求顺序写吞吐,某台数据库主机把 vm.dirty_ratio 从默认值调到 40。峰值时延明显抖动,业务间歇性超时。
实现代码:
cat /proc/meminfo | egrep 'Dirty|Writeback' iostat -xz 1 10 sysctl vm.dirty_ratio vm.dirty_background_ratio
运行结果:
Dirty: 7348224 kB Writeback: 612384 kB
脏页堆太多,前台线程被迫参与同步回写,结果 RT 被直接拖高。回滚到:
sudo sysctl -w vm.dirty_background_ratio=5 sudo sysctl -w vm.dirty_ratio=20
案例二:盲目把 vm.swappiness=1,结果低峰期都回收不动缓存
场景描述:某缓存节点为了“绝不 swap”,一刀切把所有机器都改成 vm.swappiness=1。短期看 swap 下降了,但低峰期页缓存回收变差,磁盘读放大更严重。
实现步骤:
看内存和 swap
free -h vmstat 1 10
看业务 RT 与 cache
cat /proc/meminfo | egrep 'Cached|MemAvailable|Swap'
回到更稳的值并观察
sudo sysctl -w vm.swappiness=10
案例三:盲目调大 nf_conntrack_max,结果内存先被连接跟踪表吃掉
场景描述:某入口层机器连接数暴涨,团队第一反应是把 nf_conntrack_max 从 262144 直接拉到 2097152。连接告警短暂消失,但主机内存持续升高。
实现步骤:
看 conntrack 使用率
conntrack -S cat /proc/sys/net/netfilter/nf_conntrack_count sysctl net.netfilter.nf_conntrack_max
看内存和 slab
free -h slabtop -o | head -20
对比业务连接模型
ss -s
运行结果:
nf_conntrack_count: 1380247 nf_conntrack_max: 2097152
根因不是“表太小”,而是短连接和异常重试把连接跟踪表撑大了。直接扩表只是把问题从“连接失败”换成“内存膨胀”。处理动作:
优先治理短连接和异常重试
按峰值连接数重新估算表大小
在合理范围内调大 nf_conntrack_max,不是无限放大
这类参数调整必须把内存成本一起算进去,不然入口没先挂,节点先被拖死。
四、最佳实践和注意事项
4.1 最佳实践
4.1.1 性能优化
优化点一:参数只在有证据时改。somaxconn 不会修复应用 accept 太慢,swappiness 也不会修复内存泄漏。
优化点二:改参数前留快照,改参数后留验证数据,至少保留 ss -s、free -h、iostat、核心 sysctl 输出。
优化点三:基线配置走配置管理,别让每台机器都手工改。
4.1.2 安全加固
安全措施一:生产参数文件落到 /etc/sysctl.d/,用配置管理系统统一发版。
安全措施二:禁止直接复制网络上“万能优化参数大全”。
安全措施三:变更窗口内保留回滚脚本和备份文件。
4.1.3 高可用配置
HA 方案一:参数分层管理,网络基线、内存基线、容器节点基线分开。
HA 方案二:把 sysctl 变更纳入 CMDB 或 Git 仓库审计。
备份策略:每次参数变更前自动导出完整 sysctl -a。
4.2 注意事项
4.2.1 配置注意事项
警告:老文章里经常出现的 net.ipv4.tcp_tw_recycle 早就不适合现代环境。看到这类配置先删,不要照抄。
somaxconn 只决定内核层监听队列上限,应用本身 backlog 太小同样会限制住
nf_conntrack_max 调大前,先算内存成本
dirty_ratio 调太高,经常会把“吞吐更大”换成“长尾更差”
4.2.2 常见错误
| 错误现象 | 原因分析 | 解决方案 |
|---|---|---|
| 改了 somaxconn 仍然丢连接 | 应用监听 backlog 没改、accept 太慢 | 同时看应用参数和 listen queue |
| 调低 swappiness 后内存仍紧张 | 根因是泄漏或 limit 太小 | 先查内存根因 |
| 调大 nf_conntrack_max 后主机更吃内存 | conntrack 表本身占内存 | 先算表项成本和峰值连接数 |
4.2.3 兼容性问题
版本兼容:参数在不同内核版本下是否存在、默认值是多少都可能不同。
平台兼容:容器节点、数据库节点、网关节点不适合共用一套激进参数。
组件依赖:应用层 backlog、连接池、线程模型、磁盘基线会直接影响参数效果。
五、故障排查和监控
5.1 故障排查
5.1.1 日志查看
sudo journalctl -u systemd-sysctl --since "1 hour ago" sudo dmesg -T | egrep -i 'conntrack|memory|oom|tcp|nf_'
5.1.2 常见问题排查
问题一:SYN backlog 看起来不够,怎么确认
ss -lnt netstat -s | egrep -i 'listen|SYN' sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog
解决方案:先看 listen queue 是否真的满,再决定调 somaxconn 和 tcp_max_syn_backlog。
问题二:调完 swappiness 后还是频繁换页
free -h vmstat 1 10 ps -eo pid,cmd,%mem,rss --sort=-rss | head -20
解决方案:根因通常是内存不足或泄漏,不是参数本身。
问题三:conntrack 表总满
症状:入口层连接多、NAT 多,偶发建立连接失败
排查:
conntrack -S sysctl net.netfilter.nf_conntrack_max cat /proc/sys/net/netfilter/nf_conntrack_count
解决:先优化连接生命周期,再考虑调表大小
5.1.3 调试模式
sysctl -a 2>/dev/null | egrep 'somaxconn|swappiness|dirty_ratio|nf_conntrack'
5.2 性能监控
5.2.1 关键指标监控
ss -s free -h cat /proc/meminfo | egrep 'Dirty|Writeback' conntrack -S
5.2.2 监控指标说明
| 指标名称 | 正常范围 | 告警阈值 | 说明 |
|---|---|---|---|
| conntrack 使用率 | < 70% | > 80% 持续 5m | 高了先查连接模型 |
| swap 活跃度 | ≈ 0 | > 100 pages/s 持续 3m | 先查内存根因 |
| 脏页比例 | < 5% | > 10% 持续 5m | 写回压力正在积累 |
| listen drop | 0 | 持续增长 | 监听队列或应用 accept 有问题 |
5.2.3 监控告警配置
groups: - name: linux-sysctl-risk rules: - alert: NodeConntrackUsageHigh expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8 for: 5m - alert: NodeSwapActivityHigh expr: rate(node_vmstat_pswpin[5m]) + rate(node_vmstat_pswpout[5m]) > 100 for: 3m - alert: NodeDiskWritebackPressure expr: node_memory_Dirty_bytes / node_memory_MemTotal_bytes > 0.1 for: 5m
5.3 备份与恢复
5.3.1 备份策略
#!/usr/bin/env bash set -euo pipefail mkdir -p /srv/ops/sysctl-backup sysctl -a 2>/dev/null | sort > /srv/ops/sysctl-backup/sysctl-$(date +%F-%H%M%S).txt
5.3.2 恢复流程
确认要回滚的版本:ls -1 /srv/ops/sysctl-backup | tail -5
恢复配置文件:sudo cp /srv/ops/sysctl-backup/99-prod-baseline.conf.bak /etc/sysctl.d/99-prod-baseline.conf
重新加载:sudo sysctl --system
验证:sysctl net.core.somaxconn vm.swappiness vm.dirty_ratio
六、总结
6.1 技术要点回顾
sysctl 不是救火按钮,必须先做问题定性
dirty_ratio、swappiness、nf_conntrack_max 都有明显副作用
参数要配合业务模型、资源基线和监控一起看
任何变更都要能回滚
6.2 进阶学习方向
Linux 内核网络栈参数
内存回收和写回机制
Kubernetes 节点 sysctl 管理
6.3 参考资料
Linux kernel sysctl 文档 - 内核参数官方说明
Linux proc 文件系统文档 - /proc 观测入口
Prometheus Alerting Rules - 告警规则语法
附录
A. 命令速查表
sysctl -a 2>/dev/null | sort # 导出当前参数 sysctl net.core.somaxconn vm.swappiness # 查看关键参数 ss -s # 看连接状态 conntrack -S # 看 conntrack 使用情况 cat /proc/meminfo | egrep 'Dirty|Writeback' # 看回写压力
B. 配置参数详解
net.core.somaxconn:监听 socket backlog 上限
net.ipv4.tcp_max_syn_backlog:半连接队列大小
vm.swappiness:匿名页与页缓存回收倾向
vm.dirty_ratio:前台同步刷脏页触发阈值
C. 术语表
| 术语 | 英文 | 解释 |
|---|---|---|
| 半连接队列 | SYN backlog | 握手未完成前的等待队列 |
| 脏页 | Dirty Pages | 已修改但尚未写回磁盘的页 |
| 连接跟踪 | Conntrack | Linux 内核连接状态跟踪表 |
| 过量提交 | Overcommit | 内核对内存承诺的分配策略 |
全部0条评论
快来发表一下你的评论吧 !