我们在用缓存的时候,不管是Redis或者Memcached,基本上会通用遇到以下三个问题:

  • 缓存穿透

  • 缓存并发

  • 缓存失效

缓存穿透

注:上面三个图会有什么问题呢?

我们在项目中使用缓存通常都是先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回。这个时候如果我们查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB,这样缓存就失去了意义,在流量大时,可能DB就挂掉了。

那这种问题有什么好办法解决呢?

要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。有一个比较巧妙的作法是,可以将这个不存在的key预先设定一个值。比如,"key" , “&&”。

在返回这个&&值的时候,我们的应用就可以认为这是不存在的key,那我们的应用就可以决定是否继续等待继续访问,还是放弃掉这次操作。如果继续等待访问,过一个时间轮询点后,再次请求这个key,如果取到的值不再是&&,则可以认为这时候key有值了,从而避免了透传到数据库,从而把大量的类似请求挡在了缓存之中。

缓存并发

有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

我现在的想法是对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。

这种情况和刚才说的预先设定值问题有些类似,只不过利用锁的方式,会造成部分请求等待。

缓存失效

引起这个问题的主要原因还是高并发的时候,平时我们设定一个缓存的过期时间时,可能有一些会设置1分钟啊,5分钟这些,并发很高时可能会出在某一个时间同时生成了很多的缓存,并且过期时间都一样,这个时候就可能引发一当过期时间到后,这些缓存同时失效,请求全部转发到DB,DB可能会压力过重。

那如何解决这些问题呢?

其中的一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

我们讨论的第二个问题时针对同一个缓存,第三个问题时针对很多缓存。

总结

1、缓存穿透:查询一个必然不存在的数据。比如文章表,查询一个不存在的id,每次都会访问DB,如果有人恶意破坏,很可能直接对DB造成影响。

2、缓存失效:如果缓存集中在一段时间内失效,DB的压力凸显。这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。

当发生大量的缓存穿透,例如对某个失效的缓存的大并发访问就造成了缓存雪崩。

精彩问答

问题:如何解决DB和缓存一致性问题?

当修改了数据库后,有没有及时修改缓存。这种问题,以前有过实践,修改数据库成功,而修改缓存失败的情况,最主要就是缓存服务器挂了。而因为网络问题引起的没有及时更新,可以通过重试机制来解决。而缓存服务器挂了,请求首先自然也就无法到达,从而直接访问到数据库。那么我们在修改数据库后,无法修改缓存,这时候可以将这条数据放到数据库中,同时启动一个异步任务定时去检测缓存服务器是否连接成功,一旦连接成功则从数据库中按顺序取出修改数据,依次进行缓存最新值的修改。

问题:问下缓存穿透那块!例如,一个用户查询文章,通过ID查询,按照之前说的,是将缓存的KEY预先设置一个值,,如果通过ID插过来,发现是预先设定的一个值,比如说是“&&”,那之后的继续等待访问是什么意思,这个ID什么时候会真正被附上用户所需要的值呢?

我刚说的主要是咱们常用的后面配置,前台获取的场景。前台无法获取相应的key,则等待,或者放弃。当在后台配置界面上配置了相关key和value之后,那么以前的key &&也自然会被替换掉。你说的那种情况,自然也应该会有一个进程会在某一个时刻,在缓存中设置这个ID,再有新的请求到达的时候,就会获取到最新的ID和value。

问题:其实用Redis的话,那天看到一个不错的例子,双key,有一个当时生成的一个附属key来标识数据修改到期时间,然后快到的时候去重新加载数据,如果觉得key多可以把结束时间放到主key中,附属key起到锁的功能。

这种方案,之前我们实践过。这种方案会产生双份数据,而且需要同时控制附属key与key之间的关系,操作上有一定复杂度。

问题:多级缓存是什么概念呢?

多级缓存就像我今天之前给大家发的文章里面提到了,将Ehcache与Redis做二级缓存,就像我之前写的文章 http://www.jianshu.com/p/2cd6ad416a5a 提到过的。但同样会存在一致性问题,如果我们需要强一致性的话,缓存与数据库同步是会存在时间差的,所以我们在具体开发的过程中,一定要根据场景来具体分析,二级缓存更多的解决是,缓存穿透与程序的健壮性,当集中式缓存出现问题的时候,我们的应用能够继续运行。

