前面学习了redis的基础知识,接下来将对redis三大缓存问题进行分享,本文先从缓存穿透问题开始。首先介绍什么是缓存穿透以及怎么出现的,然后对此介绍常用的解决方案,包括布隆过滤器、缓存空对象等解决方案介绍,通过实战代码通过SpringBoot搭建redis,mysql环境在代码级别对缓存穿透问题和解决方案应用进行直观展示。
本文基于的代码环境:代码使用SpringBoot集成mybatis+mysql+redis的方式,本文缓存穿透问题仅采用redis单机模式,在另一台电脑主机的linux虚拟机上发布一个单机redis环境,详细linux部署单机redis环境的步骤可参考小编redis专栏的文章。mysql环境采用本机win7系统安装mysql5.7版本并启动mysql服务。由于在代码中有关于redis和mysql的连接配置,因此前提必须保证这redis和mysql环境是可用的,否则工程代码在启动时会相应报错。
好了,在此前提下,开始介绍本文的主题:redis缓存穿透
(一)什么是redis缓存穿透,怎么出现?
redis缓存穿透:指某个查询的key在缓存中不存在,然后跳过了缓存转而频繁去查询数据库,从而导致数据库的压力很大的现象。
可以用下面的图进行展示:
(二)缓存穿透问题代码重现?
我们在使用redis时,代码中最常见的思路就是:获取用户请求key,先到redis中根据key查询,如果redis命中则直接返回命中缓存的数据,如果redis没有命中则进一步查询数据库,如果数据库存在记录则写入redis并结果返回,如果数据库不存在记录则直接返回。主要功能代码大致如下:
在redis(默认无数据)和mysql中存储的数据如下:
那么通过浏览器访问并传入不同id值,localhost:8080/selectid?id=xxxxx,查看控制台输出的结果进行分析:
1)首先正常查询存在id情况:localhost:8080/selectid?id=1,可以看到返回正确结果,由于请求redis无果最后会查询一次数据库,然后把结果写入redis缓存。
那么下一次继续用localhost:8080/selectid?id=1访问时,就会发现直接命中redis返回,不再查询数据库。
2)对于上述第一种情况是正常的,那么我们换一个数据库并不存在的id请求并且连续3次浏览器刷新请求会怎么样呢?localhost:8080/selectid?id=10: