MySQL和Redis共用同一台Linux服务器时,磁盘IO和内存如何优化配置?

当 MySQL 和 Redis 共存于同一台 Linux 服务器时,需谨慎协调资源(尤其是内存和磁盘 I/O),避免相互争抢导致性能劣化。以下是系统性、可落地的优化配置建议,兼顾稳定性与性能:


✅ 一、核心原则(先决条件)

  1. 明确角色分工
    • MySQL:持久化、复杂查询、事务保障 → 依赖磁盘 I/O + 内存(Buffer Pool)
    • Redis:纯内存缓存/高速数据结构 → 绝对不依赖磁盘(除非启用 RDB/AOF,且应严格管控)
  2. 拒绝“内存全给 Redis”或“MySQL 独占磁盘”等粗放策略
  3. 监控先行:部署 htop, iotop, vmstat 1, mysqld_exporter + redis_exporter + Prometheus/Grafana

✅ 二、内存优化(最关键!)

组件 推荐配置 说明
Redis maxmemory = 总内存 × 40%~55%(预留足够 OS 缓存 + MySQL)
maxmemory-policy = allkeys-lruvolatile-lru(避免 OOM kill)
❗禁止 noeviction(易触发 OOM Killer 杀 Redis)
✅ 设置 maxmemory-samples 5 平衡精度与开销
⚠️ 若用 Redis 6.0+,开启 lazyfree-lazy-eviction yes 降低淘汰延迟
MySQL innodb_buffer_pool_size = 总内存 × 35%~50%(必须 ≤ Redis maxmemory + Buffer Pool ≤ 总内存 × 85%)
key_buffer_size = 16M(MyISAM 已淘汰,仅兼容)
✅ 必须小于物理内存!超配将触发频繁 swap → 性能雪崩
✅ 检查 Innodb_buffer_pool_wait_free ≈ 0(否则 Buffer Pool 不足)
OS 层 vm.swappiness = 1(非 0!保留紧急 swap 防 OOM)
vm.vfs_cache_pressure = 50(降低 inode/dentry 缓存回收压力)
❌ 禁止 swappiness=0(OOM Killer 更激进)
echo 'vm.swappiness=1' >> /etc/sysctl.conf && sysctl -p

🔍 内存分配示例(64GB 内存服务器)

  • Redis maxmemory: 28GB(43%)
  • MySQL innodb_buffer_pool_size: 24GB(37.5%)
  • OS + 其他进程:≥ 12GB(含 page cache、网络缓冲、进程栈等)
    总占用 ≤ 64GB × 90% = 57.6GB,留 6.4GB 安全余量

✅ 三、磁盘 I/O 优化(减少争抢)

场景 优化措施 命令/配置示例
磁盘分离(强烈推荐) MySQL 数据目录 & Redo Log 放 SSD
Redis RDB/AOF(如启用)放另一块 SSD 或 NVMe
OS 系统盘独立
bash # 查看磁盘拓扑 lsblk -f; ls -l /sys/block/*/queue/rotational # 0=SSD, 1=HDD
I/O 调度器 SSD/NVMe:none(禁用调度器)
HDD:deadline(MySQL 随机读多)
bash echo 'none' > /sys/block/nvme0n1/queue/scheduler # 永久生效见 /etc/default/grub
Redis 持久化克制 生产环境建议:仅开启 RDB(关闭 AOF)
→ RDB 是 fork + 全量快照,I/O 可控
❌ 避免 AOF everysec(每秒刷盘,与 MySQL redo log 争 I/O)
conf # redis.conf save 300 10 # 5min内10次变更才save(降低频率) stop-writes-on-bgsave-error yes # 失败时报警而非静默 rdbcompression yes # 压缩减小写入量
MySQL I/O 优化 innodb_io_capacity = SSD: 2000~4000, NVMe: 8000+
innodb_io_capacity_max = 2× capacity
innodb_flush_method = O_DIRECT(绕过 OS cache,避免双缓存)
ini # my.cnf [mysqld] innodb_io_capacity=3000 innodb_io_capacity_max=6000 innodb_flush_method=O_DIRECT
文件系统 XFS(推荐):支持大文件、延迟分配、noatime
挂载选项:noatime,nodiratime,logbufs=8,logbsize=256k
bash # /etc/fstab /dev/nvme0n1p1 /var/lib/mysql xfs defaults,noatime,nodiratime,logbufs=8,logbsize=256k 0 0

✅ 四、进程级协同优化

项目 配置
CPU 亲和性(可选) 将 MySQL 分配到 CPU0-3,Redis 到 CPU4-7(taskset),避免上下文切换争抢 taskset -c 4-7 redis-server /etc/redis.conf
OOM Killer 优先级 降低 Redis 的 oom_score_adj(更不易被杀),提高 MySQL(关键业务) bash echo -500 > /proc/$(pgrep redis-server)/oom_score_adj echo -800 > /proc/$(pgrep mysqld)/oom_score_adj # 永久化需 systemd drop-in
日志分离 MySQL error log / slow log → SSD
Redis log → 独立小容量 SSD 或 /dev/shm(内存盘)
logfile /dev/shm/redis.log(需注意重启丢失)

✅ 五、必须规避的高危配置

❌ 危险操作 ✅ 正确做法
Redis maxmemory 设为 0(无限制) 显式设置合理上限 + LRU 策略
MySQL innodb_buffer_pool_size > 物理内存 必须 ≤ 总内存 × 50%(留足 Redis + OS)
Redis 启用 appendonly yes + appendfsync always 改为 appendfsync no(依赖 OS 刷盘)或 everysec(若必须 AOF)
使用 HDD 承载 MySQL + Redis 持久化 至少 MySQL 必须 SSD;Redis RDB/AOF 也建议 SSD
关闭 swap(swapoff -a 保留 small swap(如 2GB),设 swappiness=1

✅ 六、验证与监控清单

  1. 内存健康
    free -h                    # total, used, available(关注 available ≥ 2GB)
    cat /proc/meminfo | grep -E "MemAvailable|Buffers|Cached"
  2. I/O 压力
    iotop -oP                  # 查看 top I/O 进程(MySQL/Redis 是否霸占)
    iostat -x 1 3              # %util < 70%, await < 10ms(SSD)
  3. Redis 健康
    redis-cli info memory | grep -E "used_memory|maxmemory|mem_allocator"
    redis-cli info persistence | grep -E "rdb_bgsave_in_progress|aof_rewrite_in_progress"
  4. MySQL 健康
    SHOW ENGINE INNODB STATUSG  -- 查看 BUFFER POOL HIT RATE > 99%
    SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_%';

💡 终极建议

  • 短期:按上述内存比例 + 关闭 AOF + O_DIRECT + swappiness=1 快速见效
  • 中期:拆分磁盘(MySQL/Redis/RDB 日志各用独立 SSD)
  • 长期:业务增长后务必物理分离 —— Redis 用内存服务器,MySQL 用高 I/O 服务器,这是云厂商的标准架构(如阿里云 PolarDB + ApsaraDB for Redis)

如需具体配置模板(my.cnf / redis.conf / sysctl.conf),我可为你生成完整可部署版本。欢迎补充你的服务器规格(CPU/内存/磁盘类型/数量)和业务场景(读写比、数据量级),我来定制化调优。

是否需要我为你生成一份 一键检查脚本(自动检测冲突配置并给出修复建议)?

未经允许不得转载:CLOUD技术博 » MySQL和Redis共用同一台Linux服务器时,磁盘IO和内存如何优化配置?