奋斗
努力

MySQL和Redis共用2核4G内存服务器时如何优化资源占用?

云计算

在 2 核 4G 内存的服务器上同时运行 MySQL 和 Redis,资源竞争非常激烈。核心策略是严格限制两者的最大内存占用,并根据业务负载动态调整参数。以下是具体优化方案:


一、内存分配原则(总内存 4GB)

组件 建议最大内存 说明
MySQL 1.5~2 GB 预留操作系统 + 其他进程缓冲
Redis 1.0~1.5 GB 避免 OOM 导致服务崩溃
OS/其他 ≥0.5 GB 系统缓存、日志、监控等

⚠️ 关键:必须通过配置显式限制上限,否则默认行为可能导致 OOM Kill。


二、MySQL 优化配置(my.cnf)

[mysqld]
# 连接数控制(2 核 CPU 建议低并发)
max_connections = 50

# 内存核心参数(总和需 < 1.8GB)
innodb_buffer_pool_size = 1.2G      # InnoDB 缓存(占物理内存 60%)
key_buffer_size = 64M               # MyISAM 索引(若不用可设为 0)
sort_buffer_size = 2M               # 排序缓冲区(每个连接独立)
read_buffer_size = 2M               # 读缓冲区
read_rnd_buffer_size = 2M           # 随机读缓冲区
tmp_table_size = 32M                # 临时表内存上限
max_heap_table_size = 32M           # 同上

# 其他关键设置
thread_cache_size = 8               # 线程缓存
query_cache_type = 0                # 禁用查询缓存(高并发下反而降速)
log_bin = /var/log/mysql/mysql-bin.log
slow_query_log = 1
long_query_time = 2

注意事项

  • innodb_buffer_pool_size 是核心,优先保障它。
  • 所有 _buffer_size 参数都是每个连接独占,需结合 max_connections 计算总风险:
    总缓冲内存 ≈ (sort+read+read_rnd) × max_connections → 本例中约 (2+2+2)×50=300MB,安全。
  • 若使用 MyISAM 引擎,key_buffer_size 可适当调大,但现代应用多推荐 InnoDB。

三、Redis 优化配置(redis.conf)

# 内存限制(硬上限)
maxmemory 1.2gb
maxmemory-policy allkeys-lru        # 或 volatile-lru(根据数据过期策略选择)

# 持久化策略(减少 I/O 压力)
appendonly yes                      # AOF 开启(RDB 可能阻塞主线程)
appendfsync everysec                # 每秒刷盘(平衡性能与安全)
no-appendfsync-on-rewrite no        # 重写时不阻塞

# 网络与连接
bind 0.0.0.0
protected-mode yes
tcp-backlog 511
timeout 0
tcp-keepalive 300

# 禁用不必要的功能
save ""                             # 关闭 RDB 快照(AOF 已足够)
rdbcompression yes
rdbchecksum yes

关键点

  • maxmemory 必须严格小于物理内存剩余值(建议 1.2GB)。
  • 采用 allkeys-lru 策略自动淘汰旧数据,防止内存溢出。
  • 关闭 RDB 避免 fork() 子进程导致的瞬时内存峰值。

四、操作系统级优化

1. 交换空间(Swap)谨慎使用

# 查看当前 swap
free -h

# 若需创建(仅作为最后防线,频繁 swap 会拖垮性能)
dd if=/dev/zero of=/swapfile bs=1G count=1
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

# 调整 swappiness(降低 swap 倾向)
echo "vm.swappiness=10" >> /etc/sysctl.conf
sysctl -p

💡 建议:生产环境尽量不设 swap,依赖内存管理更可靠;测试环境可设小 swap(如 1GB)。

2. Cgroup 资源隔离(高级方案)

# 创建 cgroup 限制 MySQL 和 Redis 内存
mkdir /cgroup/memory/mysql
mkdir /cgroup/memory/redis
echo "mysql" > /cgroup/memory/mysql/cgroup.procs
echo "1.8G" > /cgroup/memory/mysql/memory.limit_in_bytes
echo "redis" > /cgroup/memory/redis/cgroup.procs
echo "1.2G" > /cgroup/memory/redis/memory.limit_in_bytes

适用场景:需要强制隔离,防止一方耗尽内存影响另一方。

3. 内核参数调优

# 增加文件描述符限制
echo "fs.file-max = 65535" >> /etc/sysctl.conf
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf

# 优化 TCP 参数
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 2048

五、监控与应急措施

  1. 实时监控工具

    # 安装 htop + redis-cli + mysqltuner
    apt install htop redis-tools mysqltuner-perl
    htop                    # 观察整体内存/CPU
    redis-cli info memory   # 检查 Redis 内存使用率
    mysqltuner              # 分析 MySQL 配置合理性
  2. 告警阈值

    • 内存使用率 > 85% → 触发告警
    • Swap 使用 > 10% → 立即介入
    • Redis used_memory_human 接近 maxmemory → 扩容或清理
  3. 应急预案

    • 准备一键重启脚本(按优先级:先停 Redis → 再停 MySQL)
    • 定期备份数据到外部存储,避免本地磁盘写满

六、替代方案建议

如果业务负载持续较高,考虑以下升级路径:

  1. 分离部署:将 Redis 迁移到独立小服务器(1 核 2G),释放 MySQL 资源。
  2. 云数据库:使用云厂商的 RDS + 云缓存服务(自动弹性伸缩)。
  3. 容器化隔离:用 Docker/K8s 为 MySQL 和 Redis 分配固定资源配额。

最终验证:压测后观察 dmesg | grep -i oom 是否出现 OOM Killer 日志,若有则需进一步收紧配置。

通过以上组合策略,可在 2 核 4G 环境下稳定支撑中小型业务的混合负载场景。

未经允许不得转载:云服务器 » MySQL和Redis共用2核4G内存服务器时如何优化资源占用?