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

1核1G(1 vCPU, 1 GB RAM)配置用于生产环境确实非常极限,尤其是同时运行 MySQL 和 Redis 两个内存密集型服务。在这种资源受限的情况下,核心策略不是“提升性能”,而是“极致裁剪”和“规避并发”。

以下是针对该配置的实战优化方案,按优先级排序:

一、 操作系统与内核层优化

  1. 关闭不必要的服务

    • 最小化安装 Linux 发行版(如 CentOS Stream/AlmaLinux 或 Ubuntu Minimal)。
    • 禁用 firewalld/ufw 以外的所有非必要守护进程(如 auditd, smartmontools 等),释放 CPU 和内存开销。
    • 使用 systemd-analyze blame 检查启动项,确保无冗余进程。
  2. 调整 Swap 分区(关键)

    • 1GB 内存极易 OOM(Out of Memory)。必须设置 Swap,但需控制其使用倾向。
    • 建议设置 1~2GB Swap 文件(非分区,便于管理)。
    • 修改 /etc/sysctl.conf:
      vm.swappiness=10  # 尽量不使用 Swap,仅在内存极度不足时启用
      vm.vfs_cache_pressure=50 # 保持目录和 inode 缓存,减少磁盘 IO
  3. 文件系统选择

    • 使用 ext4 而非 xfs 或 btrfs,在低配服务器上 ext4 的元数据操作开销更小。
    • 挂载选项添加 noatime:mount -o remount,noatime /,避免每次读取文件都更新访问时间戳,减少磁盘写入。

二、 MySQL 极致调优(MyISAM 或轻量 InnoDB)

MySQL 是此配置下的最大瓶颈。默认配置会占用大量内存。

  1. 存储引擎选择

    • 强烈建议:如果业务允许,使用 MyISAM 引擎。它不锁表行,内存占用极低,适合读多写少、无复杂事务的小型项目。
    • 若必须用 InnoDB,则需严格限制缓冲池。
  2. my.cnf 关键参数

    [mysqld]
    # 基础设置
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    
    # 内存控制(核心!)
    innodb_buffer_pool_size=128M  # 最多分配 128MB,留出空间给 OS 和其他进程
    max_connections=50            # 小型项目无需高并发连接数
    
    # 日志优化
    log_error_verbosity=2         # 降低错误日志详细程度
    slow_query_log=ON
    long_query_time=2             # 只记录慢于2秒的查询,避免日志风暴
    
    # 临时表处理
    tmp_table_size=16M
    max_heap_table_size=16M
    
    # 禁用不必要的功能
    skip-name-resolve             # 跳过 DNS 解析,加快连接建立
    local-infile=0                # 禁用 LOAD DATA LOCAL INFILE,提升安全并略减开销
  3. SQL 编写规范

    • 禁止全表扫描:所有查询必须有索引覆盖。
    • 避免大事务:1核 CPU 无法并行处理复杂事务,尽量拆分为小批量操作。
    • 字段精简:VARCHAR 长度设合理上限,避免使用 TEXT/BLOB 类型(除非必要),它们会触发临时表创建。

三、 Redis 极致调优

Redis 是单线程模型,1核 CPU 是其天然上限。重点在于防止阻塞和内存溢出。

  1. redis.conf 关键参数

    # 绑定本地地址,禁止网络直连(通过 SSH 隧道或应用内联调用)
    bind 127.0.0.1
    
    # 保护模式
    protected-mode yes
    
    # 内存限制(至关重要!)
    maxmemory 256mb           # 预留至少 300-400MB 给 MySQL 和 OS
    maxmemory-policy allkeys-lru  # 当内存满时,淘汰最少使用的键
    
    # 持久化策略(牺牲部分持久性换取性能)
    save ""                   # 关闭 RDB 快照,避免 fork 子进程导致 CPU 卡顿
    appendonly no             # 关闭 AOF,避免频繁磁盘 IO
    # 注意:这意味着重启后数据丢失。适用于缓存场景。
    # 若需持久化,可改为每秒一次 AOF,并接受性能损耗:
    # appendonly yes
    # appendfsync everysec
    
    # 客户端输出缓冲区限制
    client-output-buffer-limit normal 0 0 0
  2. 数据结构优化

    • 优先使用 Hash 而非多个 String Key,减少 Key 数量,节省内存元数据开销。
    • 避免存储大 Value(>1KB),否则会影响序列化/反序列化速度。

四、 架构与应用层优化(最关键)

在 1C1G 上,应用层优化比数据库调优更重要。

  1. 引入本地缓存(Local Cache)

    • 在 Java/Go/Python 应用中集成 Caffeine (Java) 或 LRUCache (其他语言)。
    • 将热点数据缓存在 JVM 堆内或进程内存中,减少对 Redis 的访问频率。
    • 例如:首页商品列表、用户基本信息等高频读取数据,设置 TTL 为 5~30 秒。
  2. 读写分离假象 → 异步化

    • 所有写操作(如订单创建、日志记录)不要同步等待 MySQL 返回结果。
    • 使用消息队列(如 RabbitMQ 轻量级部署,或直接异步线程池)将写请求解耦。
    • 后台线程批量插入 MySQL,避免前端请求长时间等待 DB 响应。
  3. 静态资源分离

    • Nginx 直接提供静态文件(CSS/JS/图片),不经过应用服务器。
    • 考虑将静态资源上传至 OSS(对象存储),减轻服务器带宽和存储压力。
  4. Nginx 反向X_X与压缩

    • 开启 Gzip 压缩,减少传输体积。
    • 配置 proxy_cache,对 API 响应进行短期缓存(如 10 秒),大幅降低后端 MySQL/Redis 压力。

五、 监控与预警

由于资源紧张,任何异常都会迅速放大。

  1. 安装轻量级监控

    • 使用 htop 实时观察 CPU 和内存。
    • 部署 prometheus + node_exporter + grafana(可选,若资源紧张可仅保留 alertmanager 报警)。
    • 或使用阿里云/腾讯云自带的云监控 Agent(通常更轻量且免费)。
  2. 关键指标阈值

    • CPU 使用率持续 > 80%:考虑代码优化或扩容。
    • 内存使用率 > 90%:立即触发告警,检查是否有内存泄漏。
    • Swap 使用量 > 0:说明物理内存已耗尽,系统开始剧烈抖动,需紧急干预。

六、 终极建议:迁移路径

如果上述优化后仍无法满足业务需求,说明 1C1G 已触及硬件天花板。此时应考虑以下低成本方案:

  1. 垂直拆分:

    • MySQL 和 Redis 分别部署在不同实例上(即使是最小的 1C1G 实例,总成本约 ¥50~¥100/月/台)。
    • 这样每个服务独占 1GB 内存,性能提升显著。
  2. 使用云数据库托管服务:

    • 阿里云 RDS MySQL 基础版、腾讯云 CDB 入门版等。
    • 虽然单价稍高,但免运维、自动备份、高可用保障,长期看更稳定可靠。
  3. 容器化隔离:

    • 使用 Docker Compose 部署,通过 deploy.resources.limits 限制每个容器的内存上限,防止某个服务拖垮整个系统。

总结:1核1G 部署 MySQL+Redis 的核心是 “少用”、“快进快出”。

  • MySQL:限内存、禁大事务、用 MyISAM 或轻量 InnoDB。
  • Redis:限内存、关持久化、用 LRU 淘汰。
  • 应用层:本地缓存 + 异步写入 + Nginx 缓存。

若业务增长,请立即考虑拆分实例或使用云托管数据库,这是最经济且稳定的解决方案。

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