• redis之缓存穿透、缓存击穿、缓存雪崩及解决方案


    缓存穿透

      指查询一个数据库中一定不存在的数据,那么缓存和数据库中都不存在。这种查询不存在数据的现象称为缓存穿透。

    如根据商品编号查询详情;首先去查询缓存,缓存中自然没有然后去查询数据库,如果对这个key的请求量巨大,会直接穿透缓存直接查询数据库给数据库造成很大的压力,大量穿透请求严重情况下会造成数据库宕机。

      解决方案:

      1、缓存空值:对查询结果为空的情况也进行缓存,值设置为null,不过缓存时间设置短一些,如60s。如果对该key插入了数据到db之后要清理缓存

      2、使用布隆过滤器,将所有可能存在数据的key放在布隆过滤器中,查询缓存中没有数据之后,再使用布隆过滤器进行过滤请求,判断查询的key

        是否在布隆过滤器中,如果不在,则直接返回不再查询数据库。

      总结:

      1)针对空数据的key是有限的,重复率比较高的采用缓存空值的方式。

      2)针对大量请求key不存在、请求重复率低的数据,就没必要缓存,采用布隆过滤器直接过滤掉。

        

    缓存击穿

      某个key是热点数据,扛着高并发请求集中对这个key进行访问,避免了访问数据库。那么在这个key失效的瞬间,持续的高并发就击穿了缓存直接

      请求数据库,对数据库造成很大压力。

      解决方案:

      1、热点key缓存永远不过期

        不设置过期时间

        将过期时间存在key的value中,程序判断将要过期时,异步线程对改key进行更新

      2、互斥锁,mutex lock 。当缓存失效的时候,线程不是立即去查询数据库,而是通过设置锁的方式占坑,如Redis的SETNX,判断返回值,谁拿

        到了锁谁去查询数据库然后设置缓存,没拿到锁的线程重试get方法。

    缓存雪崩

      在某个时间段,发生大规模缓存失效的情况。

      有两种可能:

        1、缓存服务宕机 

        2:缓存中大量的key集中过期失效

      缓存服务宕机解决方案:

        1、宕机前:避免出现宕机,使用集群缓存,保证缓存服务的高可用

          可以使用 主从+哨兵 ,Redis Cluster 来避免 Redis 全盘崩溃的情况。

        2、宕机后: Hystrix限流&降级,避免MySQL宕机、尽快恢复缓存集群(重启自动从磁盘中加载数据恢复,需要提前开启Redis持久化机制)

      缓存集中失效解决方案:

      1、使用互斥锁

      2、数据预热,并设置不同的失效时间

        通过缓存reload机制,预先去设置或更新缓存,在即将大并发访问前手动在后台触发加载缓存不同的key,然后设置不同的过期时间,让缓存

        过期失效的时间点尽量均匀错开

      3、二级缓存

        两个缓存,a1为原始缓存,a2为备份缓存;a1短期,a2长期;a1过期了再去查询a2

      4、缓存永远不过期

    互斥锁实现逻辑:

    public String get(key) {
          String value = redis.get(key);
          if (value == null) { //代表缓存值过期
              //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
              if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表设置成功
                   value = db.get(key);
                          redis.set(key, value, expire_secs);
                          redis.del(key_mutex);
                  } else {  //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
                          sleep(50);
                          get(key);  //重试
                  }
              } else {
                  return value;     
              }
     }

    END.

  • 相关阅读:
    [转]Release版程序调试排错技巧
    关于获得MFC窗口其它类指针的方法(CSDN)
    MFC .DLL指南(二)
    对“仅通过崩溃地址找出源代码的出错行”一文的补充与改进,转自vckbase,记录一下
    [转]调试Release版本应用程序,不知道转自哪里
    MFC的DLL 概述
    从今天开始每天写C++或其他学习的知识的笔记,以激励自己
    近日发现vs2005安装的一个问题
    VC中处理C1010错误的两种方法
    [转]VC调试篇不知道转自何处
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/13802739.html
Copyright © 2020-2023  润新知