速卖通素材
奋斗

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

服务器

在 MySQL 和 Redis 共用同一台 Linux 服务器时,资源竞争主要集中在 内存(RAM)和 磁盘 I/O。若配置不当,极易出现“争抢”现象:Redis 因内存不足触发 Swap 导致延迟飙升,或 MySQL 因 I/O 阻塞而查询变慢。

以下是针对内存和磁盘 IO 的系统级优化与配置策略:


一、核心原则:明确资源分配比例

在物理机资源有限的情况下,必须根据业务场景进行“切分”。

  • 内存分配:通常建议 MySQL : Redis = 60% : 40%50% : 50%
    • 如果 Redis 主要用于缓存热点数据且数据量可控,可给 Redis 更多内存。
    • 如果 MySQL 是主存储且涉及大量排序/临时表操作,需预留足够内存给 Buffer Pool。
  • I/O 优先级:Redis 对延迟极其敏感(毫秒级),MySQL 对吞吐量更敏感。应确保 Redis 的 I/O 不被 MySQL 的大批量写入阻塞。

二、内存优化配置 (RAM)

1. 操作系统层面

  • 关闭 Swap(关键):
    Redis 和 MySQL 都极度依赖物理内存。一旦触发 Swap,性能会下降几个数量级。

    # 临时关闭
    sudo swapoff -a
    # 永久关闭 (修改 /etc/fstab,注释掉 swap 行)
    echo "vm.swappiness = 1" | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p

    注:将 vm.swappiness 设为 1,表示仅在极端情况下才使用 Swap。

  • 透明大页 (Transparent Huge Pages, THP)
    对于 MySQL 和 Redis,THP 往往会导致抖动。建议禁用。

    # 检查状态
    cat /sys/kernel/mm/transparent_hugepage/enabled
    # 设置为 never
    echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
    echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

2. MySQL 配置 (my.cnf)

  • innodb_buffer_pool_size
    这是最重要的参数。建议设置为可用物理内存的 50%-70%(扣除 Redis 占用后)。

    [mysqld]
    innodb_buffer_pool_size = 8G  # 假设总内存 16G,Redis 占 4G,留 4G 给系统和其他进程
    innodb_log_file_size = 2G     # 适当调大,减少刷盘频率
    innodb_flush_log_at_trx_commit = 2 # 权衡安全与性能,若非X_X级可设为 2
  • 其他内存相关
    限制 sort_buffer_size, read_buffer_size 等会话级参数,避免并发高时内存爆炸。

3. Redis 配置 (redis.conf)

  • maxmemory
    必须显式设置,防止 Redis 吃光所有内存导致 OOM Killer 杀掉 MySQL。

    maxmemory 4gb                # 硬上限
    maxmemory-policy allkeys-lru # 当内存满时,淘汰策略(推荐 lru 或 volatile-lru)
  • 内存碎片率控制
    Redis 在高负载下可能产生碎片。

    activedefrag yes             # 开启主动碎片整理
    active-fraction 0.1          # 阈值

三、磁盘 I/O 优化配置

1. 文件系统与挂载选项

  • 文件系统选择
    推荐使用 XFS(默认)或 EXT4。避免使用 NFS 作为本地数据存储。
  • 挂载参数优化
    /etc/fstab 中调整挂载选项,减少元数据开销。

    # 示例:data 分区挂载
    /dev/sdb1  /data  xfs  noatime,nodiratime,logbufs=8  0 0
    • noatime/nodiratime:不更新访问时间,显著减少写 I/O。
    • logbufs=8:增加日志缓冲区(针对 XFS)。

2. I/O 调度器 (Scheduler)

根据硬盘类型选择调度算法:

  • SSD/NVMe:建议使用 nonemq-deadline(现代内核默认)。
  • 机械硬盘 (HDD):建议使用 deadlinebfq
    # 查看当前调度器
    cat /sys/block/sda/queue/scheduler
    # 修改为 deadline (以 sda 为例)
    echo deadline > /sys/block/sda/queue/scheduler

3. 隔离读写路径 (关键策略)

由于 MySQL 和 Redis 对 I/O 需求不同,尽量将数据文件分离到不同的物理磁盘或分区。

  • 方案 A:多磁盘
    • Disk 1 (NVMe/SSD): 专门用于 Redis RDB/AOF 快照及 MySQL 的 Binlog。
    • Disk 2 (HDD/大容量 SSD): 存放 MySQL 的 InnoDB Data File (ibdata1.ibd)。
  • 方案 B:单磁盘分区
    如果只有一块盘,利用 ionicecgroups 限制 MySQL 的 I/O 权重,优先保障 Redis。

4. cgroups v2 限流 (高级)

如果无法物理隔离磁盘,可使用 Linux Cgroups 限制 MySQL 的 I/O 带宽,防止其全速写入阻塞 Redis。

# 示例:限制 mysql 进程的写入带宽为 50MB/s
echo 50000000 > /sys/fs/cgroup/io/mysql/write_bps_max

(注意:具体命令取决于 cgroups 版本和内核版本)


四、监控与调优闭环

配置完成后,必须通过监控验证效果:

  1. 监控指标

    • 内存free -h 观察 Buffers/Cached,确保没有频繁 Swap。
    • I/O:使用 iostat -x 1 观察 %util(利用率)和 await(平均等待时间)。
      • await 持续超过 10ms (SSD) 或 50ms (HDD),说明存在瓶颈。
    • Redis:关注 used_memory_rssevicted_keys
    • MySQL:关注 Innodb_buffer_pool_read_requests vs Innodb_buffer_pool_reads(命中率应>99%)。
  2. 压测验证
    在低峰期模拟高负载(如 sysbench 跑 MySQL,redis-benchmark 跑 Redis),观察是否出现互相卡顿。

五、总结清单

维度 关键动作 推荐值/策略
Swap 彻底关闭 vm.swappiness = 1
THP 禁用 never
内存分配 静态切分 MySQL 60%, Redis 40% (根据业务调整)
Redis 内存上限 maxmemory 严格限制,开启 activedefrag
MySQL Buffer Pool innodb_buffer_pool_size = 可用内存的 50-70%
文件系统 挂载参数 noatime, nodiratime
I/O 调度 匹配硬件 SSD=none, HDD=deadline
隔离 物理/逻辑分离 优先分离磁盘;次选 Cgroups 限流

通过以上配置,可以在单台服务器上实现 MySQL 和 Redis 的稳定共存,最大程度减少资源争抢带来的性能抖动。

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