缓存总结

分析:
    百万并发下,如果所有的请求都落到db,那么db一定会承受不住,导致宕机。
    所以一定要加缓存。
    那么加了缓存就保证db不会因为大量并发而导致宕机嘛?缓存有什么问题?
        1)缓存击穿:
            大量并发请求一个不存在的数据。缓存一定不会命中,然后都落到db。
          解决:加null值。如果第一个请求在db返回null,那么也把他加到缓存中,这样后边的请求就会在缓存中命中null值返回。

        2)缓存穿透:
            大量并发请求一个数据,这个数据在缓存中刚好过期,那么所有的请求就会落到db。
          解决:加锁,第一个进来的请求拿到锁之后,查db,查完db把数据放入缓存中,这样后边的数据就会命中缓存。

        3)缓存雪崩:
            大量缓存中的数据同时失效。
          解决:对缓存中的数据设置一个过期时间。

1. 用“SET key value [EX seconds]  [NX|XX]1)开始我加的本地锁,锁的粒度只能锁住当前服务。
   即用synchronized锁住当前服务,这样其实也没有什么问题,就算服务有50个的话,最多也就有50个请求落到db,也可以接收。
  2)然后用分布式锁,锁的粒度是锁住当前所有服务。
   用redis的“SET key value [EX seconds]  [NX|XX]”这个命令:意思就是往redis中存一个值只有在不存的时候,才存。
   就用这个特性,来锁住所有服务。
   大量请求进来,被网关负载均衡到各个服务。
   请求进来如果缓存命中->则直接返回。
   缓存没命中:
        第一个请求拿到分布式锁->第一个请求查db->查完db放入缓存中->释放锁,这样后边的请求就能从缓存命中。
        其他请求自旋。

   这样就达到了分布式锁的目的,即大量请求进来,只查一遍db。
   但是这样写工作量还是很大的,因为每个放入缓存中的数据都要这么做。

   还要考虑:锁的过期时间的设置,原子删锁(执行lua脚本)
2.用redisson
   上边的不会有问题,就是工作量太大了,所以我们引入了redisson。

    redisson的底层已经为我们考虑周到了,比如原子删锁,锁的过期时间,设置。

    伪代码就变成
       1. 锁住
       2. 查db
       3. 释放锁
    就这三步也可以保证分布式锁。

==========缓存一致性===========
redisson成功的实现分布式锁,并且能解决缓存击穿,穿透,雪崩问题。
但是如果要是考虑缓存一致性的话,就有些麻烦了。
    失效模式(写数据库,删除缓存)和双写模式(写数据库,更新缓存)来解决缓存一致性。
    这样只要有写的时候,就会操作缓存,对缓存写有压力。话说回来,经常写的数据也不会放入缓存。
    但是工作量还是比较大的。
3.
所有引入了spingCache框架,

    读模式:
    1)缓存击穿: ache-null-values=true
    2)缓存雪崩:spring.cache.redis.time-to-live=3600000
    3)缓存击穿:   @Cacheable开启缓存的这个注解只能加本地锁,但是对数据库的影响并没有多大。
    4)缓存一致性问题解决:
    用@CacheEvict注解来实现失效模式
     @CacheEvict删除掉我们指定的所有缓存
    用@CachePut注解来实现双写模式
     @CachePut查完数据,如果数据是最新数据就把他再一次放入缓存

     写模式:
     这个框架并没有处理,所以这个框架适合读多写少,即时性,一致性要求不高的数据。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值