一、概述
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 | 內核對內存承諾的分配策略 |
-
內核
+關注
關注
4文章
1470瀏覽量
42895 -
Linux
+關注
關注
88文章
11768瀏覽量
219105
原文標題:Linux 內核參數調優避坑指南:哪些 sysctl 值不能亂改
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
Linux內核參數調優避坑指南
評論