内核参数调优

#最佳实践 #调优

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 常见问题信号

碰到这些情况就得调了:

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 基本原则

  1. 一次别改太多:每次只调几个参数,看看效果再继续
  2. 做基准测试:调优前后都测一下,看看到底提升了多少
  3. 盯着监控:建立监控,及时发现调优带来的问题
  4. 记录下来:把调优过程记下来,方便以后排查问题

11.2 别踩坑

  1. 先备份:调优前一定要备份原始配置
  2. 先测试:别直接在生产环境改,先在测试环境试试
  3. 准备回滚:万一出问题,得能快速回滚
  4. 看关键指标:盯着 CPU、内存、IO、网络这些指标

11.3 不同场景怎么调?

  1. 容器环境:要考虑容器资源限制和宿主机参数
  2. 高并发服务:重点看网络队列、文件句柄、端口范围
  3. 数据库应用:重点看内存映射、信号量、异步 IO
  4. 实时系统:重点看调度延迟、中断处理、内存分配