Linux系统性能调优

一、调优前准备:明确目标与定位瓶颈

调优的前提是 **“知道问题在哪”**,需先明确调优目标(如降低接口延迟、提高并发吞吐量、减少内存占用),再通过工具监控定位瓶颈。

1. 核心监控工具(定位瓶颈必备)

不同子系统对应不同监控工具,需熟练掌握其核心指标:
子系统 常用工具 核心监控指标
CPU top、mpstat、pidstat、htop 使用率(us/user 态、sy/kernel 态)、等待 I/O 时间(wa)、上下文切换(cs)、负载(load average)
内存 free、vmstat、top、sar -r 已用内存(used)、缓存(cache/buffer)、交换分区使用(swap used)、页交换(si/so)
磁盘 I/O iostat、iotop、df、sar -b 读写吞吐量(rMB/s、wMB/s)、I/O 等待时间(% util)、平均队列长度(avgqu-sz)
网络 ifstat、ss、netstat、tcpdump、sar -n 网卡吞吐量(rxkB/s、txkB/s)、TCP 连接数(ESTABLISHED)、丢包率(drop)、重传率(retrans)
应用层面 ps、pstack、strace、perf 进程 CPU / 内存占用、系统调用耗时、函数执行效率(perf top)

2. 瓶颈判断依据(快速定位方向)

  • CPU 瓶颈topsy(内核态)或us(用户态)持续 > 80%,wa(I/O 等待)低,上下文切换(cs)频繁(如 > 10000 次 / 秒)。
  • 内存瓶颈freeavailable内存持续 < 10%,vmstatsi(换入)、so(换出)频繁(非零),缓存(cache)被大量回收。
  • 磁盘 I/O 瓶颈iostat -x 1%util(设备繁忙度)持续 > 90%,avgqu-sz(队列长度)>2,await(平均 I/O 等待)>20ms。
  • 网络瓶颈ifstat中网卡吞吐量接近硬件上限,ss -sTCP: drops(丢包)非零,ping延迟高或tcpdump抓包显示大量重传。

二、核心子系统调优方案

针对四大子系统的常见瓶颈,提供具体调优手段(以 CentOS/RHEL 7 + 为例)。

1. CPU 调优:减少调度开销与资源争抢

CPU 的核心矛盾是 “进程调度效率” 与 “资源分配合理性”,需避免进程频繁切换、核心争抢。

(1)进程调度策略调整

Linux 内核支持 3 种调度策略,针对不同进程类型选择:
  • SCHED_FIFO/SCHED_RR:实时调度策略,优先于普通进程(适用于对延迟敏感的服务,如工业控制)。
  • SCHED_OTHER:普通调度策略(默认),通过nice值(-20~19,值越小优先级越高)调整优先级。
操作示例
给 MySQL 进程(PID=1234)提升优先级(nice=-10):
renice -n -10 1234

(2)CPU 亲和性(CPU Affinity)

将进程绑定到固定 CPU 核心,避免进程在多核心间频繁切换(减少 TLB 缓存失效)。
适用场景:高 CPU 占用的单进程服务(如数据库、计算密集型应用)。
操作示例
将 PID=1234 绑定到 CPU 0 和 1(核心编号从 0 开始):
taskset -cp 0,1 1234
# 永久生效:启动时绑定(如MySQL),在systemd服务文件中添加
ExecStart=/usr/sbin/mysqld --cpuset-cpus=0-1

(3)中断均衡优化

CPU 中断(如网卡、磁盘 I/O 中断)会抢占进程资源,需通过irqbalance服务均衡中断分配,或手动绑定高频率中断到独立核心。
操作示例
  1. 启动 irqbalance 服务(自动均衡中断):
    systemctl start irqbalance && systemctl enable irqbalance
    
  2. 手动绑定网卡中断(如 eth0)到 CPU 2:
    # 1. 查看eth0的中断号(假设为123)
    cat /proc/interrupts | grep eth0
    # 2. 绑定中断123到CPU 2(掩码0b100,即十六进制0x4)
    echo 0x4 > /proc/irq/123/smp_affinity
    

