(转)处理Redis缓存特殊情况的方法

Posted jfcat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(转)处理Redis缓存特殊情况的方法相关的知识,希望对你有一定的参考价值。

前言

当 Redis 用作缓存时,其目的就是为了减少数据库访问频率,降低数据库压力,但是假如我们某些数据并不存在于 Redis 当中,那么请求还是会直接到达数据库,而一旦在同一时间大量缓存失效或者一个不存在缓存的请求被恶意攻击访问,这些都会导致数据库压力骤增,这又该如何防止呢?

缓存雪崩

缓存雪崩指的是 Redis 当中的大量缓存在同一时间全部失效,而假如恰巧这一段时间同时又有大量请求被发起,那么就会造成请求直接访问到数据库,可能会把数据库冲垮。

缓存雪崩一般形容的是缓存中没有而数据库中有的数据,而因为时间到期导致请求直达数据库。

解决方案

解决缓存雪崩的方法有很多,常用的有以下几种:

  • 加锁,保证单线程访问缓存。这样就不会有很多请求同时访问到数据库。
  • key 值的失效时间不要设置成一样。典型的就是初始化预热数据的时候,将数据存入缓存时可以采用随机时间来确保不会在同一时间有大量缓存失效。
  • 内存允许的情况下,可以将缓存设置为永不失效。

缓存击穿

缓存击穿和缓存雪崩很类似,区别就是缓存击穿一般指的是单个缓存失效,而同一时间又有很大的并发请求需要访问这个 key,从而造成了数据库的压力。

解决方案

解决缓存击穿的方法和解决缓存雪崩的方法很类似:

  • 加锁,保证单线程访问缓存。这样第一个请求到达数据库后就会重新写入缓存,后续的请求就可以直接读取缓存。
  • 内存允许的情况下,可以将缓存设置为永不失效。

缓存穿透

缓存穿透和上面两种现象的本质区别就是这时候访问的数据不但在 Redis 中不存在,而且在数据库中也不存在,这样如果并发过大就会造成数据源源不断的到达数据库,给数据库造成极大压力。

解决方案

对于缓存穿透问题,加锁并不能起到很好地效果,因为本身 key 就是不存在,所以即使控制了线程的访问数,但是请求还是会源源不断的到达数据库。

解决缓存穿透问题一般可以采用以下方案配合使用:

  • 接口层进行校验,发现非法的 key 直接返回。比如数据库中采用的是自增 id,那么如果来了一个非整型的 id 或者负数 id 可以直接返回,或者说如果采用的是 32 位 uuid,那么发现 id 长度不等于 32 位也可以直接返回。
  • 将不存在的数据也进行缓存,可以直接缓存一个空或者其他约定好的无效 value。采用这种方案最好将 key 设置一个短期失效时间,否则大量不存在的 key 被存储到 Redis 中,也会占用大量内存。

参考:

https://www.cnblogs.com/lonely-wolf/p/14451302.html

以上是关于(转)处理Redis缓存特殊情况的方法的主要内容,如果未能解决你的问题,请参考以下文章

redis使用基础 ——Redis特殊情况处理机制

springmvc+mybatis+redis(转)

Redis整合Spring结合使用缓存实例(转)

探讨下如何更好的使用缓存 —— Redis缓存的特殊用法以及与本地缓存一起构建多级缓存的实现

怎样使用redis缓存,java代码

ehcache与redis的比较与应用场景分析(转)