小型项目用1核1G服务器部署MySQL和Redis,如何优化避免性能瓶颈?

在1核1G这样极度受限的资源环境下,同时运行 MySQL 和 Redis 确实面临巨大的挑战。内存仅1GB意味着两者必须严格共享资源,任何一方的内存溢出都会导致系统崩溃或交换(Swap)严重拖慢性能。

以下是针对该场景的核心优化策略,按优先级排序:


🚨 首要原则:避免 Swap,保证内存安全

1G 内存非常紧张,强烈建议禁用 Swap 或设置极低的 swappiness。

  • 原因:一旦触发 Swap,磁盘 I/O 会成为巨大瓶颈,MySQL/Redis 响应时间会飙升到秒级甚至分钟级。
  • 操作:
    # 临时禁用
    sudo swapoff -a
    # 永久禁用(修改 /etc/fstab 注释掉 swap 行)

一、MySQL 优化(重点:减少内存占用 + 降低连接开销)

1. 内存配置(最关键)

MySQL 默认配置会尝试使用大量内存,必须手动限制。

[mysqld]
# 最大连接数设为极低值(小型项目通常并发低)
max_connections = 20

# InnoDB 缓冲池:只分配总内存的 30%-40%(约 300-400MB)
innodb_buffer_pool_size = 256M

# 日志文件组大小,避免频繁刷盘
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M

# 禁用不必要的功能
skip-name-resolve  # 跳过 DNS 解析,提升连接速度
local-infile=0     # 禁用本地加载,提升安全与性能

2. 存储引擎选择

  • 务必使用 InnoDB,不要使用 MyISAM。
  • 如果数据量极小(< 10万行),且无需事务,可考虑 MyISAM(但 InnoDB 是主流,建议坚持)。

3. 查询优化

  • *避免 `SELECT `**:只查询需要的字段。
  • 添加索引:确保 WHERE、JOIN、ORDER BY 字段有索引。
  • 避免大事务:小型项目中尽量保持事务简短。

4. 字符集

  • 使用 utf8mb4,但注意它比 utf8 多占空间。如果确定不需要 emoji,可用 utf8 节省少量内存。

二、Redis 优化(重点:控制内存 + 淘汰策略)

1. 内存限制(强制)

# 设置最大内存为 256MB~512MB(留出空间给 MySQL)
maxmemory 256mb

# 关键:设置淘汰策略!否则 Redis 会 OOM 崩溃
# allkeys-lru: 所有键使用 LRU 算法淘汰最近最少使用的键
maxmemory-policy allkeys-lru

2. 持久化优化

  • RDB vs AOF:
    • 小型项目建议启用 RDB(快照),因为 AOF 重写会消耗大量 CPU 和内存。
    • 如果数据重要性高,启用 AOF 但设置 appendfsync everysec(每秒同步一次)。
  • 关闭 BGSAVE 期间的 fork 开销:
    no-appendfsync-on-rewrite yes
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb

3. 数据结构优化

  • 尽量使用 Hash 而非多个 String。
  • 避免存储大 Value(> 1KB),否则会增加内存碎片和序列化开销。

三、系统级优化

1. 操作系统参数调优

# 增加文件描述符限制
ulimit -n 65535

# 内核参数优化(/etc/sysctl.conf)
net.core.somaxconn = 128
net.ipv4.tcp_max_syn_backlog = 128
vm.swappiness = 0  # 彻底禁用 Swap

2. 使用轻量级 Web 服务器

  • 如果前端也部署在同一台机器,不要用 Nginx + PHP-FPM + Node.js 等重型组合。
  • 推荐:Nginx + PHP-FPM(PHP 7.x/8.x 性能更好,内存更少)。
  • 或者使用 Go/Python (FastAPI) 等静态编译语言,减少运行时开销。

3. 应用层缓存

  • 在应用代码中实现缓存,而不是完全依赖 Redis。
    • 例如:将热点数据缓存在应用进程内存中(如 Java 的 ConcurrentHashMap、Python 的 dict)。
    • 优点:无网络开销,更快。
    • 缺点:重启后丢失,需配合 Redis 做二级缓存。

四、架构建议:分离部署(强烈推荐)

如果可能,最彻底的解决方案是将 MySQL 和 Redis 分开部署。

方案 说明 成本
方案 A:同机部署(当前) 1核1G 跑两个服务,风险高,需精细调优 最低
方案 B:MySQL 独立服务器 购买一台 2核2G 的 MySQL 专用服务器,本服务器只跑 App + Redis 中等
方案 C:云数据库 RDS 使用阿里云/腾讯云 RDS(MySQL),本服务器只跑 App + Redis 较高(但有优惠)

💡 为什么推荐分离?
MySQL 是 CPU 和 IO 密集型,Redis 是内存密集型。两者争抢资源会导致“互相拖累”。即使多花几十元/月,稳定性也会大幅提升。


五、监控与告警

由于资源紧张,必须实时监控:

  1. 安装 htop 或 glances:实时查看 CPU、内存、Swap 使用情况。
  2. 设置预警:
    • 当内存使用率 > 85% 时告警。
    • 当 Swap 使用 > 0 时立即告警(说明已触发交换,性能已受损)。
  3. 定期清理:
    • 清理 /var/log/mysql/ 下的二进制日志(binlog)。
    • 定期执行 OPTIMIZE TABLE 重建索引(低频操作)。

✅ 总结:最小可行配置清单

组件 关键配置
OS 禁用 Swap (swappiness=0)
MySQL max_connections=20, innodb_buffer_pool_size=256M
Redis maxmemory=256mb, maxmemory-policy=allkeys-lru
App 使用连接池,避免短连接;应用内缓存热点数据
监控 监控内存使用率,设置 85% 告警

通过以上优化,1核1G 服务器可以稳定支撑日均 PV < 10万 的小型项目。如果流量增长,优先考虑升级 MySQL 到独立服务器。

未经允许不得转载:云知识CLOUD » 小型项目用1核1G服务器部署MySQL和Redis,如何优化避免性能瓶颈?