2. 内存调优:减少 swap 依赖与优化缓存

Linux 内存管理的核心是 “高效利用物理内存,避免频繁 swap”,需重点调整虚拟内存策略与缓存机制。

(1)调整 swappiness 参数

swappiness(0~100)控制内核使用 swap 分区的倾向:
  • 值越高,内核越倾向于使用 swap(默认 60);
  • 值越低,内核优先使用物理内存(内存充足时建议设为 10~20,避免 swap 延迟)。
操作示例
  1. 临时生效:
    sysctl -w vm.swappiness=10
    
  2. 永久生效(修改/etc/sysctl.conf):
    echo "vm.swappiness=10" >> /etc/sysctl.conf
    sysctl -p  # 加载配置
    

(2)大页内存(HugePages)优化

默认内存页大小为 4KB,大页(通常 2MB/1GB)可减少 TLB(Translation Lookaside Buffer)缓存失效,提升内存访问效率,适用于数据库(MySQL/Oracle)、虚拟化(KVM)等内存密集型应用
操作示例(配置 2MB 大页)
  1. 计算所需大页数量(如需要 10GB 大页:10*1024MB / 2MB = 5120):
    echo "vm.nr_hugepages=5120" >> /etc/sysctl.conf
    sysctl -p
    
  2. 验证大页配置:
    grep HugePages_Total /proc/meminfo  # 应显示5120
    
  3. 应用使用大页(如 MySQL):
    my.cnf中添加:
    innodb_hugepages=1
    

(3)缓存清理(谨慎操作)

Linux 会将空闲内存用于pagecache(文件缓存),当应用需要内存时会自动回收,但可手动清理缓存(仅在内存紧张且缓存无复用价值时使用):
# 清理页缓存
echo 1 > /proc/sys/vm/drop_caches
# 清理页缓存+目录项缓存
echo 2 > /proc/sys/vm/drop_caches
# 清理所有缓存
echo 3 > /proc/sys/vm/drop_caches

3. 磁盘 I/O 调优:提升读写效率与减少等待

磁盘 I/O 是系统性能的常见瓶颈(尤其是机械硬盘 HDD),需从 “调度算法、文件系统、挂载参数、硬件配置” 四方面优化。

(1)选择合适的 I/O 调度器

调度器决定磁盘 I/O 请求的处理顺序,不同磁盘类型适配不同调度器:
  • 机械硬盘(HDD):推荐mq-deadline(多队列 deadline,优化顺序读写,减少磁头移动);
  • 固态硬盘(SSD):推荐none(noop,无调度,直接转发请求,因 SSD 无磁头延迟)。
操作示例
  1. 查看当前调度器(以 /dev/sda 为例):
    cat /sys/block/sda/queue/scheduler
    
  2. 临时设置调度器为mq-deadline
    echo mq-deadline > /sys/block/sda/queue/scheduler
    
  3. 永久生效(修改/etc/udev/rules.d/60-scheduler.rules):
    # HDD配置
    SUBSYSTEM=="block", ENV{ID_SERIAL}=="你的硬盘序列号", ENV{QUEUE_SCHEDULER}="mq-deadline"
    # SSD配置
    SUBSYSTEM=="block", ENV{ID_SERIAL}=="你的SSD序列号", ENV{QUEUE_SCHEDULER}="none"
    

(2)文件系统与挂载参数优化

  • 文件系统选择
    • 大文件 / 高 I/O 场景(如日志、数据库):推荐XFS(支持更大容量,并发读写性能优于 ext4);
    • 普通场景:ext4(兼容性好,稳定性高)。
  • 挂载参数优化
    关键参数减少磁盘写操作(如noatime不记录文件访问时间),提升效率:
    # 编辑/etc/fstab,给/dev/sda1(XFS)添加参数
    /dev/sda1 /data xfs defaults,noatime,nodiratime,discard 0 0
    # 重新挂载生效
    mount -o remount /data
    

    参数说明:

    • noatime:不记录文件访问时间(减少写操作);
    • nodiratime:不记录目录访问时间;
    • discard:启用 TRIM(SSD 专用,释放无用块,避免性能下降)。

