【Linux】Linux性能调优实战:从CPU到内存
【Linux】Linux性能调优实战从CPU到内存前言Linux作为服务器领域最流行的操作系统其性能调优是每个后端工程师必须掌握的技能。无论是运行Web应用、数据库服务还是大数据处理框架深入理解Linux系统性能瓶颈并加以优化都能显著提升系统吞吐量和响应速度。作为一名AI程序员我们经常需要在Linux服务器上进行模型训练、数据处理和服务部署了解Linux性能调优技术对于提升工作效率具有重要意义。Linux性能调优是一个系统性工程涉及CPU、内存、磁盘I/O、网络等多个维度。本文将从实际工作场景出发详细讲解各子系统的性能分析方法、常见瓶颈识别方法以及具体的优化策略。通过学习本文读者将能够独立进行Linux系统性能分析和调优工作。一、Linux性能监控基础1.1 常用性能监控命令Linux提供了丰富的性能监控工具合理使用这些工具是性能分析的第一步。# top命令实时监控系统进程和整体资源使用情况 top # 常用选项 # -d seconds: 更新间隔 # -p pid: 监控指定进程 # -H: 显示线程 # -u user: 显示指定用户的进程 # htop命令增强版的top需要安装 htop # vmstat命令虚拟内存统计 vmstat 1 10 # 每秒更新一次共10次 # 输出 # r: 运行队列中的进程数 # b: 阻塞的进程数 # swpd: 使用的虚拟内存 # free: 空闲内存 # si/so: 换入/换出内存 # us/sy/id/wa: 用户/系统/空闲/等待I/O的CPU时间百分比 # mpstat命令多处理器统计 mpstat -P ALL 1 5 # 显示所有CPU核心的统计信息 # iostat命令CPU和磁盘I/O统计 iostat -xz 1 5 # 输出 # %util: 设备利用率接近100%表示I/O瓶颈 # await: I/O请求平均等待时间 # avgqu-sz: 平均请求队列长度 # svctm: 平均服务时间 # free命令内存使用情况 free -h # -h人性化显示 free -m # 以MB为单位显示 # 输出 # total: 总内存 # used: 已使用 # free: 空闲 # shared: 共享内存 # buffers/cached: 缓存 # available: 可用内存更准确的指标1.2 进程监控与分析# ps命令查看进程状态 ps aux # 显示所有进程 ps -ef # 标准格式显示 ps -eo pid,ppid,user,%cpu,%mem,cmd --sort-%cpu # 按CPU使用率排序 # 查看特定进程的信息 ps -p $(pgrep -f python) -o pid,%cpu,%mem,cmd # 查看线程信息 ps -eLf | grep python # 显示Python进程的所有线程 pstree -p $(pgrep -f process_name) # 显示进程树 # top命令中常用的交互式快捷键 # P: 按CPU排序 # M: 按内存排序 # T: 按时间排序 # c: 显示完整命令 # k: 杀死进程 # 1: 切换显示单个/所有CPU核心1.3 性能监控脚本#!/bin/bash # system_monitor.sh - 系统性能监控脚本 # 设置监控间隔秒 INTERVAL5 echo Linux System Performance Monitor echo Monitoring interval: ${INTERVAL}s echo Press CtrlC to stop echo # 循环监控 while true; do echo echo Time: $(date %Y-%m-%d %H:%M:%S) echo ---------------------------------------- # CPU使用率 echo CPU Usage: mpstat 1 1 | grep -A 5 Average || true top -bn1 | grep Cpu(s) | awk {print Total CPU: $2 $4 %} echo echo Memory Usage: free -h | grep Mem | awk {printf Used: %s / Total: %s (%.1f%%)\n, $3, $2, ($3/$2)*100} echo echo Top 5 CPU Processes: ps -eo pid,user,%cpu,%mem,cmd --sort-%cpu | head -6 echo echo Top 5 Memory Processes: ps -eo pid,user,%cpu,%mem,cmd --sort-%mem | head -6 echo echo Disk I/O: iostat -xz 1 1 2/dev/null | tail -n 7 | head -5 || echo iostat not available echo echo Network I/O: cat /proc/net/dev | grep -E eth0|ens33|ens160 | awk {printf Interface %s: RX%d bytes, TX%d bytes\n, $1, $2, $10} sleep $INTERVAL done二、CPU性能调优2.1 CPU性能指标分析理解CPU性能指标是调优的基础# 查看CPU信息 cat /proc/cpuinfo lscpu nproc # CPU核心数 # CPU使用率的构成 # us: 用户空间进程使用的CPU时间 # sy: 内核空间使用的CPU时间 # ni: nice值调整过的进程使用的CPU时间 # id: 空闲时间 # wa: 等待I/O完成的时间 # hi: 硬件中断处理时间 # si: 软件中断处理时间 # st: 被虚拟机偷走的时间 # 分析CPU瓶颈 # 1. 如果us过高应用程序计算量大考虑优化算法或增加CPU # 2. 如果sy过高系统调用频繁考虑减少系统调用或优化I/O # 3. 如果wa过高磁盘I/O瓶颈需要优化存储或增加缓存 # 4. 如果hi/si过高中断处理过多检查硬件或驱动问题2.2 进程CPU使用率优化# 查看进程的CPU使用详情 # 方法1使用ps命令 ps -p PID -o pid,%cpu,%mem,cmd # 方法2使用top top -p PID # 方法3使用pidstat需要安装sysstat包 pidstat -p PID 1 5 # 每秒采样一次共5次 # 方法4使用/proc文件系统 cat /proc/PID/stat | awk {print utime: $14/100 s, stime: $15/100 s} # 查看进程的线程CPU使用 pidstat -p PID -t 1 3 # 显示线程统计2.3 CPU亲和性配置CPU亲和性允许我们将进程绑定到特定的CPU核心减少上下文切换# taskset命令设置CPU亲和性 # 将进程绑定到CPU核心0 taskset -cp 0,1 PID # 绑定到核心0和1 # 查看进程的CPU亲和性 taskset -cp PID # 使用掩码设置亲和性 taskset -cp 0x55 PID # 二进制掩码0x55 01010101绑定到核心0,2,4,6 # numactl命令更高级的NUMA控制 numactl --cpunodebind0 --membind0 python script.py # 绑定到节点0 # 查看NUMA配置 numactl --hardware numastat2.4 进程优先级调整# nice值-20最高优先级到19最低优先级 # renice命令调整运行中进程的优先级 renice -n 10 -p PID # 将PID进程的nice值调整为10 # nice命令启动时设置优先级 nice -n -5 ./my_program # 以高优先级启动 # 查看进程优先级 ps -eo pid,ni,cmd | grep process_name # 实时调整进程优先级需要root # 在top中按r输入PID再输入nice值三、内存性能调优3.1 内存性能指标分析# 查看内存使用详情 cat /proc/meminfo # 关键指标解读 # MemTotal: 总内存 # MemFree: 空闲内存 # MemAvailable: 可用内存更准确包含可回收内存 # Buffers: 缓冲区 # Cached: 页面缓存 # SwapTotal: 交换分区总大小 # SwapFree: 交换分区空闲大小 # Dirty: 等待写回的内存 # Writeback: 正在写回的内存 # 页面缓存回收配置 # dirty_ratio: 触发强制写回的比例 # dirty_background_ratio: 后台写回开始的比例 # dirty_expire_centisecs: 脏数据过期时间百分之一秒 # dirty_writeback_centisecs: 后台写回间隔 # 查看内存使用趋势 vmstat 1 10 # 详细的内存统计 cat /proc/vmstat | grep -E pgpgin|pgpgout|pswpin|pswpout|pgfault # pgpgin/pgpgout: 页面换入/换出 # pswpin/pswpout: 交换空间换入/换出 # pgfault: 页面错误数3.2 内存泄漏检测# 方法1使用ps命令对比内存使用 ps aux --sort-%mem | head -10 sleep 60 ps aux --sort-%mem | head -10 # 对比 # 方法2使用pmap查看进程内存映射 pmap -x PID # -x显示扩展格式 # 方法3使用valgrind检测内存泄漏 valgrind --leak-checkfull ./program # 方法4使用 AddressSanitizer编译器级别 # 编译时添加 -fsanitizeaddress gcc -fsanitizeaddress -g program.c -o program # 方法5使用/proc/[pid]/smaps查看详细内存信息 cat /proc/PID/smaps | grep -A 2 heap # 查看内存分配的堆栈跟踪 cat /proc/PID/maps3.3 内存优化配置# /etc/sysctl.conf 中的内存相关配置 # 虚拟内存配置 vm.swappiness10 # 交换分区使用倾向0-100值越低越少使用swap vm.dirty_ratio15 # 触发强制写回的脏页比例 vm.dirty_background_ratio5 # 后台写回开始的脏页比例 vm.dirty_expire_centisecs500 # 脏页过期时间1/100秒 vm.dirty_writeback_centisecs100 # 后台写回间隔 # 文件系统缓存配置 vm.vfs_cache_pressure50 # 内核回收缓存的倾向100为默认越小越保留缓存 # 共享内存配置 kernel.shmmax6843596288 # 最大共享内存段大小 kernel.shmall4294967296 # 共享内存总页数 # 应用示例生效配置 sudo sysctl -p # 临时修改重启后失效 sudo sysctl -w vm.swappiness103.4 大页内存配置# 查看大页配置 cat /proc/meminfo | grep -i huge # 配置透明大页THPCentOS/RHEL 7 echo never /sys/kernel/mm/transparent_hugepage/enabled echo never /sys/kernel/mm/transparent_hugepage/defrag # 永久配置在/etc/rc.d/rc.local中添加上述命令 # 为数据库等应用配置专用大页 # 在/etc/sysctl.conf中配置 vm.nr_hugepages256 # 分配256个大页每个2MB # 查看当前大页使用情况 cat /proc/meminfo | grep -i huge四、磁盘I/O性能调优4.1 I/O性能监控与分析# iostat命令详解 iostat -x 1 5 # 关键指标 # %util: 设备利用率80%表示I/O繁忙 # r/s, w/s: 每秒读写请求数 # rkB/s, wkB/s: 每秒读写KB数 # await: 平均等待时间毫秒 # avgqu-sz: 平均队列长度 # svctm: 平均服务时间已废弃不可靠 # 查看I/O等待 iostat -x | awk /^Device/ {device$1} /^[s,v]da/ {if($NF80) print device, $NF%} # 查看进程的I/O统计 pidstat -d 1 3 # 磁盘I/O统计 pidstat -p PID -d 1 3 # 特定进程 # 查看实际I/O操作 iotop # 需要root # 安装sudo apt install iotop # 查看块设备队列 cat /sys/block/sda/queue/nr_requests # 请求队列长度 cat /sys/block/sda/queue/read_ahead_kb # 预读KB数 cat /sys/block/sda/queue/scheduler # I/O调度器 # 查看I/O调度器 cat /sys/block/*/queue/scheduler # 调度器类型 # cfq: 完全公平队列适合桌面和通用服务器正在被淘汰 # deadline: 期限调度适合数据库等延迟敏感场景 # noop: 空操作适合SSD或虚拟化环境 # mq-deadline: 多队列期限调度现代SSD推荐4.2 I/O调度器配置# 查看当前调度器 cat /sys/block/sda/queue/scheduler # 临时修改调度器 echo deadline /sys/block/sda/queue/scheduler # 永久修改在/etc/default/grub中添加 # GRUB_CMDLINE_LINUXelevatordeadline # 然后执行 sudo update-grub # 针对SSD的优化配置 echo none /sys/block/sda/queue/scheduler # SSD不需要调度器 echo mq-deadline /sys/block/sda/queue/scheduler # 或使用多队列deadline # 调整队列深度 echo 4096 /sys/block/sda/queue/nr_requests # 调整预读 blockdev --setra 4096 /dev/sda # 设置预读为4MB4.3 文件系统优化# 选择合适的文件系统 # ext4: 通用适合大多数场景 # xfs: 大文件和高并发RHEL/CentOS默认 # btrfs: 高级特性快照、压缩但生产环境需谨慎 # zfs: 高级特性适合存储服务器 # 挂载选项优化 # 在/etc/fstab中配置 # /dev/sda1 /data ext4 defaults,noatime,nodiratime,errorsremount-ro 0 1 # 常用挂载选项 # noatime: 不更新访问时间适合频繁读取的场景 # nodiratime: 不更新目录访问时间 # relatime: 合理更新访问时间折中方案 # datajournal: journaling模式ext4提高可靠性但降低性能 # barrier0: 禁用屏障需要RAID卡有电池保护 # 查看文件系统的详细信息 dumpe2fs -h /dev/sda1 # ext4 xfs_info /dev/sda1 # xfs # 文件系统检查 # ext4: fsck.ext4 -f /dev/sda1 # xfs: xfs_repair /dev/sda14.4 使用tmpfs提升性能# tmpfs是基于内存的文件系统适合临时文件 # 查看当前tmpfs使用 df -h | grep tmpfs # 挂载tmpfs mount -t tmpfs -o size4G tmpfs /tmp # 在/etc/fstab中添加 # tmpfs /tmp tmpfs defaults,size4G,mode1777 0 0 # 常见应用场景 # - /tmp 目录 # - 应用的临时缓存目录 # - 编译时的中间文件 # 注意数据不持久化需要确保数据已保存五、网络性能调优5.1 网络性能监控# 查看网络接口统计 cat /proc/net/dev ip -s link show # 查看TCP/UDP统计 netstat -s ss -s # 查看连接状态分布 ss -tan | awk {print $1} | sort | uniq -c | sort -rn # 带宽测量 # 安装 iperf3 # 服务器端iperf3 -s # 客户端iperf3 -c server_ip -t 30 # 网络延迟测量 ping -c 10 server.example.com traceroute server.example.com # 或 mtr # 查看网络连接对应的进程 ss -tlnp | grep :80 # 查看80端口的监听进程5.2 内核网络参数调优# /etc/sysctl.conf 中的网络配置 # TCP连接相关 net.ipv4.tcp_tw_reuse1 # 允许重用TIME_WAIT状态的连接 net.ipv4.tcp_fin_timeout30 # FIN超时时间 net.ipv4.tcp_keepalive_time600 # Keepalive检测间隔 net.ipv4.tcp_keepalive_probes3 # Keepalive探测次数 net.ipv4.tcp_keepalive_intvl15 # Keepalive探测间隔 # 缓冲区大小 net.core.rmem_max134217728 # 最大接收缓冲区 net.core.wmem_max134217728 # 最大发送缓冲区 net.ipv4.tcp_rmem4096 87380 134217728 # TCP接收缓冲区 net.ipv4.tcp_wmem4096 65536 134217728 # TCP发送缓冲区 # 连接队列 net.core.somaxconn65535 # 监听队列最大长度 net.ipv4.tcp_max_syn_backlog65535 # SYN队列长度 # 其他优化 net.ipv4.conf.all.forwarding1 # 启用IP转发 net.ipv4.conf.default.forwarding1 net.core.netdev_max_backlog65535 # 网络设备积压队列 net.ipv4.tcp_no_metrics_save1 # 不保存连接度量到缓存 # 生效配置 sudo sysctl -p # 临时修改 sudo sysctl -w net.core.somaxconn655355.3 网络接口优化# 查看和设置网卡参数 ethtool eth0 # 查看统计信息 ethtool -S eth0 # 常见的网卡优化设置 ethtool -G eth0 rx 4096 tx 4096 # 设置环形缓冲区大小 ethtool -C eth0 rx-usecs 100 tx-usecs 100 # 中断合并 # 开启网卡多队列 ethtool -L eth0 combined 4 # 查看网卡队列 cat /proc/interrupts | grep eth0 # 绑定中断到CPU # 查看当前中断亲和性 cat /proc/irq/XX/smp_affinity # 设置中断亲和性十六进制掩码 echo 01 /proc/irq/XX/smp_affinity # 绑定到CPU 0 echo 02 /proc/irq/XX/smp_affinity # 绑定到CPU 15.4 连接追踪优化# 查看连接跟踪表 cat /proc/net/nf_conntrack sudo conntrack -L # 最大连接跟踪数 cat /proc/sys/net/netfilter/nf_conntrack_max # 设置最大连接跟踪数 echo 262144 /proc/sys/net/netfilter/nf_conntrack_max # 超时时间优化 cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established # 在/etc/sysctl.conf中配置 net.netfilter.nf_conntrack_max262144 net.netfilter.nf_conntrack_tcp_timeout_established7200六、综合调优实战案例6.1 Web服务器Nginx调优# /etc/nginx/nginx.conf worker_processes auto; # 自动设置与CPU核心数一致 worker_rlimit_nofile 65535; # 打开文件描述符限制 events { worker_connections 10240; # 每个worker的连接数 use epoll; # Linux高性能事件模型 multi_accept on; # 一次接受多个连接 } http { # 基础优化 sendfile on; tcp_nopush on; tcp_nodelay on; # Keepalive设置 keepalive_timeout 65; keepalive_requests 10000; # Gzip压缩 gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript; # 缓冲区设置 client_body_buffer_size 10K; client_header_buffer_size 1k; client_max_body_size 8m; large_client_header_buffers 4 32k; # 超时设置 client_body_timeout 12; client_header_timeout 12; send_timeout 10; # 连接复用 upstream backend { server 127.0.0.1:8001; server 127.0.0.1:8002; keepalive 32; # Keepalive连接数 } }6.2 数据库服务器调优# /etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] # InnoDB缓冲池大小建议为服务器内存的60-80% innodb_buffer_pool_size8G innodb_buffer_pool_instances8 # 多实例减少锁竞争 # 日志配置 innodb_log_file_size1G innodb_log_files_in_group3 innodb_flush_log_at_trx_commit1 # 1安全2性能0最快 # 并发配置 innodb_thread_concurrency0 # 0不限制由InnoDB自动调整 innodb_read_io_threads8 innodb_write_io_threads8 innodb_io_capacity2000 innodb_io_capacity_max4000 # 临时表和排序 tmp_table_size256M max_heap_table_size256M sort_buffer_size4M join_buffer_size4M # 连接数 max_connections500 wait_timeout600 interactive_timeout600 # 慢查询日志 slow_query_log1 slow_query_log_file/var/log/mysql/slow.log long_query_time1 # 缓存 query_cache_type0 # MySQL 8.0已移除忽略此设置6.3 Python应用进程管理#!/bin/bash # start_python_app.sh - Python应用启动脚本 export PYTHONUNBUFFERED1 export OMP_NUM_THREADS4 # OpenMP线程数 # 进程数建议为2-4倍CPU核心数 WORKERS8 # 每个进程的线程数对于I/O密集型可以更多 THREADS2 # 超时时间 TIMEOUT30 # 绑定到特定CPU核心可选 # CPU_MASK0,1,2,3 # 使用gunicorn启动 # gunicorn是Python WSGI服务器支持多worker exec gunicorn \ --workers $WORKERS \ --threads $THREADS \ --timeout $TIMEOUT \ --bind 0.0.0.0:8000 \ --worker-class uvicorn.workers.UvicornWorker \ --access-logfile /var/log/app/access.log \ --error-logfile /var/log/app/error.log \ --log-level info \ --max-requests 1000 \ --max-requests-jitter 50 \ app:app6.4 完整系统调优脚本#!/bin/bash # optimize_system.sh - Linux系统性能调优脚本 set -e echo Linux System Performance Optimization # 检查是否为root if [ $EUID -ne 0 ]; then echo Please run as root exit 1 fi # 备份当前配置 BACKUP_DIR/tmp/sys_backup_$(date %Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR cp -r /etc/sysctl.conf $BACKUP_DIR/ 2/dev/null || true cp -r /etc/security/limits.conf $BACKUP_DIR/ 2/dev/null || true echo Backup saved to: $BACKUP_DIR # 优化内核参数 cat /etc/sysctl.conf EOF # Performance Optimization # Network net.core.somaxconn65535 net.core.netdev_max_backlog65535 net.ipv4.tcp_max_syn_backlog65535 net.ipv4.tcp_fin_timeout30 net.ipv4.tcp_tw_reuse1 net.ipv4.tcp_keepalive_time600 net.ipv4.tcp_keepalive_probes3 net.ipv4.tcp_keepalive_intvl15 # Memory vm.swappiness10 vm.dirty_ratio15 vm.dirty_background_ratio5 vm.dirty_expire_centisecs500 vm.vfs_cache_pressure50 # File System fs.file-max2097152 fs.inotify.max_user_instances524288 fs.inotify.max_user_watches524288 EOF # 生效配置 sysctl -p # 优化文件描述符限制 cat /etc/security/limits.conf EOF # Performance Optimization * soft nofile 2097152 * hard nofile 2097152 * soft nproc 65535 * hard nproc 65535 EOF # 优化网络如果使用systemd if [ -d /etc/systemd ]; then mkdir -p /etc/systemd/system.conf.d/ cat /etc/systemd/system.conf.d/performance.conf EOF [Manager] DefaultLimitNOFILE2097152 DefaultLimitNPROC65535 EOF fi echo Optimization Complete echo Please reboot for full effect七、性能问题排查方法论7.1 排查流程当遇到性能问题时应该按照以下流程排查确认问题确定是CPU、内存、磁盘还是网络问题收集数据使用监控工具收集性能数据分析瓶颈找出性能瓶颈的根本原因制定方案制定优化方案实施优化执行优化操作验证效果确认优化效果# 快速定位问题类型 # 1. 运行top按ShiftO再按1查看CPU核心使用情况 # 2. 如果CPU使用率高问题在CPU # 3. 如果CPU使用率低但负载高问题在I/O # 4. 如果内存使用率高但交换区使用低说明应用需要更多内存 # 5. 如果交换区使用率高说明内存不足 # 使用uptime快速查看负载 uptime # 输出load average: 0.5, 0.8, 1.2 # 三个数字分别是1分钟、5分钟、15分钟的平均负载 # 如果负载大于CPU核心数说明有性能瓶颈7.2 常用排查命令速查表# CPU问题 top -bn1 | head -20 # 查看高CPU进程 pidstat -p PID 1 10 # 监控特定进程 ps -eo pid,pcpu,cmd --sort-pcpu | head # 按CPU排序 # 内存问题 free -h # 查看内存使用 ps -eo pid,pmem,cmd --sort-pmem | head # 按内存排序 cat /proc/meminfo | grep -E Swap|Cache # 查看缓存和交换 # I/O问题 iostat -xz 1 10 # 查看磁盘I/O iotop # 查看I/O占用 pidstat -d 1 5 # 查看进程I/O # 网络问题 ss -tuln # 查看监听端口 netstat -anp | grep ESTABLISHED # 查看活动连接 cat /proc/net/sockstat # 查看套接字统计八、总结Linux性能调优是一个系统性的工程需要综合考虑CPU、内存、磁盘I/O和网络等多个方面。本文介绍了性能监控基础掌握top、vmstat、iostat等常用监控命令CPU调优理解CPU指标、合理设置优先级和亲和性内存调优分析内存使用、检测内存泄漏、优化配置磁盘I/O调优选择合适的调度器、优化文件系统网络调优调整内核参数、优化网卡配置实战案例Web服务器、数据库、应用进程的具体优化性能调优的关键是先监控分析再针对性优化每次只改一个参数便于定位效果记录优化前后的数据验证优化效果理解原理比记住命令更重要希望本文能够帮助读者建立起完整的Linux性能调优知识体系在实际工作中有效提升系统性能。