服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-08-17 简米科技 4,241 字 10 分钟阅读

Redis如何实现分布式缓存?分布式缓存策略有哪些?

导读分布式缓存策略的核心是结合业务场景选择缓存模式、淘汰算法和高可用方案,Redis凭借丰富的数据结构与集群能力成为主流实现,Redis缓存策略有哪些?核心机制与选型指南理解Redis缓存策略,本质上是回答“缓存什么、存多久、满了怎么办”这三个问题,业内常见的策略体系围绕缓存模式、淘汰算法和过期策略展开,每个维度都……

分布式缓存策略的核心是结合业务场景选择缓存模式、淘汰算法和高可用方案,Redis凭借丰富的数据结构与集群能力成为主流实现。

Redis缓存策略有哪些?核心机制与选型指南

理解Redis缓存策略,本质上是回答“缓存什么、存多久、满了怎么办”这三个问题,业内常见的策略体系围绕缓存模式、淘汰算法和过期策略展开,每个维度都直接影响系统性能与数据一致性。

缓存模式与业务匹配

  • Cache Aside(旁路缓存):最常用的模式,业务代码同时维护缓存和数据库,读时先查缓存,命中则返回;未命中则查数据库,回填缓存,写时更新数据库,随后删除缓存,这种模式适合读多写少、对一致性要求不高的场景,如商品详情页。
  • Read/Write Through(读写穿透):缓存层负责与数据库交互,应用只与缓存通信,读未命中时由缓存组件从数据库加载,写时由缓存同步写入数据库,该模式简化了业务代码,但只适合缓存层具备完整数据源能力的场景,如本地缓存库。
  • Write Behind(异步写回):写操作仅更新缓存,异步批量写入数据库,性能极高,但可能丢数据,适用于日志、点赞等弱一致性场景。

选择建议:互联网业务首选Cache Aside,因为其代码逻辑清晰,结合Redis的原子操作可避免并发写冲突,若需强一致性,可搭配分布式锁。

缓存淘汰策略详解

当内存写满时,Redis根据配置的maxmemory-policy决定淘汰哪些键,常见策略包括:

  • LRU(最近最少使用):淘汰最近最久未使用的键。allkeys-lru对所有键生效,volatile-lru仅对带过期时间的键生效,多数场景下推荐allkeys-lru,因为它能自适应访问模式,比如热点商品数据自然保留,冷数据被淘汰。
  • LFU(最不经常使用):淘汰访问频率最低的键。allkeys-lfuvolatile-lfu对应,适用于访问模式有冷热分明的业务,如某段时间内用户频繁访问某个活动页面,活动结束后访问骤降,LFU能更快识别并淘汰。
  • TTL(即将过期):淘汰剩余存活时间最短的键。volatile-ttl仅对设置了过期时间的键有效,适合需要精确控制过期顺序的场景,如会话缓存。
  • 随机淘汰allkeys-randomvolatile-random,用于临时缓存或请求量极低的场景,一般不用。

实操步骤

Redis如何实现分布式缓存?分布式缓存策略有哪些?

:在redis.conf中设置maxmemory 4gbmaxmemory-policy allkeys-lru,然后重启Redis或执行CONFIG SET maxmemory-policy allkeys-lru动态生效,建议根据业务流量估算内存上限,保留20%冗余。

过期策略与内存管理

Redis采用定期删除+惰性删除组合,定期删除每隔100ms随机抽取部分带过期时间的键检查并删除;惰性删除在每次访问键时检查是否过期,过期则删除,这种策略避免了全量扫描的性能开销,但会导致过期键在未被访问时残留占用内存,合理设置maxmemory和淘汰策略是内存管理的最后防线。

小技巧:对于大量相同过期时间的键,可以给它们增加随机偏移量,避免同一时间大量键过期导致缓存雪崩,例如在设置缓存时,过期时间统一为“3600 + random(0,600)”。

Redis缓存穿透解决方案:布隆过滤器与缓存空对象

缓存穿透是指查询一个不存在的数据,由于缓存未命中,每次请求都落到数据库,导致数据库压力飙升,常见于恶意攻击或查询不存在的ID场景。

缓存穿透成因与影响

当API接口未对参数做校验,或者用户按顺序遍历ID时,大量请求直接穿透缓存,例如一个电商系统,用户请求商品ID为“-1”或一个不存在的ID,如果缓存层未命中,数据库每次都要返回空结果,大量并发下数据库连接可能被耗尽。

布隆过滤器实现步骤

布隆过滤器是一种概率型数据结构,用于判断元素是否“可能存在”或“肯定不存在”,使用多个哈希函数将元素映射到一个位数组中,存在误判率(可能把不存在判为存在),但不会漏判。

实现步骤

  1. 预估容量和误判率:假设预计存储100万个key,允许误判率1%,则位数组长度约1200万bit,哈希函数数量约7个。
  2. 初始化位数组:在Redis中,可以使用SETBIT命令操作字符串实现位数组,或使用Redis 4.0+的BF.RESERVE模块命令,推荐使用Redisson或Lettuce等客户端内置布隆过滤器。
  3. 预热数据:将所有可能存在的key(如商品ID)提前写入布隆过滤器。
  4. 查询流程:请求到达时,先检查布隆过滤器,如果过滤器返回不存在,直接拒绝请求;如果返回可能存在,再查询缓存或数据库。