(3)磁盘分区对齐与 RAID 配置

  • 分区对齐:SSD 和 RAID 需对齐(通常按 4KB 或 2MB 对齐),否则会导致 “双倍 I/O”,可用parted工具分区时指定align-check optimal 1验证。
  • RAID 级别选择
    • 读写均衡(如数据库):RAID 10(镜像 + 条带,性能高、可靠性高,需至少 4 块盘);
    • 读多写少(如 Web 静态资源):RAID 5(条带 + 奇偶校验,容量利用率高,需至少 3 块盘)。

4. 网络调优:提升并发与吞吐量

网络瓶颈常表现为 “连接队列溢出、丢包、延迟高”,需重点优化 TCP 参数与网卡配置。

(1)TCP 连接队列优化

TCP 连接建立需经过 “半连接队列(SYN 队列)” 和 “全连接队列(Accept 队列)”,队列满会导致连接失败。
关键参数(修改/etc/sysctl.conf
# 1. 半连接队列最大长度(默认128,高并发场景设为4096)
net.ipv4.tcp_max_syn_backlog=4096
# 2. 全连接队列最大长度(需与应用监听队列配合,如Nginx的backlog)
net.core.somaxconn=4096
# 3. 启用SYN Cookie(应对SYN洪水攻击,同时缓解半连接队列压力)
net.ipv4.tcp_syncookies=1

(2)TCP 连接回收与超时优化

减少无效连接占用资源,加速连接回收:
# 1. TIME_WAIT状态连接的回收时间(默认60s,设为30s)
net.ipv4.tcp_fin_timeout=30
# 2. 启用TIME_WAIT连接复用(高并发场景推荐开启)
net.ipv4.tcp_tw_reuse=1
# 3. 最大TIME_WAIT连接数(默认180000,根据内存调整)
net.ipv4.tcp_max_tw_buckets=50000
# 4. TCP连接超时重传次数(默认5次,设为3次减少无效等待)
net.ipv4.tcp_syn_retries=3

(3)TCP 滑动窗口与吞吐量优化

TCP 滑动窗口决定数据传输的 “批量大小”,优化后提升大文件传输效率:
# 1. 启用TCP窗口缩放(支持更大窗口,默认开启)
net.ipv4.tcp_window_scaling=1
# 2. 设置TCP接收缓冲区(min/default/max,单位字节)
net.ipv4.tcp_rmem=4096 87380 67108864
# 3. 设置TCP发送缓冲区(min/default/max,单位字节)
net.ipv4.tcp_wmem=4096 65536 67108864
# 4. 启用TCP拥塞控制算法(BBR算法适合高带宽延迟网络,需内核4.9+)
net.ipv4.tcp_congestion_control=bbr

(4)网卡多队列(RSS)优化

多队列网卡(如千兆 / 万兆网卡)可将中断分配到多个 CPU 核心,避免单核心中断瓶颈:
操作示例
  1. 查看网卡是否支持多队列(以 eth0 为例):
    ethtool -l eth0  # 查看"Combined queues"数量
    
  2. 启用多队列(如设置为 4 个队列):
    ethtool -L eth0 combined 4
    
  3. 配合irqbalance服务自动分配中断,或手动绑定中断到不同 CPU。

三、系统参数与资源限制调优

除子系统外,需调整系统级资源限制(如文件描述符、进程数),避免应用因资源不足报错。

1. 文件描述符限制(高并发必备)

Linux 中 “一切皆文件”,网络连接、文件句柄均占用文件描述符,默认限制(1024)远不能满足高并发需求(如 Nginx、MySQL)。
操作示例
  1. 临时生效(当前 Shell):
    ulimit -n 65535  # 单个进程最大文件描述符数
    ulimit -u 65535  # 单个用户最大进程数
    
  2. 永久生效(全局配置):
    编辑/etc/security/limits.conf,添加:
    * soft nofile 65535  # 软限制(警告阈值)
    * hard nofile 65535  # 硬限制(不可超过)
    * soft nproc  65535
    * hard nproc  65535
    
  3. 对 systemd 管理的服务生效(如 Nginx):
    编辑服务文件(/usr/lib/systemd/system/nginx.service),添加:
    [Service]
    LimitNOFILE=65535
    LimitNPROC=65535
    


    重新加载配置:

    systemctl daemon-reload && systemctl restart nginx
    

2. 内核参数持久化

所有通过sysctl -w修改的参数均为临时生效,需写入/etc/sysctl.conf/etc/sysctl.d/目录下的文件,确保重启后生效:
# 保存当前sysctl配置到文件
sysctl -a > /etc/sysctl.d/custom.conf
# 加载配置
sysctl --system

四、应用层面优化(关键!系统调优是基础)

系统调优为应用提供 “硬件资源保障”,但应用本身的优化对性能影响更大,需结合具体服务调整。

1. Web 服务器(Nginx 为例)

# 1. 工作进程数=CPU核心数(充分利用多核)
worker_processes auto;
# 2. 每个工作进程的最大连接数(结合文件描述符限制)
worker_connections 10240;
# 3. 启用epoll事件模型(高并发场景优于select/poll)
use epoll;
# 4. 关闭不必要的模块(如SSL、gzip,未使用时禁用)
# 5. 开启连接复用(keepalive)
keepalive_timeout 60;
keepalive_requests 100;

2. 数据库(MySQL 为例)

# 1. InnoDB缓冲区(物理内存的50%~70%,减少磁盘I/O)
innodb_buffer_pool_size=8G
# 2. 并发连接数(根据业务调整,避免连接过多导致内存溢出)
max_connections=2000
# 3. 慢查询日志(定位低效SQL,优化查询性能)
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
# 4. 禁用不必要的日志(如binlog未用于主从同步时关闭)
# log_bin=OFF

3. 应用代码优化

  • 减少不必要的系统调用(如频繁open/close文件,改为批量操作);
  • 避免内存泄漏(如 Java 应用通过 JVM 参数-Xms/-Xmx限制堆大小,定期分析堆快照);
  • 优化数据结构(如高频查询用哈希表替代数组,减少遍历耗时)。

五、调优流程与注意事项

1. 标准调优流程

  1. 定目标:明确性能指标(如 QPS 从 1000 提升到 2000,延迟从 100ms 降至 50ms);
  2. 查瓶颈:用监控工具采集调优前的基准数据(CPU、内存、I/O、网络);
  3. 改配置:针对瓶颈调整 1~2 个参数(避免同时改多个参数,无法定位效果);
  4. 验效果:重启服务 / 加载配置后,对比监控数据是否达到目标;
  5. 迭代优化:若未达标,重复 “查瓶颈→改配置→验效果”,直至满足需求。

2. 注意事项

  • 备份配置:修改任何配置前(如sysctl.confnginx.conf),先备份原文件(如cp /etc/sysctl.conf /etc/sysctl.conf.bak);
  • 避免盲目调优:参数并非 “越大越好”(如max_connections过大会导致 MySQL 内存溢出),需理解参数含义;
  • 结合业务场景:高并发 Web 服务(优化网络、文件描述符)与数据库服务(优化内存、磁盘 I/O)的调重点不同;
  • 监控长期效果:调优后需持续监控(如用 Prometheus+Grafana),避免负载变化导致新瓶颈。

总结

Linux 性能调优的核心是 “数据驱动、针对性优化”—— 先通过监控工具定位瓶颈(CPU / 内存 / 磁盘 I/O/ 网络),再从 “系统参数→硬件配置→应用代码” 逐层优化,最后通过长期监控验证效果。需避免 “无瓶颈盲目调参”,同时牢记:应用优化是核心,系统调优是基础,二者结合才能最大化性能。
阅读剩余
THE END