#最佳实践 #调优
1. 怎么查当前参数?
1.1 基本查询
# 查询单个参数
sysctl vm.swappiness
cat /proc/sys/vm/swappiness
# 查看所有内核参数
sysctl -a
# 查看配置文件
cat /etc/sysctl.conf
# 查看当前 ulimit 限制
ulimit -a
ulimit -n # 查看文件描述符限制
1.2 高级查询
# 查询特定类别的参数
sysctl -a | grep "^vm\." # 内存相关
sysctl -a | grep "^net\." # 网络相关
sysctl -a | grep "^fs\." # 文件系统相关
# 查看参数说明
sysctl -d vm.swappiness
2. 内存相关参数
| 参数名 |
参数说明 |
推荐值 |
什么时候调 |
| vm.overcommit_memory |
0:严格检查,内存不足拒绝分配 1:允许所有内存分配请求 2:允许分配不超过 swap+RAM×overcommit_ratio% |
1 |
Redis、Elasticsearch 这类内存密集型应用建议设为 1 |
| vm.swappiness |
0:尽量不用 swap 100:积极用 swap 60:默认值(偏高) |
10 |
数据库、中间件建议 0-10,避免性能抖动 |
| vm.max_map_count |
进程可拥有的内存映射区域数量 |
655360 |
Elasticsearch 必须调,默认 65530 不够用 |
| vm.dirty_ratio |
脏页占总内存百分比,达到后阻塞写入 |
10-20 |
默认 20-40 太高,会导致 IO 突发卡顿 |
| vm.dirty_background_ratio |
后台刷盘触发阈值 |
5 |
默认 10,降低可减少 IO 延迟峰值 |
| vm.dirty_expire_centisecs |
脏页存活时间(百分之一秒) |
3000 |
默认 3000(30秒),可适当降低 |
| vm.dirty_writeback_centisecs |
后台刷盘线程唤醒间隔 |
500 |
默认 500(5秒),IO 密集可降低 |
| vm.vfs_cache_pressure |
控制内核回收内存缓存的倾向 |
50-100 |
默认100,降低可保留更多缓存 |
| vm.min_free_kbytes |
系统保留的最小空闲内存(KB) |
物理内存的1-3% |
防止内存不足导致系统卡顿 |
3. 网络相关参数
| 参数名 |
参数说明 |
推荐值 |
什么时候调 |
| net.core.somaxconn |
socket 监听队列最大长度 |
32768 |
高并发服务必调,默认 128 太小 |
| net.ipv4.tcp_max_syn_backlog |
SYN 队列长度 |
8192 |
防止 SYN flood,默认 1024 不够 |
| net.core.netdev_max_backlog |
网卡接收队列长度 |
16384 |
高流量场景需调大,默认 1000 |
| net.ipv4.tcp_fin_timeout |
FIN_WAIT_2 超时时间(秒) |
30 |
默认 60,缩短可快速回收连接 |
| net.ipv4.tcp_tw_reuse |
允许 TIME_WAIT 复用 |
1 |
高并发必开,加速连接复用 |
| net.ipv4.tcp_keepalive_time |
TCP keepalive 探测间隔(秒) |
600 |
默认 7200 太长,建议 10 分钟 |
| net.ipv4.ip_local_port_range |
本地端口范围 |
10000 65535 |
默认范围小,高并发需扩大 |
| net.ipv4.tcp_max_tw_buckets |
TIME_WAIT 连接数上限 |
36000 |
防止 TIME_WAIT 太多占资源 |
| net.core.rmem_max |
套接字接收缓冲区最大值 |
134217728 |
高带宽网络需调大 |
| net.core.wmem_max |
套接字发送缓冲区最大值 |
134217728 |
高带宽网络需调大 |
| net.ipv4.tcp_rmem |
TCP 接收缓冲区 |
4096 87380 134217728 |
根据网络环境调 |
| net.ipv4.tcp_wmem |
TCP 发送缓冲区 |
4096 65536 134217728 |
根据网络环境调 |
| net.ipv4.tcp_slow_start_after_idle |
空闲后是否启用慢启动 |
0 |
设为0可提高长连接性能 |
4. 文件系统相关参数
| 参数名 |
参数说明 |
推荐值 |
什么时候调 |
| fs.file-max |
系统级最大文件句柄数 |
2097152 |
默认值偏小,高并发必调 |
| fs.inotify.max_user_watches |
用户可监控的文件数量 |
524288 |
开发环境、容器环境常需调大 |
| fs.aio-max-nr |
异步 IO 最大请求数 |
1048576 |
数据库(比如 MySQL)需要较大值 |
| fs.nr_open |
单个进程最大文件句柄数 |
1048576 |
配合 ulimit 用 |
5. 进程相关参数
| 参数名 |
参数说明 |
推荐值 |
什么时候调 |
| kernel.pid_max |
系统最大进程 ID |
4194304 |
容器环境、高并发场景需调大 |
| kernel.threads-max |
系统最大线程数 |
根据内存调 |
查看 cat /proc/sys/kernel/threads-max |
| kernel.sem |
信号量参数 |
250 32000 32 128 |
数据库应用需调大 |
6. 调度器相关参数
| 参数名 |
参数说明 |
推荐值 |
什么时候调 |
| kernel.sched_min_granularity_ns |
最小调度粒度 |
10000000 |
CPU 密集型应用可适当减小 |
| kernel.sched_latency_ns |
调度延迟 |
18000000 |
交互式应用可适当减小 |
| kernel.sched_wakeup_granularity_ns |
唤醒粒度 |
15000000 |
延迟敏感应用可减小 |
7. ulimit 限制(用户级)
# 查看当前限制
ulimit -a
# 查看具体进程的限制
cat /proc/<PID>/limits
| 参数 |
查询命令 |
说明 |
推荐值 |
在哪配置 |
| nofile |
ulimit -n |
单进程最大文件描述符 |
1000000 |
/etc/security/limits.conf |
| nproc |
ulimit -u |
单用户最大进程数 |
65535 |
/etc/security/limits.conf |
| core |
ulimit -c |
core dump 文件大小 |
unlimited |
调试时开启 |
| memlock |
ulimit -l |
最大锁定内存 |
unlimited |
数据库应用建议设为 unlimited |
8. 什么时候需要调优?
8.1 系统级检查
# 1. 检查是否出现 "too many open files"
dmesg | grep -i "too many open files"
# 2. 查看当前文件句柄使用情况
cat /proc/sys/fs/file-nr
# 输出:已分配 已使用 最大值
# 3. 查看 TCP 连接状态统计
ss -s
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 4. 查看 TIME_WAIT 连接数
ss -ant | grep TIME_WAIT | wc -l
# 5. 查看内存和 swap 使用
free -h
vmstat 1 5
# 6. 查看脏页情况
cat /proc/meminfo | grep Dirty
# 7. 查看网络队列丢包
netstat -s | grep -i "listen queue"
cat /proc/net/netstat | grep TcpExt
# 8. 查看系统负载
uptime
cat /proc/loadavg
# 9. 查看 CPU 使用率
top -n 1 | grep "Cpu(s)"
8.2 应用级检查
# 查看特定进程的资源使用
pidstat -p <PID> 1 5
# 查看进程的线程数
ps -eLf | grep <process_name> | wc -l
# 查看进程的内存映射
cat /proc/<PID>/maps | wc -l
# 查看进程的文件描述符使用
ls /proc/<PID>/fd | wc -l
8.3 常见问题信号
碰到这些情况就得调了:
- 文件句柄不够:报 "too many open files" → 调 fs.file-max 和 ulimit
- TIME_WAIT 太多:TIME_WAIT 连接数过万 → 调 tcp_tw_reuse、tcp_fin_timeout
- 频繁 swap:应用老是 swap → 调 vm.swappiness
- Elasticsearch 起不来:调 vm.max_map_count
- 网络连接超时、丢包:调 somaxconn、tcp_max_syn_backlog
- IO 性能抖动:调 vm.dirty_ratio
- 端口用完了:本地端口范围不够 → 调 ip_local_port_range
- 信号量不足:数据库启动失败 → 调 kernel.sem
9. 一键优化脚本
#!/bin/bash
# Linux 内核参数一键优化脚本
# 备份原配置
cp /etc/sysctl.conf /etc/sysctl.conf.bak.$(date +%F_%T)
# 内存优化
cat >> /etc/sysctl.conf << EOF
# 内存管理
vm.overcommit_memory = 1
vm.swappiness = 10
vm.max_map_count = 655360
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
vm.vfs_cache_pressure = 50
vm.min_free_kbytes = 65536
# 网络优化
net.core.somaxconn = 32768
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 10000 65535
net.ipv4.tcp_max_tw_buckets = 36000
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_slow_start_after_idle = 0
# 文件系统
fs.file-max = 2097152
fs.inotify.max_user_watches = 524288
fs.aio-max-nr = 1048576
fs.nr_open = 1048576
# 进程和调度
kernel.pid_max = 4194304
kernel.sem = 250 32000 32 128
EOF
# 应用配置
sysctl -p
# ulimit 配置
cat >> /etc/security/limits.conf << EOF
* soft nofile 1000000
* hard nofile 1000000
* soft nproc 65535
* hard nproc 65535
* soft memlock unlimited
* hard memlock unlimited
* soft core unlimited
* hard core unlimited
EOF
# 对于 systemd 服务,还需配置
mkdir -p /etc/systemd/system.conf.d/
cat > /etc/systemd/system.conf.d/limits.conf << EOF
[Manager]
DefaultLimitNOFILE=1000000
DefaultLimitNPROC=65535
EOF
systemctl daemon-reexec
echo "内核参数优化完成,部分配置需重新登录或重启生效"
echo "建议执行 'sysctl -p' 确认配置已生效"
10. 怎么验证配置生效了?
# 验证 sysctl 参数
sysctl vm.swappiness vm.max_map_count net.core.somaxconn
# 验证 ulimit(需重新登录)
ulimit -n
ulimit -u
# 查看进程实际限制
cat /proc/$(pgrep -f your_app)/limits
# 验证特定服务限制
systemctl show <service_name> | grep LimitNOFILE
11. 调优要注意什么?
11.1 基本原则
- 一次别改太多:每次只调几个参数,看看效果再继续
- 做基准测试:调优前后都测一下,看看到底提升了多少
- 盯着监控:建立监控,及时发现调优带来的问题
- 记录下来:把调优过程记下来,方便以后排查问题
11.2 别踩坑
- 先备份:调优前一定要备份原始配置
- 先测试:别直接在生产环境改,先在测试环境试试
- 准备回滚:万一出问题,得能快速回滚
- 看关键指标:盯着 CPU、内存、IO、网络这些指标
11.3 不同场景怎么调?
- 容器环境:要考虑容器资源限制和宿主机参数
- 高并发服务:重点看网络队列、文件句柄、端口范围
- 数据库应用:重点看内存映射、信号量、异步 IO
- 实时系统:重点看调度延迟、中断处理、内存分配