引言
AlmaLinux 作为 CentOS 的继任者,以其稳定性和企业级特性赢得了广泛认可。然而,仅仅安装系统是不够的,要充分发挥其性能潜力,需要从内核参数、系统资源、到应用层进行全方位的调优。本文将深入探讨如何在 AlmaLinux 上进行性能优化,涵盖从基础内核调优到高级应用层优化的实战技巧。
1. 系统性能监控与基准测试
在进行任何优化之前,必须先了解系统的当前状态。性能监控和基准测试是优化的基础。
1.1 常用监控工具
- top/htop:实时查看系统资源使用情况。
- vmstat:报告虚拟内存统计信息。
- iostat:监控磁盘 I/O 统计。
- netstat/ss:网络连接和套接字统计。
- dstat:综合系统资源监控工具。
1.2 基准测试工具
- sysbench:综合性能测试工具,支持 CPU、内存、磁盘、数据库等测试。
- fio:灵活的 I/O 测试工具。
- iperf3:网络性能测试。
- phoronix-test-suite:全面的硬件和系统性能测试套件。
1.3 实战:使用 sysbench 进行基准测试
# 安装 sysbench
sudo dnf install -y sysbench
# CPU 测试:计算素数
sysbench cpu --cpu-max-prime=20000 run
# 内存测试:分配和读取内存
sysbench memory --memory-block-size=1M --memory-total-size=100G run
# 磁盘测试:随机读写
sysbench fileio --file-total-size=10G --file-test-mode=rndrw --time=300 --threads=4 run
# 数据库测试(以 MySQL 为例)
sysbench oltp_read_write --table-size=1000000 --threads=4 --time=300 --report-interval=10 run
通过这些测试,你可以获得系统的基准性能数据,为后续优化提供参考。
2. 内核调优
内核参数直接影响系统性能。AlmaLinux 基于 RHEL,使用 sysctl 进行内核参数调整。
2.1 内存管理优化
2.1.1 调整虚拟内存参数
# 查看当前虚拟内存参数
sysctl vm.swappiness
# 降低交换倾向,提高性能(适用于内存充足的服务器)
sudo sysctl -w vm.swappiness=10
# 调整脏页比例,平衡 I/O 和内存使用
sudo sysctl -w vm.dirty_ratio=10
sudo sysctl -w vm.dirty_background_ratio=5
# 调整内存回收策略
sudo sysctl -w vm.vfs_cache_pressure=50
2.1.2 大页内存(HugePages)
对于内存密集型应用(如数据库),启用大页内存可以减少 TLB 压力,提高性能。
# 检查当前大页配置
grep Huge /proc/meminfo
# 配置大页数量(例如 1024 个 2MB 大页)
sudo sysctl -w vm.nr_hugepages=1024
# 永久生效:编辑 /etc/sysctl.conf
echo "vm.nr_hugepages=1024" | sudo tee -a /etc/sysctl.conf
# 在应用中使用大页(以 PostgreSQL 为例)
# 在 postgresql.conf 中添加:
# huge_pages = on
# shared_buffers = 4GB # 必须是大页大小的整数倍
2.2 磁盘 I/O 优化
2.1.1 I/O 调度器选择
AlmaLinux 支持多种 I/O 调度器:noop、deadline、cfq、kyber、mq-deadline。
# 查看当前 I/O 调度器
cat /sys/block/sda/queue/scheduler
# 为 SSD 选择 kyber 或 none(无调度)
echo kyber | sudo tee /sys/block/sda/queue/scheduler
# 永久生效:创建 udev 规则
sudo tee /etc/udev/rules.d/60-ioscheduler.rules <<EOF
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="kyber"
EOF
2.2.2 调整 I/O 队列深度
# 查看当前队列深度
cat /sys/block/sda/queue/nr_requests
# 增加队列深度以提高并发 I/O 能力
echo 128 | sudo tee /sys/block/sda/queue/nr_requests
# 永久生效:编辑 /etc/sysctl.conf
echo "block.sda.queue.nr_requests=128" | sudo tee -a /etc/sysctl.conf
2.3 网络优化
2.3.1 TCP 参数调优
# 查看当前 TCP 参数
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem
# 调整 TCP 缓冲区大小(适用于高吞吐量网络)
sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sudo sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
# 启用 TCP BBR 拥塞控制算法(适用于高延迟网络)
sudo sysctl -w net.core.default_qdisc=fq
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
# 调整连接跟踪表大小(适用于高并发连接)
sudo sysctl -w net.netfilter.nf_conntrack_max=1000000
2.3.2 网络接口优化
# 查看网卡信息
ethtool -i eth0
# 启用多队列(RSS)以提高多核 CPU 利用率
sudo ethtool -L eth0 combined 8
# 调整网卡缓冲区大小
sudo ethtool -G eth0 rx 4096 tx 4096
# 启用 TCP 卸载功能(如果网卡支持)
sudo ethtool -K eth0 tso on gso on gro on lro on
2.4 进程调度优化
2.4.1 CPU 亲和性
# 查看 CPU 信息
lscpu
# 将特定进程绑定到 CPU 核心(例如绑定到 CPU 0-3)
taskset -cp 0-3 <pid>
# 永久生效:使用 systemd 服务配置
# 在服务文件中添加:
# [Service]
# CPUAffinity=0-3
2.4.2 实时优先级
# 设置进程的实时优先级(需要 root 权限)
sudo chrt -f -p 99 <pid>
# 在 systemd 服务中设置实时优先级
# [Service]
# CPUSchedulingPolicy=rr
# CPUSchedulingPriority=99
3. 文件系统优化
3.1 选择合适的文件系统
- XFS:适合大文件和高并发 I/O,AlmaLinux 默认。
- ext4:通用性好,适合大多数场景。
- Btrfs:支持快照和压缩,适合开发环境。
3.2 挂载选项优化
# 查看当前挂载选项
mount | grep /dev/sda1
# 优化 XFS 挂载选项
sudo mount -o noatime,nodiratime,logbufs=8,logbsize=256k /dev/sda1 /data
# 永久生效:编辑 /etc/fstab
/dev/sda1 /data xfs noatime,nodiratime,logbufs=8,logbsize=256k 0 0
3.3 文件系统参数调整
3.3.1 XFS 参数
# 调整 XFS 日志大小(适用于高写入负载)
sudo xfs_admin -L 1G /dev/sda1
# 调整 XFS 分配器参数
sudo xfs_admin -u /dev/sda1
# 在交互式界面中调整 agcount、agsize 等参数
3.3.2 ext4 参数
# 调整 ext4 日志大小
sudo tune2fs -J size=1024 /dev/sda1
# 调整保留块比例(默认 5%,可降低以增加可用空间)
sudo tune2fs -m 1 /dev/sda1
4. 应用层优化
4.1 Web 服务器优化(以 Nginx 为例)
4.1.1 Nginx 配置优化
# /etc/nginx/nginx.conf
worker_processes auto; # 自动设置为 CPU 核心数
worker_connections 65536; # 每个 worker 进程的最大连接数
worker_rlimit_nofile 65536; # worker 进程可打开的最大文件数
events {
use epoll; # 高性能事件模型
multi_accept on; # 一次接受多个连接
}
http {
# 缓冲区优化
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# 连接超时
keepalive_timeout 65;
keepalive_requests 100;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 缓存配置
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 负载均衡(如果有多台服务器)
upstream backend {
least_conn;
server 192.168.1.101:80 max_fails=3 fail_timeout=30s;
server 192.168.1.102:80 max_fails=3 fail_timeout=30s;
keepalive 32;
}
}
4.1.2 系统级优化
# 调整系统文件描述符限制
echo "* soft nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "* hard nofile 65536" | sudo tee -a /etc/security/limits.conf
# 调整内核参数以支持高并发连接
sudo sysctl -w net.core.somaxconn=65535
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=65535
# 永久生效:编辑 /etc/sysctl.conf
4.2 数据库优化(以 MySQL/MariaDB 为例)
4.2.1 MySQL 配置优化
# /etc/my.cnf.d/server.cnf
[mysqld]
# 内存配置
innodb_buffer_pool_size = 70% of total RAM # 例如 16GB RAM -> 11GB
innodb_log_file_size = 2G
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 2 # 平衡性能和数据安全
# 连接配置
max_connections = 500
thread_cache_size = 100
table_open_cache = 2000
# 查询缓存(MySQL 8.0 已移除,适用于 5.7 及以下)
query_cache_type = 0 # 建议禁用,使用应用层缓存
# 日志配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# 其他优化
innodb_flush_method = O_DIRECT # 避免双重缓冲
innodb_file_per_table = 1
innodb_read_io_threads = 8
innodb_write_io_threads = 8
4.2.2 索引优化
-- 检查慢查询日志
SHOW VARIABLES LIKE 'slow_query_log%';
-- 使用 EXPLAIN 分析查询
EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';
-- 创建合适的索引
CREATE INDEX idx_email ON users(email);
-- 使用覆盖索引
CREATE INDEX idx_email_name ON users(email, name);
-- 定期分析表
ANALYZE TABLE users;
4.3 应用服务器优化(以 Java 应用为例)
4.3.1 JVM 调优
# 常见 JVM 参数示例
JAVA_OPTS="
-Xms4g -Xmx4g # 初始和最大堆内存
-XX:+UseG1GC # 使用 G1 垃圾回收器
-XX:MaxGCPauseMillis=200 # 目标最大 GC 暂停时间
-XX:InitiatingHeapOccupancyPercent=45 # G1 启动并发标记的阈值
-XX:+HeapDumpOnOutOfMemoryError # OOM 时生成堆转储
-XX:HeapDumpPath=/var/log/java/heapdump.hprof
-XX:+PrintGCDetails -XX:+PrintGCDateStamps # GC 日志
-Xloggc:/var/log/java/gc.log
-XX:+UseStringDeduplication # 字符串去重(G1 特有)
-XX:MaxMetaspaceSize=256m # 元空间大小
-XX:+DisableExplicitGC # 禁用 System.gc()
-XX:+UseCompressedOops # 启用压缩指针(64位系统)
-XX:+UseCompressedClassPointers
"
4.3.2 应用配置优化
# Spring Boot application.yml 示例
server:
tomcat:
max-threads: 200 # 最大线程数
min-spare-threads: 20 # 最小空闲线程数
max-connections: 10000 # 最大连接数
connection-timeout: 5000 # 连接超时(毫秒)
keep-alive-timeout: 60000 # 保持连接超时
max-http-form-post-size: 10MB # 表单大小限制
spring:
datasource:
hikari:
maximum-pool-size: 50 # 连接池最大连接数
minimum-idle: 10 # 最小空闲连接
connection-timeout: 30000 # 连接超时
idle-timeout: 600000 # 空闲超时
max-lifetime: 1800000 # 连接最大存活时间
leak-detection-threshold: 60000 # 连接泄漏检测阈值
jpa:
properties:
hibernate:
jdbc:
batch_size: 50 # 批处理大小
order_inserts: true # 插入顺序
order_updates: true # 更新顺序
generate_statistics: true # 生成统计信息
5. 容器化环境优化
5.1 Docker 优化
5.1.1 Docker 守护进程配置
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 65536,
"Soft": 65536
}
},
"exec-opts": ["native.cgroupdriver=systemd"],
"max-concurrent-downloads": 3,
"max-concurrent-uploads": 3,
"live-restore": true,
"no-new-privileges": true,
"userns-remap": "default"
}
5.1.2 容器资源限制
# 运行容器时限制资源
docker run -d \
--name myapp \
--memory=2g \
--memory-swap=2g \
--cpus="1.5" \
--cpu-shares=512 \
--ulimit nofile=65536:65536 \
--restart=unless-stopped \
myapp:latest
# 使用 docker-compose
version: '3.8'
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '1.5'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
ulimits:
nofile:
soft: 65536
hard: 65536
5.2 Kubernetes 优化
5.2.1 资源请求和限制
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"
env:
- name: JAVA_OPTS
value: "-Xms1g -Xmx1g -XX:+UseG1GC"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
5.2.2 调度器优化
# nodeSelector 和 affinity
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
topologyKey: kubernetes.io/hostname
tolerations:
- key: "dedicated"
operator: "Equal"
value: "app"
effect: "NoSchedule"
6. 监控与告警
6.1 监控体系搭建
6.1.1 Prometheus + Grafana
# docker-compose.yml for Prometheus and Grafana
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
ports:
- "9090:9090"
restart: unless-stopped
grafana:
image: grafana/grafana:latest
container_name: grafana
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
ports:
- "3000:3000"
restart: unless-stopped
volumes:
prometheus_data:
grafana_data:
6.1.2 Node Exporter 配置
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
- job_name: 'mysql'
static_configs:
- targets: ['localhost:9104']
- job_name: 'nginx'
static_configs:
- targets: ['localhost:9113']
- job_name: 'java-app'
static_configs:
- targets: ['localhost:8080']
6.2 告警规则
# alert.rules.yml
groups:
- name: node_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is above 80% for 5 minutes"
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is above 85% for 5 minutes"
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100) < 10
for: 5m
labels:
severity: critical
annotations:
summary: "Low disk space on {{ $labels.instance }}"
description: "Disk space is below 10% on {{ $labels.instance }}"
7. 性能调优实战案例
7.1 案例:高并发 Web 服务器优化
场景:一台 16 核 CPU、64GB 内存的 AlmaLinux 服务器,运行 Nginx 和 PHP-FPM,需要处理 10,000+ 并发连接。
优化步骤:
内核调优: “`bash
增加文件描述符限制
echo “* soft nofile 100000” >> /etc/security/limits.conf echo “* hard nofile 100000” >> /etc/security/limits.conf
# 调整 TCP 参数 sysctl -w net.core.somaxconn=65535 sysctl -w net.ipv4.tcp_max_syn_backlog=65535 sysctl -w net.ipv4.tcp_tw_reuse=1 sysctl -w net.ipv4.tcp_fin_timeout=30
# 调整内存参数 sysctl -w vm.swappiness=10 sysctl -w vm.dirty_ratio=10 sysctl -w vm.dirty_background_ratio=5
2. **Nginx 优化**:
```nginx
worker_processes auto;
worker_connections 65536;
worker_rlimit_nofile 100000;
events {
use epoll;
multi_accept on;
}
http {
# 连接优化
keepalive_timeout 65;
keepalive_requests 1000;
# 缓冲区优化
client_body_buffer_size 128k;
client_max_body_size 10m;
# Gzip 压缩
gzip on;
gzip_comp_level 6;
# 负载均衡
upstream php_backend {
least_conn;
server 127.0.0.1:9000 max_fails=3 fail_timeout=30s;
keepalive 32;
}
}
PHP-FPM 优化:
; /etc/php-fpm.d/www.conf [www] pm = dynamic pm.max_children = 200 pm.start_servers = 50 pm.min_spare_servers = 50 pm.max_spare_servers = 100 pm.max_requests = 5000 request_terminate_timeout = 30系统监控: “`bash
安装监控工具
dnf install -y node_exporter
# 启动服务 systemctl enable –now node_exporter
# 配置 Prometheus 和 Grafana 进行监控
**优化结果**:
- 并发连接数从 5,000 提升到 15,000+
- 平均响应时间从 200ms 降低到 50ms
- CPU 利用率从 90% 降低到 60%
### 7.2 案例:数据库性能优化
**场景**:MySQL 数据库在高并发写入场景下出现性能瓶颈。
**优化步骤**:
1. **硬件层面**:
- 使用 SSD 磁盘
- 增加内存到 64GB
- 配置 RAID 10
2. **MySQL 配置优化**:
```ini
[mysqld]
innodb_buffer_pool_size = 48G # 75% of 64GB
innodb_log_file_size = 4G
innodb_log_buffer_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
innodb_read_io_threads = 16
innodb_write_io_threads = 16
innodb_buffer_pool_instances = 8
innodb_log_file_size = 2G
innodb_log_buffer_size = 64M
- 查询优化: “`sql – 分析慢查询 SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 1;
– 使用 EXPLAIN 分析 EXPLAIN SELECT * FROM orders WHERE customer_id = 12345;
– 创建复合索引 CREATE INDEX idx_customer_date ON orders(customer_id, order_date);
– 使用分区表 ALTER TABLE orders PARTITION BY RANGE (YEAR(order_date)) (
PARTITION p2022 VALUES LESS THAN (2023),
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025)
);
– 使用读写分离 – 主库写入,从库读取
3. **配置优化**:
```ini
[mysqld]
# 内存优化
innodb_buffer_pool_size = 48G # 64GB 内存的 75%
innodb_buffer_pool_instances = 8
# 日志优化
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 4G
innodb_log_buffer_size = 128M
# 并发优化
innodb_thread_concurrency = 32
innodb_read_io_threads = 16
innodb_write_io_threads = 16
# 其他优化
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_flush_neighbors = 0
优化结果:
- QPS 从 500 提升到 3,000
- 平均查询时间从 50ms 降低到 10ms
- 磁盘 I/O 等待时间减少 70%
8. 性能调优最佳实践
8.1 调优原则
- 监控先行:在调优前建立完善的监控体系
- 逐步调整:每次只调整一个参数,观察效果
- 记录变更:详细记录每次调整的参数和效果
- 测试验证:在生产环境前在测试环境充分验证
- 回滚计划:准备好回滚方案,以防性能下降
8.2 常见误区
- 过度调优:不是所有参数都需要调整
- 忽视应用层:内核调优不能解决所有问题
- 忽略硬件限制:软件调优无法突破硬件瓶颈
- 不考虑业务场景:不同业务需要不同的调优策略
8.3 持续优化
性能优化不是一次性的工作,而是持续的过程:
- 定期审查:每季度审查一次系统性能
- 容量规划:根据业务增长预测资源需求
- 技术更新:关注新版本的性能改进
- 知识分享:团队内分享优化经验和案例
9. 总结
AlmaLinux 性能优化是一个系统工程,需要从内核、系统、应用多个层面进行。通过本文的实战指南,你可以:
- 掌握监控方法:使用合适的工具监控系统状态
- 理解内核参数:根据业务需求调整关键内核参数
- 优化应用配置:针对不同应用进行针对性优化
- 建立监控体系:实现性能问题的早期发现和预警
- 遵循最佳实践:避免常见误区,持续优化系统
记住,性能优化的目标不是追求极致的数字,而是在资源、成本和性能之间找到最佳平衡点。每个系统都是独特的,需要根据具体业务场景进行定制化优化。
通过持续的监控、分析和调整,你的 AlmaLinux 系统将能够稳定、高效地支撑业务发展,充分发挥其性能潜力。
