分布式缓存是一种设计思想。
分布式缓存是指将缓存数据分布存储在 多台服务器 上,以便在高并发场景下提供更高的吞吐量和更好的容错性。
通常使用Redis实现
使用 Redis 实现分布式缓存,典型流程可以理解为:
应用先查 Redis,Redis 没有再查数据库,然后把结果写回 Redis

基本流程

  1. 用户请求进入应用服务

    比如用户查询商品详情:

    GET /products/1001
    
  2. 应用先查询 Redis 缓存

    应用根据业务生成一个缓存 Key,例如:

    product:1001
    

    然后查询 Redis:

    GET product:1001
    
  3. 如果 Redis 中有数据,直接返回

    这叫 缓存命中

    用户请求
       ↓
    应用服务
       ↓
    Redis 有数据
       ↓
    直接返回结果
    

    优点是速度快,不需要访问数据库。

  4. 如果 Redis 中没有数据,查询数据库

    这叫 缓存未命中

    用户请求
       ↓
    应用服务
       ↓
    Redis 没有数据
       ↓
    查询数据库
    
  5. 将数据库查询结果写入 Redis

    数据库查到结果后,应用把数据写入 Redis,并设置过期时间:

    SET product:1001 "{商品数据}" EX 3600
    

    表示缓存 1 小时。

  6. 返回数据给用户

    最后应用把数据库查到的数据返回给用户。

完整流程如下:

用户请求
   ↓
应用服务
   ↓
查询 Redis
   ↓
Redis 是否有数据?
   ↓
有数据 ----------------→ 直接返回
   ↓
没有数据
   ↓
查询数据库
   ↓
写入 Redis,并设置过期时间
   ↓
返回结果

简单 Java 示例

public Product getProductById(Long id) {
    String key = "product:" + id;

    // 1. 先查 Redis
    Product product = redisTemplate.opsForValue().get(key);

    if (product != null) {
        // 2. 缓存命中,直接返回
        return product;
    }

    // 3. 缓存未命中,查数据库
    product = productMapper.selectById(id);

    if (product != null) {
        // 4. 写入 Redis,并设置过期时间
        redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS);
    }

    return product;
}

常见缓存策略

  • Cache Aside Pattern,旁路缓存模式

    最常见,也是上面这个流程:

    读:先查缓存,缓存没有查数据库,再写缓存
    写:先更新数据库,再删除缓存
    
  • 设置过期时间

    防止 Redis 中的数据长期不更新:

    product:1001 过期时间 1 小时
    
  • 更新数据时删除缓存

    修改商品信息时,通常这样做:

    更新数据库
        ↓
    删除 Redis 缓存
    

    而不是直接更新缓存。

写操作流程

比如修改商品价格:

用户修改商品信息
   ↓
应用服务
   ↓
更新数据库
   ↓
删除 Redis 中对应缓存
   ↓
下次查询时重新加载新数据到 Redis

示例:

public void updateProduct(Product product) {
    // 1. 更新数据库
    productMapper.updateById(product);

    // 2. 删除缓存
    String key = "product:" + product.getId();
    redisTemplate.delete(key);
}

使用 Redis 做分布式缓存时要注意的问题

  • 缓存穿透

    查询一个数据库中也不存在的数据,导致每次都查数据库。

    解决方式:

    缓存空值 / 布隆过滤器
    
  • 缓存击穿

    某个热点 Key 过期,大量请求同时打到数据库。

    解决方式:

    加互斥锁 / 热点数据不过期 / 提前刷新
    
  • 缓存雪崩

    大量 Key 同时过期,数据库压力突然增大。

    解决方式:

    过期时间加随机值 / 多级缓存 / 限流降级
    
  • 数据一致性

    数据库和 Redis 可能短时间不一致。

    常见做法:

    先更新数据库,再删除缓存
    

Redis 分布式缓存的核心流程就是:读数据先查缓存,缓存没有查数据库并写回缓存;写数据先更新数据库,再删除缓存。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