引言

AlmaLinux 作为 CentOS 的继任者,继承了 RHEL 的稳定性和企业级特性,广泛应用于生产环境。然而,随着业务负载的增加,系统性能瓶颈逐渐显现。本文将从内核参数、系统资源、应用层等多个维度,提供一套完整的性能优化实战策略,帮助您充分发挥 AlmaLinux 的硬件潜力。

一、 性能优化前的准备工作

在开始优化之前,必须建立性能基线,否则无法量化优化效果。

1.1 建立性能基线

使用 sysstat 工具包(包含 sar, iostat, mpstat 等)收集系统历史性能数据。

# 安装 sysstat
sudo dnf install -y sysstat

# 启用 sysstat 服务(每10分钟收集一次数据)
sudo systemctl enable --now sysstat

# 查看历史 CPU 使用率(例如查看昨天的数据)
sar -u -f /var/log/sa/sa$(date -d "yesterday" +%d)

# 查看历史磁盘 I/O
sar -d -f /var/log/sa/sa$(date -d "yesterday" +%d)

1.2 实时监控工具

对于实时问题排查,以下工具不可或缺:

  • htop: 交互式进程查看器,比 top 更直观。
  • iotop: 实时监控磁盘 I/O 使用情况。
  • nethogs: 按进程实时监控网络带宽。
  • perf: Linux 内核自带的性能分析工具,用于深入分析 CPU 性能。
# 安装常用监控工具
sudo dnf install -y htop iotop nethogs perf

# 使用 perf 分析 CPU 热点(例如分析 10 秒)
sudo perf top

二、 内核参数调优

内核参数是系统性能的基石,不合理的设置会导致严重的性能问题。

2.1 虚拟内存管理

虚拟内存参数直接影响系统的内存分配和交换行为。

关键参数:

  • vm.swappiness: 控制内核将内存数据交换到磁盘的倾向性。值越低,越倾向于使用物理内存。
  • vm.vfs_cache_pressure: 控制内核回收用于目录和 inode 缓存的内存的倾向性。值越高,回收越积极。
  • vm.dirty_background_ratio & vm.dirty_ratio: 控制脏页(已修改但未写入磁盘的内存页)的阈值,影响磁盘写入的突发性和延迟。

优化示例:

对于数据库服务器(如 MySQL),通常需要降低 swappiness 以减少磁盘 I/O,提高性能。

# 临时修改(重启后失效)
sudo sysctl -w vm.swappiness=10
sudo sysctl -w vm.vfs_cache_pressure=50

# 永久修改(编辑 /etc/sysctl.conf 或创建 /etc/sysctl.d/99-custom.conf)
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.d/99-custom.conf
echo "vm.vfs_cache_pressure=50" | sudo tee -a /etc/sysctl.d/99-custom.conf

# 应用配置
sudo sysctl -p /etc/sysctl.d/99-custom.conf

代码示例:验证 swappiness 对性能的影响

假设我们有一个内存密集型应用,我们可以通过 stress 工具模拟内存压力,并观察 vmstat 的输出。

# 安装 stress
sudo dnf install -y stress

# 在一个终端运行 stress,模拟 4 个进程持续分配内存(每个 1GB)
stress --vm 4 --vm-bytes 1G --vm-keep &

# 在另一个终端运行 vmstat,观察 si(交换进入)和 so(交换出去)的值
vmstat 1

如果 vm.swappiness 设置过高(如默认 60),你会看到 so 值显著增加,表示系统正在积极将内存交换到磁盘,这会导致应用性能下降。将 vm.swappiness 降低到 10 后,so 值会显著减少。

2.2 网络性能优化

对于高并发网络服务(如 Web 服务器、API 网关),网络参数调优至关重要。

