欢迎来到“雪碧聊技术”CSDN博客!
在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将不断探索Java的深邃世界,分享最新的技术动态、实战经验以及项目心得。
让我们一同在Java的广阔天地中遨游,携手提升技术能力,共创美好未来!感谢您的关注与支持,期待在“雪碧聊技术”与您共同成长!
目录
一、缓存穿透
1、什么是缓存穿透?
缓存穿透的关键:不怀好意的人,会使大量的请求打到数据库,从而使数据库崩溃。
2、解决缓存穿透的两个方案
①缓存空字符串
②布隆过滤
3、解决商铺查询的缓存穿透问题
①思路:使用缓存空对象的方式。
②编写代码
③运行项目,查看效果
4、总结
①缓存穿透产生的原因是什么?
②缓存穿透的解决方案有哪些?
一、缓存穿透
1、什么是缓存穿透?
缓存穿透:是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。
举例:
假设我们的店铺id是1~20,结果有人非要查询id为100的店铺,这明显是不合理的,于是就会出现如下情况:
此时缓存中没有,去数据库查询也没有,于是这个不怀好意的人抓住了这个漏洞,搞了一堆线程来发送大量的请求,查询这个不存在的id,这些海量的请求都会打到数据库中,长时间一来,数据库就会垮掉(数据库速度不像redis那么快,可能打到数据库的请求一多,就会导致数据库垮掉)。
缓存穿透的关键:不怀好意的人,会使大量的请求打到数据库,从而使数据库崩溃。
2、解决缓存穿透的两个方案
解决关键:不让大量的不合理请求,打到数据库!
①缓存空字符串
解决思路:一个不怀好意的人,查询id=100的店铺时,redis、数据库中都没有,因此数据库就向redis中缓存一个key为100,值为“”空字符串的数据。这样即使这个人,查询id=100的店铺,发送多少次请求都没用,因为都被redis命中了""空字符串,然后就直接拒绝请求了,这是摸不到数据库的,因此就不会导致数据库崩溃。
因此就解决了缓存穿透。
- 优点:实现简单,维护方便。
- 缺点:产生额外的内存消耗、可能造成短期的不一致
可以给存入redis中null的数据,设置有效期TTL,这样就不会导致爆满。
②布隆过滤
请求先经过“布隆过滤器”,先问问所查询的数据是否存在,如果“布隆过滤器”说不存在,那么将直接拒绝这个请求,根本不给你摸到数据库的机会。
- 优点:内存占用较少,没有多余的key。
- 缺点:实现复杂、存在误判可能
3、解决商铺查询的缓存穿透问题
①思路:使用缓存空对象的方式。
第一步:查询数据库时,如果不存在,不仅要报404异常,还要将查询的id作为key,“”空字符串作为value,存入redis中,这样该请求就不会一直摸到数据库。
第二步:判断redis命中时,要额外增加一个判断逻辑:如果命中的是“”空字符串,则直接结束请求;不是“”空字符串,才会返回给前端。
②编写代码
③运行项目,查看效果
第一次访问一个不存在的商铺id=0:
可见此时数据库中,查询该id不存在,于是以该id为key,“”空字符串为value,存入redis中,以便后期防止缓存穿透。
第二次访问该id=0的商铺,就是纯恶意访问,想让这个id=0的请求频繁打在数据库上:
此时发现该请求摸不到数据库,而是在redis命中“”空字符串,然后被拒绝了,挡住了,没有摸到数据库,这就解决了“缓存穿透”。
4、总结
①缓存穿透产生的原因是什么?
用户请求的数据在redis缓存、数据库中都不存在,于是恶意地、频繁地发起这样的请求,一直打到数据库中,给数据库带来巨大压力,导致数据库崩溃。
②缓存穿透的解决方案有哪些?
- 方式一:缓存“”空字符串
- 方式二:布隆过滤