zoukankan      html  css  js  c++  java
  • Redis缓存击穿、穿透、雪崩解决方案

    1、缓存处理流程

    接收到查询数据请求时,优先从缓存中查询,若缓存中有数据,则直接返回,若缓存中查不到则从DB中查询,将查询的结果更新到缓存中,并返回查询结果,若DB中查不到,则返回空数据

     

    1、缓存雪崩

    缓存中大批量的数据都到了过期时间,从而导致查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同,缓存击穿是指某一条数据到了过期时间,大量的并发请求都来查询这一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库

    解决方案:

    1、设置热点数据永不过期
    2、缓存数据的过期时间设置随机,可以在原有的过期时间上加上一个随机值,比如1-3min,防止同一时间大量缓存数据集体失效,导致数据库压力过大。
    3、如果是分布式部署缓存数据库,可将热点数据分别存放到不同的缓存数据库中,避免某一点由于压力过大而down掉。(redis集群,mysql集群)

    4.定时把数据库数据刷新到redis

    2、缓存穿透

    当缓存与数据库中都不存在该数据时,由于当数据库查询不到数据就不会写入缓存,这个时候如果用户不断的恶意发起请求,就会导致这个不存在的数据每次请求都会查询DB,请求量大的情况下,就会导致DB压力过大,直接挂掉。

    解决方案:

    1、当查询返回一个空数据时,直接将这个空数据存到缓存中,过期时间不宜设置过长,建议不超过5分钟
    2、采用布隆过滤器:将所有可能存在数据,分别通过多个哈希函数生成多个哈希值,然后将这些哈希值存到一个足够大的bitmap中,此时一个一定不存在的数据就会被这个bitmap拦截,从而减少了数据库的查询压力。

    https://www.bilibili.com/video/BV15y4y1r7X3/?spm_id_from=333.788.recommend_more_video.1

    3.数据过滤

    3、缓存击穿

    某一个数据缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,严重情况下会直接挂掉。

    解决方案:

    1、添加互斥锁:(reids集群--》分布式锁)

    • ReentrantLock公平锁
    • 根据key值加锁,这样线程之间会不影响,不会因为某一个线程获取了锁,其它线程就处于等待时间,也就是线程A从数据库取key1的数据并不妨碍线程B取key2的数据
      2、设置热点数据永不过期(物理上的不过期、“逻辑上”的不过期(缓存到期动态构建缓存))
  • 相关阅读:
    ECMAScript 引用类型Object 对象
    jQuery Form Plugin
    在 PHP5 中使用 DOM 控制 XML
    JavaScript encodeURI()和encodeURIComponent() 函数
    程序员进阶的建议:多看、多写、多交流
    jQuery 取 css zindex 值在各种浏览器中的返回值
    XPath 语法教程(Tutorial_2)
    使用 strpos 需要注意 === 运算符
    关于代码开发规范和原则
    PHP 编写大型网站问题集
  • 原文地址:https://www.cnblogs.com/xiangshihua/p/15007009.html
Copyright © 2011-2022 走看看