关键参数:

  • net.core.somaxconn: 定义了系统中每一个端口最大的 TCP 连接队列长度。对于高并发服务,需要增大此值。
  • net.ipv4.tcp_max_syn_backlog: 定义了 SYN 包(连接请求)的最大队列长度。在 SYN Flood 攻击或高并发连接建立时,需要增大此值。
  • net.ipv4.tcp_tw_reuse & net.ipv4.tcp_tw_recycle: 控制 TIME_WAIT 状态的套接字重用。在高并发短连接场景下,开启 tcp_tw_reuse 可以快速释放端口。
  • net.ipv4.tcp_fin_timeout: 控制 FIN_WAIT_2 状态的超时时间,减少连接占用时间。

优化示例:

对于一个高并发的 Nginx 服务器,建议调整以下参数:

# 编辑 /etc/sysctl.d/99-network.conf
cat <<EOF | sudo tee /etc/sysctl.d/99-network.conf
# 增大 TCP 连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535

# 启用 TIME_WAIT 状态套接字重用
net.ipv4.tcp_tw_reuse = 1

# 缩短 FIN_WAIT_2 状态超时时间
net.ipv4.tcp_fin_timeout = 30

# 增大可用端口范围
net.ipv4.ip_local_port_range = 1024 65535

# 增大 TCP 接收和发送缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
EOF

# 应用配置
sudo sysctl -p /etc/sysctl.d/99-network.conf

验证方法:

使用 ss 命令查看当前连接状态和队列情况。

# 查看所有 TCP 连接的状态统计
ss -s

# 查看特定端口的连接队列(例如 80 端口)
ss -ltn | grep :80

2.3 文件系统与 I/O 调度器

I/O 调度器决定了磁盘 I/O 请求的处理顺序,对磁盘性能影响巨大。

常见 I/O 调度器:

  • noop: 最简单的调度器,适用于 SSD 等非旋转介质。
  • deadline: 保证请求的延迟,适用于混合负载。
  • cfq (Completely Fair Queuing): 默认调度器,为每个进程公平分配 I/O 带宽,适合桌面环境。
  • kyber & mq-deadline: 多队列调度器,适用于 NVMe SSD 和多核 CPU。

优化示例:

对于 NVMe SSD,推荐使用 kybernoop

# 查看当前 I/O 调度器
cat /sys/block/sda/queue/scheduler
# 输出示例: noop [deadline] cfq

# 临时修改(例如将 sda 的调度器改为 kyber)
echo kyber | sudo tee /sys/block/sda/queue/scheduler

# 永久修改(通过 udev 规则)
cat <<EOF | sudo tee /etc/udev/rules.d/60-ioscheduler.rules
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="kyber"
EOF

# 重新加载 udev 规则
sudo udevadm control --reload-rules && sudo udevadm trigger

验证方法:

使用 fio (Flexible I/O Tester) 进行基准测试。

# 安装 fio
sudo dnf install -y fio

# 创建一个随机读写测试文件(1GB,4K 块大小,队列深度 32)
fio --name=random-read-write --ioengine=libaio --rw=randrw --bs=4k --size=1G --numjobs=4 --runtime=60 --group_reporting --direct=1

# 对比不同调度器下的性能(需要在修改调度器后分别运行)

三、 系统资源与服务优化

3.1 CPU 调度策略

Linux 默认使用 CFS (Completely Fair Scheduler) 调度器。对于实时性要求高的应用,可以考虑使用 SCHED_FIFOSCHED_RR

使用 chrt 设置进程调度策略:

# 查看当前进程的调度策略和优先级
chrt -p <PID>

# 将进程设置为 SCHED_FIFO 策略,优先级 99(最高)
sudo chrt -f -p 99 <PID>

# 启动一个新进程并设置调度策略
sudo chrt -f 99 /path/to/your/application

注意: 将普通进程设置为实时调度策略需要 root 权限,且需谨慎,避免系统无响应。

3.2 服务管理与资源限制

使用 systemd 的资源控制功能(cgroups)来限制服务的资源使用,防止某个服务耗尽系统资源。

