Redis作为缓存的使用场景与常见问题

Redis作为缓存的使用场景与常见问题

一、Redis作为缓存的典型使用场景

1. 热点数据缓存

  • 场景:高频访问的数据库查询结果(如电商商品详情)
  • 优势:通过内存读写避免频繁访问数据库,响应时间从毫秒级降至微秒级
  • 实现SET user:1001 "{name: 'Alice', age: 28}" EX 3600

2. 会话存储(Session Storage)

  • 场景:分布式系统中的用户会话共享
  • 优势:比传统Cookie更安全,比数据库存储更高效
  • 数据结构:String/Hash存储会话信息

3. 页面/API缓存

  • 场景:缓存渲染后的HTML页面或API响应
  • 技巧:配合EXPIRE实现自动过期,使用GETSET保证缓存更新原子性

4. 排行榜/计数器

  • 数据结构
    • Sorted Set实现实时排行榜(ZADD leaderboard 100 "user1"
    • INCR实现原子计数器(UV/PV统计)

5. 分布式锁

  • 实现SET lock_key unique_value NX EX 30
  • 注意点:需配合Lua脚本保证原子性,推荐RedLock算法

6. 消息队列

  • 方案:使用List结构实现简单队列,Stream数据类型实现可靠消息队列

二、常见问题与解决方案

1. 缓存穿透

  • 现象:大量请求不存在的key(恶意攻击/非法查询)
  • 解决方案1(推荐)
-- 布隆过滤器伪代码
  if not bloom_filter.exists(key) then
      return null
  end
  • 解决方案2
    空值缓存:SET null_key “” EX 300
  • 解决方案3
    接口校验:增加参数合法性验证

2. 缓存击穿

现象:热点key过期瞬间大量请求直达DB

  • 解决方案1(最终一致性场景推荐)
    永不过期策略 + 异步更新
  • 解决方案2(强一致性场景推荐)
    互斥锁:
def get_data(key):
    value = redis.get(key)
    if not value:
        if redis.setnx("lock", 1):
            redis.expire("lock", 10)
            value = db.get(key)
            redis.setex(key, 3600, value)
            redis.delete("lock")
        else:
            sleep(0.1)
            return get_data(key)
    return value

3. 缓存雪崩

现象:大量key同时过期导致DB压力激增

  • 解决方案1(推荐)
    随机过期时间:EXPIRE key 3600 + random(600)
  • 解决方案2
    分级缓存:L1缓存(Redis)+ L2缓存(本地缓存)
  • 解决方案3
    熔断降级:Hystrix/Sentinel实现系统保护
  • 解决方案4
    搭建集群

4. 数据一致性

挑战:缓存与数据库的同步延迟

  • 策略1(最终一致性场景推荐)
    延迟双删策略:
public void updateData(Data data) {
    redis.del(data.id);      // 第一次删除
    db.update(data);         // 数据库更新
    Thread.sleep(500);       // 等待主从同步
    redis.del(data.id);      // 第二次删除
}
  • 策略2(最终一致性场景推荐)
    订阅binlog实现异步更新(Canal框架)
  • 策略3(强一致性场景推荐)
    适用于金融交易、库存扣减、订单状态等对数据准确性要求极高的场景,需要保证缓存与数据库的实时严格一致
    同步双写 + 事务控制:
    将数据库更新与缓存操作放在同一事务中
// 伪代码示例(需要支持XA事务的中间件)
@Transactional
public void updateOrder(Order order) {
    // 1. 数据库更新
    orderDao.update(order);
    
    // 2. 同步更新缓存(必须与数据库操作在同一事务)
    redisTemplate.opsForValue().set(
        "order:" + order.getId(), 
        order,
        30, TimeUnit.SECONDS
    );
}

注意事项:
需要数据库和Redis支持分布式事务(如通过Seata框架)
性能损耗较大(较最终一致性方案吞吐量下降40%-60%)

5. 内存管理

风险:内存溢出导致服务崩溃
应对措施:
监控内存使用:INFO memory
配置淘汰策略:
maxmemory 16gb
maxmemory-policy allkeys-lru(优先淘汰最近最少使用的key)
使用内存分析工具:redis-rdb-tools分析大key

6. 集群问题

常见问题:
脑裂问题:配置min-slaves-to-write 1
数据倾斜:使用Hash Tag合理分配slot
扩容缩容:使用redis-trib工具管理集群

7. 持久化风险

方案选择:
RDB:定时快照,恢复快但可能丢失数据
AOF:日志追加,数据安全但文件较大
混合模式(Redis 4.0+):aof-use-rdb-preamble yes

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值