今日分享 redis缓存

1、缓存穿透、缓存击穿、缓存雪崩区别和解决方案

前台向后台请求数据,后台先从缓存中取到数据,如果取不到时,从数据库查询,如果数据库取到则更新到缓存并返回结果,如果数据库未找到,那直接返回空结果。

- 缓存穿透:

查询数据时候,缓存中和数据库均没有。但是用户不断的发起请求(此时可能是恶意攻击),攻击会导致数据库压力过大,甚至dawn机
解决方案:

  • 1、增加接口校验,如用户鉴权校验,id做基础校验将异常的请求直接拦截

  • 2、从缓存中取数据,在数据库中也没有取到,这时候将键值对的value值设置成null并可以设置短时间的有效期限,防止用户用同一个id进行暴力攻击

  • 3、布隆过滤器(中间件)hashMap+bit数组(因为redis支持get 、set bit方法)在缓存之前再加一层布隆过滤器,在查询的时候先去布隆过滤器查询key是否存在,如果不存在就直接返回,存在再走查缓存和数据库。

  • <可参考博客:https://zhuanlan.zhihu.com/p/43263751>

缓存击穿:
是指缓存中没有但是数据库中存在的数据,这时候由于并发用户特别多,同时缓存没有读到数据,用户请求一下同时去数据库取数据,引起DB瞬时压力过大
解决方案:

  • 1、设置热点数据永不过期

  • 2、加互斥锁:
    多个线程同时去查询数据库的这条数据时,我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它,其他线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来了,就可以直接走缓存了。
    今日分享 redis缓存_第1张图片
    缓存雪崩
    ​ 缓存雪崩的情况是,在某一时刻发生大规模的缓存失效的情况,比如你的缓存服务宕机了,会有大量的请求进来直接打到DB上。结果就是DB撑不住宕机了

  • 1、事前,使用集群缓存,保证缓存服务的高可用 ​ 这种方案是在发生雪崩前对缓存集群实现高可用,如果是使用Redis,可以使用主从+哨兵或者Redis Cluster来避免Redis全盘崩溃的情况。

  • 2、事中:ehcache本地缓存 + Hystrix限流&降级,避免数据库被打死 ​
    使用ehcache本地缓存的目的也是考虑在Redis、Cluster完全不可用的时候,ehcache本地缓存可以支撑一阵。 ​
    使用Hystrix进行限流&降级,例如一秒来了3000个请求,我们可以设置只能有一秒1000个请求能通过这个组件,那么其他剩余的2000请求就会走限流逻辑。然后去调用我们自己开发的降级组件,比如设置一些默认值之类的,以此来保护数据库不会被大量的请求给打死。

  • 3、事后:开启Redis持久化机制,尽快恢复缓存集群 ​ 一旦重启,就能从磁盘上自动加载数据恢复内存中的数据。

解决热点数据集中失效问题
什么是热点数据集中失效?

​ 我们在设置缓存的时候,一般会给缓存设置一个失效时间,过了这个时间,缓存就失效。对于一些热点的数据来说,当缓存失效以后会存在大量的请求过来,然后打到数据库中去,从而可能导致数据库崩溃的情况。

解决方案

  • 1、设置不同的过期时间 ​
    为了避免这些热点数据集中失效,那么我们在设置缓存过期时间的时候,尽量让他们失效的时间错开。例如在一个基础的时间上加上或减去一个范围内的随机值。
  • 2、互斥锁 ​ 结合上面击穿的情况,在第一个请求去查询数据库的时候加一个互斥锁,其余的查询都会被阻塞住,知道锁释放,从而保护数据库。
    ​ 但是因为它会阻塞其他线程,此时系统吞吐量会下降,需要结合实际的业务去考虑是否要这么做。

主从复制、哨兵机制:一个主节点(master)可拥有多个从节点(slave),从节点实现对主节点的复制,保证数据同步。而哨兵(sentinel)则对各节点进行监控,主要包括主节点存活检测、主从运行情况检测等,一旦主节点宕机,哨兵可自动进行故障转移 (failover)、主从切换。

你可能感兴趣的:(缓存,redis,java)