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

在 1 核 1G 的极限资源下部署 MySQL + Redis,核心策略是“做减法”:减少服务数量、降低并发需求、严格限制内存占用,并充分利用操作系统层面的优化。以下是针对该场景的具体优化方案:

1. 操作系统层面优化(基础)

在应用层之前,先确保系统本身不浪费资源。

  • 开启 Swap 分区:物理内存仅 1G,极易发生 OOM(内存溢出)。建议创建至少 2G 的 Swap 文件,防止进程因内存不足被系统直接杀死。
    # 示例:创建 2G swap
    dd if=/dev/zero of=/swapfile bs=1M count=2048
    chmod 600 /swapfile
    mkswap /swapfile
    swapon /swapfile
  • 关闭不必要的服务:移除 Docker、监控X_X(如 Prometheus Node Exporter)、日志收集等后台服务,只保留 Nginx/Apache、MySQL、Redis 和 SSH。
  • 调整内核参数:
    • vm.swappiness:调低到 10,减少主动交换内存的频率。
    • net.core.somaxconn:适当调大连接队列,避免高并发时丢包。

2. MySQL 深度裁剪配置 (my.cnf)

1G 内存中,MySQL 默认配置会瞬间吃光内存。必须手动限制其最大内存占用(建议控制在 300MB – 400MB 以内),将剩余内存留给 OS 缓存和 Redis。

[mysqld]
# 基础设置
port = 3306
basedir = /usr/local/mysql
datadir = /var/lib/mysql
socket = /tmp/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid

# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

# --- 关键内存优化 (核心) ---
innodb_buffer_pool_size = 256M      # 限制缓冲池,预留空间给 OS 和其他进程
max_connections = 50                # 小型项目通常不需要太多连接,限制并发
thread_cache_size = 8               # 减少线程创建开销
query_cache_size = 0                # 禁用查询缓存(MySQL 8.0+ 已移除,旧版本建议禁用,因为单核竞争严重)
tmp_table_size = 16M                # 临时表大小限制
max_heap_table_size = 16M

# --- 性能与稳定性 ---
innodb_log_file_size = 64M          # 减小日志文件大小,加快恢复速度
innodb_flush_method = O_DIRECT      # 绕过 OS 缓存,避免双重缓存导致内存浪费
log_bin = /var/log/mysql/mysql-bin  # 开启主从复制日志(若无需备份可关闭以省 IO)
skip-name-resolve                   # 禁止 DNS 反向解析,提速连接建立

# --- 单核优化 ---
innodb_thread_concurrency = 1       # 强制 InnoDB 线程并发度为 1,适配单核 CPU
innodb_read_io_threads = 1
innodb_write_io_threads = 1

额外建议:

  • 使用 MyISAM 引擎仅用于极小的、读多写少的静态数据表(如字典表),但需注意其不支持事务。
  • 如果可能,将历史数据归档或迁移到冷存储,保持在线库体积最小化。

3. Redis 极致精简配置 (redis.conf)

Redis 依赖内存运行,1G 内存下需严格控制最大内存和淘汰策略。

# 基础设置
bind 127.0.0.1
protected-mode yes
port 6379
daemonize no
pidfile /var/run/redis/redis_6379.pid

# --- 关键内存优化 ---
maxmemory 256mb                     # 严格限制 Redis 最大内存,留出空间给 OS 和 MySQL
maxmemory-policy allkeys-lru        # 当内存满时,优先淘汰最近最少使用的键(适合缓存场景)
# 或者 allkeys-random / volatile-lru (根据业务特性选择)

# --- 持久化优化 (IO 敏感) ---
appendonly yes                      # 开启 AOF,保证数据不丢失
appendfsync everysec                # 每秒同步一次,平衡性能和安全性(比 always 快得多)
# 关闭 RDB 快照,避免在内存紧张时触发 fork 子进程导致卡顿
save ""                             # 禁用 RDB

# --- 其他 ---
tcp-backlog 512
timeout 300
tcp-keepalive 300

4. 架构与应用层优化

硬件无法升级时,软件架构必须配合。

  • 读写分离与缓存策略:
    • 尽量让所有热点数据命中 Redis。
    • 对于非实时性要求高的查询,允许少量延迟。
  • SQL 优化:
    • 杜绝 SELECT *,只查必要字段。
    • 确保所有查询字段都有索引,特别是 WHERE, ORDER BY, GROUP BY 涉及的字段。
    • 避免在大表上进行全表扫描。
  • 应用侧限流:
    • 在代码层(如 Spring Boot 或 Go)增加简单的限流逻辑,防止突发流量打垮数据库。
    • 使用连接池,并设置合理的 max-active 和 max-wait。
  • 日志管理:
    • 关闭 MySQL 和 Redis 的详细慢查询日志(Slow Query Log),除非正在调试。
    • 应用日志采用异步写入或滚动切割,避免磁盘 IO 阻塞。

5. 监控与运维策略

  • 轻量级监控:不要安装重型监控 Agent。使用简单的 Shell 脚本或 top/free 命令定期输出关键指标(CPU 使用率、内存剩余量、Swap 使用量)。
  • 定期清理:编写定时任务清理过期日志、临时文件和 Redis 中的脏数据。
  • 备份策略:由于磁盘 I/O 敏感,备份时间应选在凌晨低峰期,且使用 mysqldump --single-transaction 减少锁表时间。

总结

在 1 核 1G 环境下,“够用即可”是最高原则。

  1. 内存分配:MySQL (~300M) + Redis (~256M) + OS/Buffer (~400M) + Swap (2G)。
  2. 核心动作:限制连接数、禁用冗余功能(如查询缓存、RDB)、强制单线程并发模型。
  3. 预期管理:这种配置仅适合日 PV 几千到几万的小工具或个人博客,一旦并发超过 50 QPS,瓶颈必然出现,此时应考虑升级服务器或引入云数据库托管服务。
未经允许不得转载:云知道CLOUD » 小型项目用1核1G服务器部署MySQL和Redis,如何优化避免性能瓶颈?