缓存穿透、并发和失效的解决方案相关推荐

  1. 缓存穿透和缓存雪崩的一些解决方案

    作为一个内存数据库,redis也总是免不了有各种各样的问题,这篇文章主要是针对其中两个问题进行讲解:缓存穿透和缓存雪崩.并给出一些解决方案.这两个问题是基本问题也是面试常问问题. 一.缓存穿透 1.概 ...

  2. redis缓存穿透和缓存雪崩的浅析以及解决方案

    作为一个内存数据库,redis也总是免不了有各种各样的问题,这篇文章主要是针对其中两个问题进行讲解:缓存穿透和缓存雪崩.并给出一些解决方案.这两个问题是基本问题也是面试常问问题. 一.缓存穿透 1.概 ...

  3. Redis(四)(主从复制-搭建环境测试,哨兵模式-测试,缓存穿透,缓存击穿,缓存雪崩)

    文章目录 1.主从复制 (1)为什么会有主从复制? (2)主从复制能干啥? (3)搭建一主二从环境 (4)测试 (5)复制原理 (6)使用层层链路型来进行连接 (7)主机宕机后手动配置主机 2.哨兵模 ...

  4. 详解缓存穿透、缓存雪崩、缓存击穿

    背景 在现代软件架构中,缓存的应用已经非常普及.缓存的使用在面试和实践中都是避不开的硬技能.硬知识,如果你说还不太熟悉缓存的使用,可能都不好意思说自己是程序员. 这篇文章,带大家进一步学习在缓存使用中 ...

  5. 缓存穿透、缓存雪崩、缓存击穿?

    背景 在现代软件架构中,缓存的应用已经非常普及.缓存的使用在面试和实践中都是避不开的硬技能.硬知识,如果你说还不太熟悉缓存的使用,可能都不好意思说自己是程序员. 这篇文章,带大家进一步学习在缓存使用中 ...

  6. redis——缓存雪崩、缓存穿透、缓存击穿

    通常我们为了保证缓存中的数据与数据库中的数据一致性,会给 Redis 里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库,并将数据更新到 ...

  7. 清空缓存的命令_布隆过滤器应用——解决Redis缓存穿透问题

    1. 布隆过滤器 简要介绍布隆过滤器的概念和特点,详细知识请参考几篇参考文献或其它文章. 1.1 概念 简单点说,布隆过滤器本质是一个位数组. 当一个元素加入过滤器时,使用多个hash函数对元素求值, ...

  8. redis缓存雪崩、缓存击穿和缓存穿透还傻傻分不清?看这篇就够了

    前言 关于Redis的高频问题,缓存雪崩.缓存击穿和缓存穿透一定少不了,相信大家在面试中都被问到过类似的问题.为什么这些问题一直热门呢?因为我们在使用Redis缓存时,这些问题都是很容易遇到的.接下来 ...

  9. 高并发缓存处理之——缓存穿透的几种形式及解决方案

    缓存失效的几种形式 1 缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去 ...

最新文章

  1. python 多进程使用总结
  2. c#(winform)中ComboBox和ListBox添加项完全解决
  3. WPF 实现截屏控件之移动(二)(仿微信)
  4. Django实现简单的用户添加、删除、修改等功能
  5. OpenCV实现同态滤波
  6. 2020年58同城产品笔试题
  7. 域名注册管理机构域名注册服务机构的基本概念
  8. openCV学习资料整理
  9. java 大写中文金额 转 数字
  10. 关于选项卡的切换——JS实现
  11. [基础库Numpy] 技能树总结:一篇文章学会Numpy库
  12. 转换pdf 为 png
  13. 追求神乎其技的程式设计之道(八)
  14. Python数据分析案例07——二手车估价(机器学习全流程,数据清洗、特征工程、模型选择、交叉验证、网格搜参、预测储存)
  15. orecle的decode函数用法
  16. 1-XPE体系结构基础
  17. 【程序猿保健】ShaderJoy —— 拉力带教程
  18. 交换瓶子(蓝桥杯入门)
  19. 深度学习:利用神经网络在少量数据情况下预测房价走势
  20. 在服务器上利用mmdetection来训练自己的voc数据集

热门文章

  1. 从源码和内核角度分析redis和nginx以及java NIO可以支持多大的并发
  2. Linux中errno使用
  3. c#中什么情况下用(int)什么情况下用Convert.ToInt32
  4. vs2008 外部调用ActiveX控件接口方法
  5. 【FFmpeg】设置H264参数
  6. 【Qt】Qt项目常用代码总结
  7. php生成表格和读取,phpexcelreader读取excel自动生成表跟字段
  8. cpu渲染测试软件,CineBench渲染能力测试_CPUCPU评测-中关村在线
  9. 基于python的压测工具_Python Locust性能测试简介及框架实践
  10. python cv2 轮廓的包络 面积_Python 基于FIR实现Hilbert滤波器求信号包络详解