缓存中间件Redis以及缓存相关问题总结

缓存相关

数据库和缓存一致性问题

​ 如果对数据库查询做了缓存,那么在更新数据库(增、删、改)的时候,就可能存在缓存和数据库数据不一致的情况。对于数据一致性要求比较高的场景,就需要重点考虑数据库和缓存怎么尽量减少不一致的情况。

​ 对数据库做更新的时候,更新缓存的几种策略如下:

  • 先删除缓存,再更新数据库。
    • 存在问题:删除完缓存,更新数据库期间,有其他请求过来查询数据并更新缓存,那么就会产生数据不一致的情况。
    • 解决方案:使用延迟双删的策略,更新完数据库一定时间后再次删除缓存。这种方案也是无法完美解决不一致情况的,只能尽量减少出现不一致的时间。在更新完数据库到再次删除缓存期间的查询就有可能拿到旧数据。
  • 先更新数据库,再删除缓存。
    • 存在问题:更新数据库到删除缓存这段时间内,如果有查询请求进来,那么拿到的还是缓存中的旧数据。
    • 解决方案:异步更新缓存(基于订阅mysql的binlog的同步机制)。Mysql的binlog增量订阅消息+消息队列+增量数据更新到redis。一旦mysql中出现更新操作,就把binlog相关消息推送到redis,redis再根据binlog记录对redis更新。
  • 串行化解决数据库缓存一致性问题。

缓存穿透

  • 缓存穿透指的是,一条不存在数据库中的查询,因为每次查回来都是空的,不做缓存,所以对于大量不存在的数据发起的请求,会大量占用数据库资源。

  • 解决方法:

    • 布隆过滤器:预先将数据库中所有的数据存到布隆过滤器中,表示此数据存在。每次查询的时候先走布隆过滤器判断数据是否存在。

      • 布隆过滤器原理:

        布隆过滤器底层数据结构是一个固定长度的位数组,初始状态所有位都为0。当将变量添加到布隆过滤器时,通过k个哈希函数,将变量映射到数组上的k个点,并将这k个点的值设置为1。当查询某个变量是否存在的时候,同样通过k个函数将变量映射位k个点,检查是否每个点都为1,如果都为1表示可能存在,否则不存在。需要注意的是,布隆过滤器判断存在的条件并不是一定的,有一定概率误判。

      • 布隆过滤器的缺点:

        • 容易误判,且数据量越大越容易误判。
        • 不能删除里面的元素,因为删除了会影响大量的其他数据。
        • redis有布隆过滤器的插件(RedisBloom)。
        • Redission可以直接操作布隆过滤器。
    • 将空结果也作为返回结果缓存下载,但是这个值的过期时间需要设置的相对较短。

缓存击穿

  • 缓存击穿指得是,设置了缓存的热点数据,在某一刻缓存失效了,导致大量请求全部打到数据库中,使得数据库压力急剧增加而影响系统整体运行情况。
  • 解决方法:
    • 设置热点数据永不过期,那么就不会存在这种情况。
    • 使用互斥锁,来限制直接发起查询数据库的情况,具体方法如下几种:
      • redis的setnx实现分布式锁:当缓存过期的时候,所有请求查询缓存为空,首先去获取分布式锁,检查是否被占用。如果被占用,则等待一段时间,继续检查缓存是否有值。如果没有被占用,则查询数据库的值,放到缓存中然后释放锁。
      • 单机应用直接使用Lock(ReentrantLock互斥锁)。
    • 使用hystrix限流。
    • 使用两级缓存:每个微服务本地设置一个缓存作为一级缓存(ehcache),redis再存一份缓存,作为二级缓存。优先查本地缓存,如果本地缓存为空,则查二级缓存。如果都为空才去查数据库。

缓存雪崩

  • 缓存雪崩指的是,大量缓存数据同时失效,或者缓存服务器宕机,这时候大量数据请求全部发到数据库中,导致数据库系统压力过大。
  • 解决方案:
    • 给缓存设置不同的过期时间,错开缓存同时过期的情况。可以在缓存的时间上加上1~5分钟的随机时间。
    • 保障缓存服务器(Redis)的高可用性。
    • 对缓存数据的交易进行资源隔离、限流、熔断等操作,一旦遇到缓存服务器宕机的情况,可以直接熔断。
    • redis数据备份和事后恢复。

Redis实现分布式锁

  • Redis实现分布式锁的原理是setnx命令,如果指定的key已经有值,则返回0,否则返回1,并设置为指定的值。这是一个原子操作,分布式情况下也能保证原子性。

  • RestTemplate里面封装了对应的方法RestTemplate.opsForValue().setIfAbsent(),设置成功则返回true,设置失败则返回false。

  • 实现分布式锁:

    > setnx key value   // 加锁
    > expire key 1000   // 设置锁定最长时间,避免设置锁的应用挂掉而长久占有锁
    > del key    // 解锁
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值