示例:限制 Nginx 服务的 CPU 和内存使用

# 编辑 Nginx 的 systemd 服务文件
sudo systemctl edit nginx

# 在打开的编辑器中添加以下内容(覆盖默认配置)
[Service]
# 限制 CPU 使用率(例如限制为 2 个 CPU 核心)
CPUQuota=200%

# 限制内存使用(例如限制为 2GB)
MemoryLimit=2G

# 限制进程数
TasksMax=1000

# 保存并退出

重新加载并重启服务:

sudo systemctl daemon-reload
sudo systemctl restart nginx

验证资源限制:

# 查看服务的 cgroup 信息
systemctl status nginx

# 使用 systemd-cgtop 查看 cgroup 的资源使用情况
systemd-cgtop

3.3 磁盘 I/O 优化

除了 I/O 调度器,还可以通过以下方式优化磁盘 I/O:

  • 使用 noatime 挂载选项:禁止记录文件访问时间,减少不必要的磁盘写入。
  • 使用 barriernobarrier:控制磁盘写入的屏障,对于有电池备份的 RAID 卡,可以关闭 barrier 以提高性能。

优化示例:

修改 /etc/fstab 文件,为关键分区添加优化选项。

# 编辑 /etc/fstab
sudo vim /etc/fstab

# 找到对应的分区行,例如 /dev/sda1
# 原行可能为:
# /dev/sda1 / ext4 defaults 1 1

# 修改为(针对 SSD):
/dev/sda1 / ext4 defaults,noatime,nobarrier 1 1

# 重新挂载分区(无需重启)
sudo mount -o remount /

四、 应用层调优

应用层调优需要根据具体的应用类型进行,这里以常见的 Web 服务器(Nginx)和数据库(MySQL)为例。

4.1 Nginx 性能调优

Nginx 是高性能的 Web 服务器,但默认配置可能无法充分发挥其潜力。

关键配置项:

  • worker_processes: 工作进程数,通常设置为 CPU 核心数。
  • worker_connections: 每个工作进程的最大连接数。
  • keepalive_timeout: 保持连接的超时时间。
  • gzip: 启用 Gzip 压缩,减少传输数据量。

优化配置示例 (/etc/nginx/nginx.conf):

# 根据 CPU 核心数自动设置 worker_processes
worker_processes auto;

# 每个工作进程的最大连接数
events {
    worker_connections 1024;
    use epoll; # 使用 epoll 事件模型,适用于 Linux
    multi_accept on; # 允许一次接受多个连接
}

