在 2核4G(2 vCPU, 4GB RAM)的配置下,同时运行 MySQL 和 Nginx 属于资源非常紧张的场景。MySQL 是内存大户,Nginx 是 CPU/IO 敏感型服务,两者争抢资源时容易导致系统卡顿或崩溃。
以下是针对该配置的关键优化参数和建议,分为 MySQL 优化、Nginx 优化、操作系统级优化 和 架构建议 四部分:
一、MySQL 优化(核心重点)
MySQL 对内存极度敏感,默认配置通常不适合小内存服务器。首要目标是限制 MySQL 的最大内存占用,防止 OOM(内存溢出)。
1. my.cnf 关键参数调整
[mysqld]
# 1. 连接数控制(根据并发量调整,避免创建过多线程消耗内存)
max_connections = 50 # 默认151,小内存务必降低
# 2. 内存分配核心参数
innodb_buffer_pool_size = 1G # 【最关键】InnoDB缓冲池大小
# 建议:总内存4G - OS(1G) - MySQL其他开销(1G) - Nginx预留(0.5G) ≈ 1.5~2G
# 但为了安全起见,初期设为 1G~1.5G,观察后再调整。
# 注意:如果只使用 MyISAM 引擎,此参数无效,但现代应用几乎都用 InnoDB。
innodb_log_file_size = 256M # 日志文件大小,增大可减少刷盘频率,提升性能
innodb_flush_log_at_trx_commit = 2 # 性能优先:每秒刷盘一次(牺牲少量数据安全性,换取速度)
# 如果追求数据安全,设为 1,但性能会下降。
# 3. 临时表与排序优化
tmp_table_size = 64M # 内部临时表最大内存大小
max_heap_table_size = 64M # 用户创建的 MEMORY 表最大大小
# 这两个值必须相等,否则较小的那个生效。
# 4. 查询缓存(MySQL 5.7+ 已移除,8.0 完全移除,若用 5.6 可启用)
# query_cache_type = 1
# query_cache_size = 32M # 仅适用于旧版本
# 5. 线程缓存
thread_cache_size = 8 # 减少线程创建开销
# 6. 关闭不必要的功能
performance_schema = OFF # 关闭性能模式,节省内存和CPU
2. 为什么这样设置?
innodb_buffer_pool_size:这是 MySQL 性能的命脉。设置为 1G~1.5G 可以确保热点数据留在内存中,大幅减少磁盘 I/O。max_connections:每个连接都会占用约 2~5MB 内存(取决于查询复杂度)。50 个连接最多占用 ~250MB,加上 Buffer Pool 的 1G,MySQL 总内存控制在 ~1.5G 左右,留出足够空间给系统和 Nginx。
二、Nginx 优化
Nginx 本身轻量,但在高并发或小内存下需注意 worker 数量和缓冲区。
1. nginx.conf 关键参数
worker_processes auto; # 自动匹配 CPU 核心数(2核=2进程)
events {
worker_connections 1024; # 每个 worker 最大连接数
# 总并发连接数 = worker_processes * worker_connections = 2 * 1024 = 2048
}
http {
# 1. 开启 gzip 压缩,减少带宽占用,降低传输压力
gzip on;
gzip_min_length 1k;
gzip_comp_level 2; # 压缩级别不宜过高,节省CPU
gzip_types text/plain application/json application/javascript text/css;
# 2. 缓冲区优化(根据实际请求大小调整)
client_body_buffer_size 16k;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
# 3. 超时设置(快速释放空闲连接,节省内存)
keepalive_timeout 65;
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
# 4. 文件描述符限制
worker_rlimit_nofile 65535;
}
2. 注意事项
- 不要过度调大
worker_connections:在 4G 内存下,过高的并发会导致大量上下文切换和内存碎片。 - 启用 Gzip:显著减少网络传输数据量,间接减轻服务器负载。
三、操作系统级优化(Linux)
1. 内存管理
# 查看当前内存使用
free -h
# 推荐 swappiness 值:60~100
# 小内存服务器应允许更多使用 Swap,避免直接 OOM
echo "vm.swappiness=100" >> /etc/sysctl.conf
sysctl -p
2. 文件描述符限制
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
# /etc/sysctl.conf
fs.file-max = 65535
3. 禁用不必要的服务
- 关闭
firewalld(改用iptables或云厂商安全组) - 关闭
auditd(审计服务,消耗大量 CPU 和 IO) - 关闭
chronyd(如果时间同步要求不高,或使用轻量级 ntpdate)
四、关键架构建议(至关重要!)
⚠️ 重要提醒:2核4G 同时跑 MySQL + Nginx + 应用(如 Java/PHP)是非常危险的。
1. 分离部署(强烈推荐)
- 方案 A:MySQL 单独一台服务器(即使最低配 2C4G),Nginx + 应用在一台。
- 方案 B:使用云数据库 RDS,本地只跑 Nginx + 应用。
- 原因:MySQL 的随机读写对磁盘 IOPS 要求极高,且内存波动大。一旦 MySQL 因内存不足触发 swap 或 OOM,整个系统会卡死。
2. 如果必须同机运行:
- 使用轻量级应用层:不要用 Java(JVM 至少需 1~2G 堆内存),建议使用 PHP-FPM、Python (Flask/Django)、Go 或 Node.js,这些语言内存占用更低。
- 监控内存:使用
htop或top实时监控,确保 MySQL 的 RSS 内存不超过 2G。 - 启用 Swap:虽然 Swap 慢,但比 OOM kill 好。确保有 2~4G 的 Swap 分区。
五、验证与监控
-
检查 MySQL 状态
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW STATUS LIKE 'Threads_created'; -- 如果增长过快,增加 thread_cache_size SHOW STATUS LIKE 'Handler_read_rnd_next'; -- 高值表示全表扫描,需加索引 -
检查系统负载
top -c # 关注 load average 是否超过 CPU 核心数(2) # 关注 MEM 使用率,Swap 使用率 -
压力测试
- 使用
ab或wrk对 Nginx 进行简单压测,观察错误率和响应时间。 - 模拟高并发查询 MySQL,观察是否出现
Too many connections或InnoDB buffer pool full。
- 使用
总结配置清单(2C4G 基准版)
| 组件 | 关键参数 | 说明 |
|---|---|---|
| MySQL | innodb_buffer_pool_size=1G |
核心内存,保证热点数据在内存 |
max_connections=50 |
限制连接数,防内存耗尽 | |
tmp_table_size=64M |
控制临时表内存使用 | |
performance_schema=OFF |
节省资源 | |
| Nginx | worker_processes=2 |
匹配 CPU 核心 |
gzip on |
减少带宽,提升用户体验 | |
keepalive_timeout=65 |
合理复用连接 | |
| OS | vm.swappiness=100 |
允许使用 Swap,防 OOM |
fs.file-max=65535 |
提高文件句柄上限 |
最后建议:如果业务流量持续增长,第一优先级是升级 MySQL 到独立服务器,而不是继续优化单机参数。
云知识CLOUD