在 2核4G 的服务器上同时运行 MySQL、Redis 和 Nginx(典型 LEMP 栈),资源已非常紧张,必须精细化配置和权衡,否则极易出现内存溢出(OOM)、CPU 饱和、服务响应迟缓甚至崩溃。以下是针对该场景的实用、安全、可落地的优化建议,按优先级和模块组织:
✅ 一、核心原则(先决条件)
- 禁止默认安装:禁用所有非必要服务(如 MySQL 的 Performance Schema、InnoDB 各种监控表)。
- 不启用 swap(但谨慎配置):2G 内存以下 swap 易引X_X顿;建议配置
vm.swappiness=1(仅在极端内存压力下使用 swap),不推荐完全禁用(避免 OOM killer 杀进程)。 - 统一时间 & 日志轮转:
chrony同步时间;logrotate管理日志,防止/var/log占满磁盘。
✅ 二、内存分配策略(关键!总内存 ≈ 3.8G 可用)
| 组件 | 推荐最大内存占用 | 说明 |
|---|---|---|
| MySQL | ≤ 1.2G | InnoDB 缓冲池是核心,占大头;其他缓冲区严格压缩 |
| Redis | ≤ 512M | 设定 maxmemory 450mb + maxmemory-policy allkeys-lru,防 OOM |
| Nginx | ≤ 256M | 主要消耗在 worker 进程和缓存,静态文件少则更低 |
| 系统/OS/预留 | ≥ 800M | 包含内核、SSH、监控、临时缓冲等,不可压缩 |
⚠️ 总和控制在 ≤ 3.5G,留 300MB+ 应对突发(如日志写入、连接峰值)
✅ 三、各组件具体优化配置
🔹 MySQL(推荐 MySQL 8.0+,关闭冗余功能)
# /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# —— 内存相关 ——
innodb_buffer_pool_size = 1024M # 必须!占 MySQL 内存 80%+
innodb_log_file_size = 64M # 减小日志大小(默认 48M→64M 平衡性能/恢复)
innodb_flush_method = O_DIRECT # 避免双缓冲(Linux 下推荐)
# —— 连接与线程 ——
max_connections = 100 # 默认151,2C 100 足够;超时回收更快
wait_timeout = 60 # 空闲连接 60s 断开
interactive_timeout = 60
# —— 关闭非必要功能(省内存+CPU)——
skip-log-bin # ❗生产环境慎用!若无需主从/备份,关闭 binlog
skip-performance_schema # 必关!节省 ~200MB 内存
innodb_stats_on_metadata = OFF # 防止 INFORMATION_SCHEMA 查询卡顿
table_open_cache = 400 # 降低默认值(2000→400)
tmp_table_size = 32M
max_heap_table_size = 32M
# —— 其他 ——
log-error = /var/log/mysql/error.log
slow_query_log = OFF # 开发调试时再开启
✅ 验证命令:mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
✅ 重启后检查内存:ps aux --sort=-%mem | head -10
🔹 Redis(推荐 Redis 7.x,内存敏感型配置)
# /etc/redis/redis.conf
# —— 内存限制 ——
maxmemory 450mb
maxmemory-policy allkeys-lru # 或 volatile-lru(若 key 有 TTL)
maxmemory-samples 5 # 降低采样数(默认5,足够)
# —— 连接与性能 ——
bind 127.0.0.1 # 仅本地访问(Nginx → PHP → Redis)
protected-mode yes # 安全前提
tcp-keepalive 300 # 保持连接活跃
timeout 300 # 空闲连接超时
# —— 持久化(2C4G 不推荐 RDB+AOF 混合)——
save "" # ❌ 关闭 RDB 自动快照(由外部脚本定时备份)
appendonly no # ❌ 关闭 AOF(除非数据绝对不能丢,否则选其一)
# 如需持久化:每天低峰期 `redis-cli bgsave` 手动触发 RDB,并 rsync 到远程
# —— 其他 ——
lazyfree-lazy-eviction yes # 内存不足时异步删除,防阻塞
lazyfree-lazy-expire yes
✅ 启动后确认:redis-cli info memory | grep -E "used_memory_human|maxmemory_human"
🔹 Nginx(轻量、静态优先)
# /etc/nginx/nginx.conf
user www-data;
worker_processes 2; # 严格匹配 CPU 核数
worker_rlimit_nofile 65535;
events {
worker_connections 1024; # 每 worker 最多 1024 连接(2×1024=2048 并发足够)
use epoll; # Linux 高效事件模型
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# —— 日志精简 ——
access_log /var/log/nginx/access.log main buffer=64k flush=5s;
log_not_found off;
error_log /var/log/nginx/error.log warn;
# —— 缓存与连接 ——
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15; # 降低长连接时间(默认75s→15s)
client_header_timeout 10;
client_body_timeout 10;
send_timeout 10;
# —— 静态资源缓存(减压 PHP/MySQL)——
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# —— 限制资源(防攻击/误配)——
client_max_body_size 2m;
client_header_buffer_size 1k;
large_client_header_buffers 2 1k;
include /etc/nginx/conf.d/*.conf;
}
✅ PHP-FPM 建议搭配(若用 PHP):
pm = staticpm.max_children = 20(2C 下 15–25 安全区间)pm.start_servers = 5,pm.min_spare_servers = 3,pm.max_spare_servers = 8
✅ 四、系统级优化(Linux Kernel)
# 1. 降低 swappiness(减少 swap 使用倾向)
echo 'vm.swappiness=1' >> /etc/sysctl.conf
sysctl -p
# 2. 提升网络连接能力(应对并发)
echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 65535' >> /etc/sysctl.conf
echo 'fs.file-max = 2097152' >> /etc/sysctl.conf
sysctl -p
# 3. 限制各服务 ulimit(防单服务耗尽句柄)
# 在 /etc/systemd/system/mysqld.service.d/override.conf 中添加:
[Service]
LimitNOFILE=65535
LimitNPROC=4096
# 同理为 redis-server.service、nginx.service 添加相同配置
systemctl daemon-reload
✅ 五、监控与告警(必备!)
- 实时监控:
htop、iotop、mytop、redis-cli info、nginx -T | grep "log_format" - 轻量监控工具(推荐):
netdata(<50MB 内存,Web 界面,一键安装)- 或
prometheus + node_exporter + mysqld_exporter + redis_exporter(稍重,但精准)
- 关键告警阈值:
- 内存使用 > 90%
- MySQL
Threads_connected > 80 - Redis
used_memory > 420mb - Nginx
Active connections > 1500
✅ 六、强烈建议的架构改进(长期)
| 场景 | 建议 |
|---|---|
| 流量 > 1000 PV/天 或 有用户上传 | 将静态资源(图片/CSS/JS)托管到 CDN 或对象存储(如腾讯云 COS),Nginx 仅作反向X_X |
| 数据库读多写少 | 用 Redis 缓存热点查询(如首页、用户信息),加 Cache-Control 头 |
| 业务增长明显 | 拆分部署:Nginx + PHP → 2C4G;MySQL → 独立 2C4G(或云数据库 RDS);Redis → 独立 1C2G |
| 零停机需求 | 至少保留 1 台同配置备用机,配合 Keepalived 实现高可用 |
🚫 绝对避免的操作
- ❌ 开启 MySQL
query_cache(MySQL 8.0 已移除,5.7 中反而降低性能) - ❌ Redis 设置
maxmemory为 0(即不限制)→ 必然 OOM - ❌ Nginx
worker_processes auto(在容器或小内存环境会设为 4+,加剧争抢) - ❌ 在同一台机器跑 MySQL + Redis + Elasticsearch(ES 至少需 2G 内存)
✅ 附:快速检查清单(部署后执行)
# 1. 总内存占用
free -h && ps aux --sort=-%mem | head -10
# 2. 各服务内存上限验证
grep -i "buffer_pool|maxmemory|worker_process" /etc/{my.cnf,redis/redis.conf,nginx/nginx.conf}
# 3. 连接数是否合理
ss -s | grep "TCP:"; netstat -an | grep :3306 | wc -l; redis-cli info clients | grep connected
# 4. 日志是否循环
ls -lh /var/log/{mysql,nginx,redis}*
如需,我可为你生成:
- ✅ 一键优化脚本(自动修改配置 + 重启服务)
- ✅ Docker Compose 版(带资源限制
mem_limit: 1200m) - ✅ 针对 WordPress / Laravel / Django 的专项调优
欢迎补充你的具体场景(如:是否跑 PHP?是否需要 HTTPS?并发预估?数据重要性?),我可以进一步定制方案。
云小栈