http {
    # 启用 Gzip 压缩
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 保持连接超时时间
    keepalive_timeout 65;
    keepalive_requests 100;

    # 缓存静态文件
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    # 优化 TCP 连接
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # 虚拟主机配置
    server {
        listen 80;
        server_name example.com;

        # 静态文件处理
        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }

        # 动态请求代理到后端
        location / {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

验证 Nginx 配置:

# 检查配置文件语法
sudo nginx -t

# 重新加载配置
sudo nginx -s reload

# 使用 ab (Apache Benchmark) 进行压力测试
sudo dnf install -y httpd-tools
ab -n 10000 -c 100 http://localhost/

4.2 MySQL 性能调优

MySQL 的性能调优涉及多个方面,包括缓冲池、查询缓存、连接数等。

关键配置项 (/etc/my.cnf/etc/mysql/my.cnf):

  • innodb_buffer_pool_size: InnoDB 缓冲池大小,通常设置为物理内存的 50%-70%。
  • innodb_log_file_size: 重做日志文件大小,影响写入性能和恢复时间。
  • max_connections: 最大连接数,根据应用需求设置。
  • query_cache_size: 查询缓存大小(MySQL 8.0 已移除,5.7 及以下版本可考虑)。

优化配置示例(MySQL 8.0):

[mysqld]
# 基础配置
port = 3306
socket = /var/lib/mysql/mysql.sock

# 内存配置(假设服务器有 16GB 内存)
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8

# 日志配置
innodb_log_file_size = 2G
innodb_log_buffer_size = 64M

# 连接配置
max_connections = 500
thread_cache_size = 50

# 查询优化
join_buffer_size = 256K
sort_buffer_size = 256K
read_buffer_size = 256K
read_rnd_buffer_size = 256K

# 其他
innodb_flush_log_at_trx_commit = 2 # 平衡性能和数据安全
innodb_flush_method = O_DIRECT # 直接 I/O,避免双重缓存

验证 MySQL 配置:

-- 登录 MySQL
mysql -u root -p

-- 查看当前缓冲池使用情况
SHOW ENGINE INNODB STATUS\G

-- 查看当前连接数
SHOW STATUS LIKE 'Threads_connected';

-- 查看慢查询日志(需要先开启)
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 超过 2 秒的查询记录为慢查询

使用 pt-query-digest 分析慢查询日志:

# 安装 Percona Toolkit
sudo dnf install -y percona-toolkit

# 分析慢查询日志
pt-query-digest /var/lib/mysql/slow.log

五、 监控与持续优化

性能优化是一个持续的过程,需要建立完善的监控体系。

5.1 监控工具栈

  • Prometheus + Grafana: 云原生监控的黄金组合,用于收集和可视化指标。
  • Zabbix: 传统企业级监控,功能全面。
  • ELK Stack (Elasticsearch, Logstash, Kibana): 用于日志分析和监控。

示例:使用 Prometheus 监控 AlmaLinux 系统指标

# 安装 Node Exporter(用于收集系统指标)
sudo dnf install -y node_exporter

# 启动 Node Exporter
sudo systemctl enable --now node_exporter

# 验证 Node Exporter 是否运行
curl http://localhost:9100/metrics

5.2 自动化优化脚本

可以编写脚本,根据系统负载自动调整某些参数。

示例:根据 CPU 负载动态调整 vm.swappiness

#!/bin/bash
# 动态调整 vm.swappiness 脚本

# 阈值设置
LOAD_THRESHOLD=5.0  # 5.0 是 1 分钟平均负载
SWAPPINESS_HIGH=60
SWAPPINESS_LOW=10

# 获取 1 分钟平均负载
LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}')

# 比较负载并调整 swappiness
if (( $(echo "$LOAD > $LOAD_THRESHOLD" | bc -l) )); then
    echo "High load detected ($LOAD), setting swappiness to $SWAPPINESS_HIGH"
    sysctl -w vm.swappiness=$SWAPPINESS_HIGH
else
    echo "Normal load ($LOAD), setting swappiness to $SWAPPINESS_LOW"
    sysctl -w vm.swappiness=$SWAPPINESS_LOW
fi

将脚本添加到 crontab,每 5 分钟运行一次:

# 编辑 crontab
sudo crontab -e

# 添加以下行
*/5 * * * * /path/to/your/script.sh

六、 总结

AlmaLinux 的性能优化是一个系统工程,需要从内核参数、系统资源、应用层等多个层面入手。本文提供了从基础监控到高级调优的全方位策略,并辅以具体的代码示例和验证方法。

关键要点回顾:

  1. 监控先行:在优化前建立性能基线,使用 sysstathtop 等工具持续监控。
  2. 内核调优:根据负载类型调整虚拟内存、网络和 I/O 参数。
  3. 资源管理:利用 systemd 的 cgroups 功能限制服务资源,防止资源争抢。
  4. 应用优化:针对具体应用(如 Nginx、MySQL)进行配置调优。
  5. 持续迭代:性能优化不是一劳永逸的,需要根据业务变化和监控数据持续调整。

通过遵循本文的指南,您可以系统地提升 AlmaLinux 服务器的性能,确保其稳定、高效地运行。记住,任何优化都应以实际测试和监控数据为依据,避免盲目调整。