评估 Redis 是否要扩容:什么时候该加内存加机器

评估 Redis 是否要扩容:什么时候该加内存加机器

核心问题:什么时候该扩容

Redis 作为内存数据库,扩容是运维中最常见的操作之一。太早扩容浪费资源,太晚扩容影响业务。我们需要一个科学的判断标准。

扩容的六个关键信号

信号一:内存使用率超过 80%

> INFO MEMORY
# Memory
used_memory:8589934592        # 8GB
maxmemory:10737418240         # 10GB(上限)

使用率 = 8GB / 10GB = 80%。长期超过 80% 就应该考虑扩容

为什么是 80%?

10GB × 80% = 8GB 使用量
10GB × 20% = 2GB 剩余空间

20% 的余量用于:
– 瞬时突发写入
– RDB/AOF rewrite 期间的额外内存(写入时复制)
– 内存碎片(jemalloc 的 1.02-1.10 倍实际分配)
– 客户端输出缓冲区

信号二:频繁触发淘汰策略

> INFO STATS
evicted_keys:5000  # 正在淘汰 key

evicted_keys 持续增长,说明内存不够用了,Redis 被迫删除一些 key。

def check_eviction_severity(r):
    """检查淘汰严重程度"""
    stats1 = r.info('stats')
    time.sleep(60)
    stats2 = r.info('stats')

    evicted_per_sec = (stats2['evicted_keys'] - stats1['evicted_keys']) / 60

    if evicted_per_sec == 0:
        return "安全"
    elif evicted_per_sec < 10:
        return "轻度淘汰"
    elif evicted_per_sec < 100:
        return "中度淘汰,建议观察"
    else:
        return "严重淘汰,立即扩容!"

信号三:QPS 达到单机上限

# 当 CPU 使用率持续 80%+ 且 QPS 无法再提升时
redis-cli INFO STATS | grep instantaneous_ops_per_sec

# 单机极限测试(根据服务器性能)
# 4 核 8GB: 约 8-12 万 QPS
# 8 核 16GB: 约 12-18 万 QPS

如果 CPU 已经很满但 QPS 无法满足业务需求,说明需要横向扩容(加实例)。

信号四:延迟显著增加

# 正常情况下
redis-cli --latency -h localhost -p 6379
min: 0, max: 2, avg: 0.19

# 需要警惕的情况
# avg > 1ms 且持续上升,同时 CPU 或内存使用率高

信号五:持久化时间变长

redis-cli INFO PERSISTENCE
rdb_last_bgsave_time_sec:15    # 上次 BGSAVE 耗时
aof_last_rewrite_time_sec:20   # 上次 AOF 重写耗时

这些时间随数据集增大而线性增长。如果 RDB 备份时间已经接近备份周期,说明数据太大了。

信号六:主从同步压力增大

redis-cli INFO REPLICATION
master_repl_offset:5000000000
slave_repl_offset:4950000000  # 差距 50M

如果从库同步延迟持续增大,且不是因为从库性能问题,说明主库的写入量太大,需要扩容了。

决策矩阵

def should_scale_up(r):
    """综合判断是否需要扩容"""
    info = {
        'memory': r.info('memory'),
        'stats': r.info('stats'),
        'persistence': r.info('persistence'),
        'replication': r.info('replication')
    }

    reasons = []
    score = 0

    # 1. 内存使用率
    used = info['memory']['used_memory']
    maxmem = info['memory']['maxmemory']
    if maxmem > 0:
        ratio = used / maxmem
        if ratio > 0.9:
            reasons.append(f"内存使用率 {ratio:.0%} > 90% (紧急)")
            score += 5
        elif ratio > 0.8:
            reasons.append(f"内存使用率 {ratio:.0%} > 80% (预警)")
            score += 3

    # 2. 淘汰 key
    evicted = info['stats']['evicted_keys']
    if evicted > 1000:
        reasons.append(f"已淘汰 {evicted} 个 key")
        score += 5

    # 3. 残片率
    frag = info['memory']['mem_fragmentation_ratio']
    if frag > 2.0:
        reasons.append(f"碎片率 {frag:.2f}(过高)")
        score += 2

    # 4. 持久化时间
    bgsave_time = info['persistence'].get('rdb_last_bgsave_time_sec', 0)
    if bgsave_time > 60:
        reasons.append(f"BGSAVE 耗时 {bgsave_time}s")
        score += 2

    # 5. 峰值对比
    peak = info['memory']['used_memory_peak']
    if peak > maxmem * 0.9:
        reasons.append(f"内存峰值 {peak/1024/1024:.0f}MB 接近上限")
        score += 3

    decision = "需要紧急扩容" if score >= 8 else "建议扩容" if score >= 5 else "暂不需要扩容"

    return {
        'score': score,
        'decision': decision,
        'reasons': reasons
    }

扩容方案

方案一:垂直扩容(升级硬件)

# 简单粗暴:加内存
# 旧:4GB → 新:8GB/16GB/32GB

# 需要注意
# 1. 云服务只需调整规格
# 2. 自建服务器需要关机加内存条
# 3. 大内存重启后 RDB 恢复更慢
# 4. fork 耗时随内存增大而增加

方案二:水平扩容(Redis Cluster)

# 从单机扩容到 3 节点 Cluster
# 每个节点仍用 8GB,但总量变成 24GB

# 新增节点
redis-cli --cluster add-node new-node:6379 existing-node:6379

# 重新分配 slot
redis-cli --cluster rebalance existing-node:6379

# 监控数据迁移
redis-cli --cluster check existing-node:6379

方案三:读写分离

# 如果主要是读压力大(QPS 高但内存不是瓶颈)
# 增加从库
SLAVEOF master_host master_port

# 配置客户端使用从库读
readonly = True  # 只读从库

扩容决策检查清单

## 扩容前的自查清单

### 先确认不是代码问题
□ 有没有 BigKey 可以拆分?
□ 有没有过期时间可以设置?
□ 数据结构是否可以优化(String → Hash?)
□ 是否有内存泄漏的代码?

### 再确认真的需要扩容
□ 内存使用率 > 80% 持续超过 1 周?
□ 有 key 被淘汰(evicted_keys > 0)?
□ QPS 接近单机上限?
□ 延迟显著增加?
□ 主从同步延迟增大?

### 选择扩容方案
□ 垂直扩容(升级配置)短期应急
□ 水平扩容(加实例)长期方案
□ 读写分离 读多写少场景

面试要点

  • 核心判断标准:内存使用率 > 80% + evicted_keys > 0
  • 扩容的两种方式:垂直(升级单机)和水平(加实例)
  • 垂直扩容简单但有上限(单机内存上限)
  • 水平扩容是更推荐的方案(可线性扩展)
  • 扩容前先确认是否可以通过代码优化减少内存消耗
  • 峰值内存(used_memory_peak)也是重要参考指标
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容