Develop

Redis 缓存策略与高可用集群搭建:从单机到 Sentinel + Cluster

✎ -- 字 🕐 -- 分钟
字号
Redis 缓存策略与高可用架构

三大缓存问题

在高并发场景下,Redis 面临三大经典问题:缓存穿透、缓存击穿、缓存雪崩。理解并正确处理它们是后端开发的必备技能。

1. 缓存穿透

问题:查询不存在的数据,请求直接穿透缓存打到数据库。

解决方案

  • 布隆过滤器:预先标记所有可能的 key
  • 缓存空值:对不存在的 key 缓存空标记
// Node.js 示例:缓存空值
async function getProduct(id) {
    const cacheKey = `product:${id}`;
    let data = await redis.get(cacheKey);
    
    if (data === '__NULL__') return null;
    if (data) return JSON.parse(data);
    
    const product = await db.findProduct(id);
    if (!product) {
        await redis.setex(cacheKey, 60, '__NULL__');
        return null;
    }
    
    await redis.setex(cacheKey, 3600, JSON.stringify(product));
    return product;
}

2. 缓存击穿

问题:热点 key 过期瞬间,大量请求同时打到数据库。

解决方案:互斥锁 / 逻辑过期

async function getWithMutex(key) {
    let data = await redis.get(key);
    if (data) return JSON.parse(data);
    
    const lockKey = `${key}:lock`;
    const locked = await redis.set(lockKey, '1', 'NX', 'EX', 10);
    
    if (locked) {
        const fresh = await db.query(key);
        await redis.setex(key, 3600, JSON.stringify(fresh));
        await redis.del(lockKey);
        return fresh;
    }
    
    // 等待 50ms 后重试
    await sleep(50);
    return getWithMutex(key);
}

3. 缓存雪崩

问题:大量 key 同时过期,或 Redis 服务宕机,导致请求全部打到数据库。

解决方案

  • TTL 加随机值:setex(key, 3600 + Math.random() * 600, value)
  • 多级缓存:本地缓存 + Redis + DB
  • 限流降级:Sentinel 限流 + Hystrix 断路器

4. Sentinel 哨兵模式

# sentinel.conf
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000

5. Cluster 集群模式

# 启动 6 个节点(3 主 3 从)
redis-server redis7000.conf --cluster-enabled yes
redis-server redis7001.conf --cluster-enabled yes
# ... 共 6 个节点

# 创建集群
redis-cli --cluster create \
  127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
  127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
  --cluster-replicas 1

总结

理解缓存穿透、击穿、雪崩的成因与解决方案,掌握 Sentinel 和 Cluster 的部署,就能构建稳定可靠的 Redis 缓存体系。