zhangxiaoxu132113 / data-redis

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Redis整合Guava的Optionals解决缓存穿透问题

一,什么是缓存穿透

缓存穿透是指根据key从缓存组件获取不到数据,就去数据库查询数据。如果用户恶意访问这个key的数据,那么就会不断缓存穿透到数据库查询数据。 这样会造成数据库的性能压力问题。

二,怎么解决

网上给出的解决方案大都相似,如果在数据库查询不到对应的数据,就塞一个约定的值(比如:#@xz%!j.~*^&,不是骂人的意思哦)。 如果下次再请求这个key就可以查询出数据,判断这个值是不是我们约定的值,如果是的话,就说明在数据库没有找到这个key对应的值。这时候就不会缓存穿透到数据库。

三,谁是罪魁祸首呢?就是表意不清的null关键字

为什么说罪魁祸首就是null关键字呢?下面开始分析

  • 当第一次访问key为123的数据的时候,缓存没有这个key,则返回null,这个时候的null是说明缓存没有这个key
  • 接下来,查询数据库,假如数据库没有对应的数据,返回的是null,把这个null放入这个key(当然,原则上是放不进去的),这就产生歧义了,null即表述了key不存在,也表述了数据库不在key对应的数据。 一个null表明了两个意思,导致描述不清楚,访问这个key,返回的null到底是没有这个key,还是说数据不存在这个值。

四,Guava Optional主张不使用null

Guava Optional是不主张使用null关键字,认为null是比较糟糕的设计。 如果程序这样设计呢?如果查询数据库不存在该值,那就将null封装为一个Optional对象放到缓存中。

  • 当第一次访问key为123的数据的时候,如果为null则说明没有key
  • 查询数据库不管有没有查询到数据,都把对象放到Options,然后放到缓存。
  • 当第二次查询缓存的时候,返回的就不是null,而是Options,通过
if (!optional.isPresent()) {
   throw new RuntimeException("数据库没有该" + key + "对应的数据");
}

来判断是否是空值。

About


Languages

Language:Java 100.0%