代码示例(Java + Redisson):

RBloomFilter<String> bloomFilter = redisson.getBloomFilter("productFilter");
bloomFilter.tryInit(1000000L, 0.01);
// 预热
bloomFilter.add("123");
// 查询
if (!bloomFilter.contains(requestId)) {
    return "不存在";
}

Redis如何实现分布式缓存?分布式缓存策略有哪些?

注意:布隆过滤器无法删除元素,如果业务数据频繁删除,考虑使用布隆过滤器的变种(如Counting Bloom Filter)或定期重建。

缓存空对象与降级策略

当查询结果为空时,将空结果也缓存起来,设置较短的过期时间(如60秒),这样后续相同请求可以从缓存中拿到空值,避免穿透,缺点是缓存层会存储大量空键,占用内存,且可能导致数据不一致(如果真实数据写入后,空缓存未过期),解决方案是结合布隆过滤器使用,布隆过滤器拦截大部分不存在请求,缓存空对象作为兜底。

降级策略:在缓存层与数据库之间增加限流组件,如Sentinel或Hystrix,当数据库压力超过阈值时,直接返回默认值或错误提示,保护数据库。

高并发场景下Redis缓存策略实战

高并发场景对缓存策略的挑战来自热点key、缓存雪崩和集群扩展,业界在实践中总结出若干可复用的方案。

热点key的发现与处理

热点key指短时间内被大量访问的key,比如明星动态、秒杀商品,它们会导致Redis单实例CPU飙升,甚至引发局部故障。

发现方法:本地统计访问频率,在Redis客户端使用INFO commandstats查看命令频次,或使用Redis 6.0的CLIENT LIST结合idle字段监测,开源工具如RedisHotKey也能实时监控。

处理方案

  • 本地缓存+Redis缓存:在应用层使用Caffeine或Guava Cache缓存热点key,设置较短的过期时间(如1秒),减少对Redis的请求。
  • 读写分离:让热key的读请求分散到多个Redis从节点,或使用Redis Cluster自然分片。
  • 限流与降级:对热点key的写操作进行限流,读操作返回过期数据或默认值。

缓存雪崩预防与互斥锁

缓存雪崩指大量缓存key在同一时间过期,或Redis实例宕机,导致所有请求直接打到数据库,预防措施包括:

  • 过期时间加随机值:避免大批key同时过期,设置过期时间时增加随机偏移量。
  • 高可用架构:使用Redis Sentinel或Cluster保证故障自动切换,防止单点失效。
  • 互斥锁(Mutex):当缓存失效时,只允许一个线程去加载数据,其他线程等待或返回旧缓存,实现方式:使用SETNX命令尝试获取锁,成功则加载数据,其他线程

    Redis如何实现分布式缓存?分布式缓存策略有哪些?

    sleep后重试。

实操步骤:在Java中,使用Redisson的RLock实现:

RLock lock = redisson.getLock("cache_rebuild_lock");
if (lock.tryLock(100, 10, TimeUnit.SECONDS)) {
    try {
        // 查询数据库并回填缓存
    } finally {
        lock.unlock();
    }
} else {
    // 等待或返回旧值
}

集群高可用方案对比

Redis高可用方案主要有哨兵模式集群模式

方案 架构 优点 适用场景
哨兵模式 一主多从,哨兵监控 配置简单,自动故障转移 数据量不超过单机内存,读写分离需求
集群模式 多主多从,数据分片 容量水平扩展,自动分片 数据量超过单机内存,高并发写入

选择建议:数据量在10GB以内且对一致性要求高的场景,优先使用哨兵模式;数据量达到百GB级或需要弹性伸缩时,选择集群模式,国内云厂商提供的Redis服务(如简米云、酷番云)通常支持两种模式,价格差异主要体现在规格和带宽上,企业版价格通常比自建高30-50%,但免运维。

分布式缓存(Redis)常见问题解答

Q1: Redis缓存穿透和缓存雪崩有什么区别?

缓存穿透是查询不存在的数据,每次绕过缓存直达数据库;缓存雪崩是大量缓存key同时失效或Redis宕机,导致请求全部落到数据库,前者是数据缺失,后者是缓存失效,解决方案不同:穿透用布隆过滤器和空对象缓存,雪崩用过期时间随机化和高可用集群。

Q2: 如何选择合适的Redis缓存淘汰策略?

多数场景推荐allkeys-lru,因为它能自动保留热点数据,如果业务访问模式有明确冷热周期,且对最近访问不敏感,可选allkeys-lfu,如果每个key都有明确的过期时间且希望优先淘汰即将过期的key,可选volatile-ttl,优先保障内存不溢出,再根据业务验证响应时间。

Q3: Redis集群模式下缓存策略有何变化?

集群模式下,key根据哈希槽分布到不同节点,淘汰策略、过期策略在每个节点独立执行。缓存穿透和雪崩的解决方案不变,但热点key可能导致单个节点压力过大,需结合本地缓存或一致性哈希优化,布隆过滤器建议在客户端侧维护,避免跨节点请求。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