走啊走
加油

单台云服务器上同时部署MySQL和Redis的最佳实践是什么?

服务器价格表

在单台云服务器上同时部署 MySQL 和 Redis 是常见但需谨慎的操作(尤其在生产环境)。虽然技术上可行,但不推荐用于中高负载或关键业务场景。以下是兼顾稳定性、性能与可维护性的最佳实践指南,按优先级分层说明:


✅ 一、前提判断:是否真的需要共存?

场景 建议
开发/测试/低流量个人项目(QPS < 100) 可接受,但需严格资源隔离
生产环境、日活 > 1万、有事务一致性要求 ❌ 强烈建议分离:MySQL + Redis 分布在不同实例(至少不同物理机/虚拟机)
成本敏感但有基本SLA要求(如99.5%可用性) 可共存,但必须满足下述所有硬性约束

💡 理由:MySQL(重IO/内存/CPU)与Redis(纯内存/高CPU争用)存在资源冲突,易引发雪崩(如Redis bgsave导致IO阻塞MySQL,或OOM Killer误杀进程)。


✅ 二、强制性基础配置(共存底线)

1. 资源隔离与配额

  • CPU
    • 使用 cgroups(systemd slice)或 cpuset 限制:
      # 示例:为MySQL分配2核,Redis分配1核(预留1核给系统)
      sudo systemctl set-property mysqld CPUQuota=200%
      sudo systemctl set-property redis-server CPUQuota=100%
  • 内存
    • MySQL:innodb_buffer_pool_size ≤ 总内存 × 50%(最大不超过70%,需预留系统+Redis空间)
    • Redis:maxmemory 必须严格设置(严禁使用默认无限制!)
      # redis.conf
      maxmemory 2gb
      maxmemory-policy allkeys-lru  # 避免evicting keys with expire
    • 系统预留:至少 2GB 给 OS + 其他进程(SSH、监控等)

2. 磁盘IO隔离

  • MySQL数据目录 & Redis RDB/AOF 文件 必须放在不同物理磁盘(或至少不同挂载点,避免IO竞争):
    # 推荐目录结构
    /data/mysql     # SSD专用分区
    /data/redis     # 另一SSD分区(或NVMe)
    /var/log        # 独立小容量盘(或tmpfs)
  • 禁用 Redis AOF(除非强持久化需求),改用 RDB + save 60 1000(降低写压力)
  • MySQL 调整 innodb_io_capacityinnodb_io_capacity_max 匹配磁盘性能

3. 网络与端口

  • 显式绑定内网地址(禁止0.0.0.0):
    # my.cnf
    bind-address = 127.0.0.1
    # redis.conf
    bind 127.0.0.1
    protected-mode yes
  • 使用非默认端口(降低扫描风险):
    • MySQL: 3307(而非3306)
    • Redis: 6380(而非6379)

✅ 三、关键安全加固

  • 用户隔离
    sudo adduser --shell /usr/sbin/nologin --disabled-password mysql
    sudo adduser --shell /usr/sbin/nologin --disabled-password redis
    chown -R mysql:mysql /data/mysql
    chown -R redis:redis /data/redis
  • 禁用危险命令(Redis):
    # redis.conf — 防止FLUSHDB/CONFIG/KEYS等
    rename-command FLUSHDB ""
    rename-command CONFIG ""
    rename-command KEYS ""
  • MySQL最小权限原则:应用连接账号仅授予 SELECT,INSERT,UPDATE,DELETE on specific DB,禁用 FILE, PROCESS, SUPER

✅ 四、监控与告警(不可省略!)

部署轻量级监控(推荐 Prometheus + Node Exporter + mysqld_exporter + redis_exporter): 指标 阈值告警 工具
Redis 内存使用率 > 85% redis_memory_used_bytes / redis_memory_max_bytes
MySQL 连接数 > 80% of max_connections mysql_global_status_threads_connected
磁盘IO等待 iowait > 20%(持续5分钟) Node Exporter
OOM Killer 日志 /var/log/messages 中出现 Killed process Filebeat + Alert

📌 必须配置:当 Redis 内存达90% 或 MySQL IO wait > 30% 时自动触发短信/钉钉告警


✅ 五、备份与故障恢复

  • 备份策略分离
    • MySQL:每日全量(mysqldumpxtrabackup)+ binlog 实时归档
    • Redis:每小时 RDB 快照(save 3600 1)+ 定期上传至对象存储(OSS/S3)
  • 恢复演练:每月执行一次跨服务恢复测试(例:模拟Redis宕机后,验证MySQL事务是否正常)

⚠️ 六、明确的淘汰路径(重要!)

当出现以下任一情况,立即迁移Redis到独立实例

  • Redis used_memory_rss > 3GB(且持续增长)
  • MySQL Innodb_buffer_pool_wait_free > 0(表示内存压力)
  • 云服务器平均负载(uptime)持续 > CPU核数 × 0.7
  • 应用出现“偶发超时”,且日志显示 Redis timeoutMySQL slow query 同时发生

✅ 附:推荐最小硬件配置(共存底线)

项目 最低要求 推荐配置
CPU 4核 8核(Intel Xeon / AMD EPYC)
内存 16GB 32GB(MySQL 12GB + Redis 8GB + OS 4GB)
磁盘 2×500GB NVMe(分离分区) 2×1TB NVMe(RAID 1 或独立挂载)
OS Ubuntu 22.04 LTS / CentOS Stream 9 同左,启用 zram 压缩交换区

🔚 总结:一句话原则

“可以共存,但必须像对待两个互不信任的邻居一样——划清地界(资源)、装好门锁(安全)、装上监控摄像头(可观测性),并随时准备给他们各自买房(水平拆分)。”

如需具体配置文件模板(my.cnf/redis.conf)、一键部署脚本(Ansible)或监控面板(Grafana JSON),我可立即为您生成。欢迎补充您的云平台(阿里云/腾讯云/AWS)和当前负载规模,提供定制化方案。