zoukankan      html  css  js  c++  java
  • <转>浅谈缓存击穿、缓存并发和缓存失效

    原文地址:缓存穿透、缓存并发、缓存失效之思路变迁

    我们在用缓存的时候,不管是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的压力凸显。这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。

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

  • 相关阅读:
    python字符串连接方式(转)
    Python顺序与range和random
    将EXCEL中的列拼接成SQL insert插入语句
    Python OS模块
    Python3.5连接Mysql
    Mysql查看连接端口及版本
    Mysqldb连接Mysql数据库(转)
    Python 文件I/O (转)
    Python 日期和时间(转)
    Python序列的方法(转)
  • 原文地址:https://www.cnblogs.com/imyalost/p/7612111.html
Copyright © 2011-2022 走看看