Redis缓存击穿,雪崩,穿透解决方案[亲测有效]

Redis缓存击穿,雪崩,穿透解决方案[亲测有效]缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

Redis缓存击穿,雪崩,穿透解决方案

缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

 

解决方案

有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

 

缓存雪崩

缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DBDB瞬时压力过重雪崩。

 

解决方案

缓存失效时的雪崩效应对底层系统的冲击非常可怕。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线 程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。这里分享一个简单方案就是将缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

 

缓存击穿

对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据,这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

 

解决方案

使用互斥锁(mutex key)

 

业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如RedisSETNX或者MemcacheADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

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

代码100分

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/9337.html

(0)
上一篇 2023-02-10 17:00
下一篇 2023-02-10

相关推荐

  • innodb存储方式_innodb原理

    innodb存储方式_innodb原理前言 如果你使用过mysql数据库,对它的存储引擎:innodb,一定不会感到陌生。 众所周知,在mysql8以前,默认的存储引擎是:myslam。但mysql8之后,默认的存储引擎已经变成了:inn

    2023-04-21
    107
  • mysql临时表会占用运行内存吗?_临时表空间和表空间有什么区别

    mysql临时表会占用运行内存吗?_临时表空间和表空间有什么区别都说“大隐隐于市,高手在深宫”。突如其来的“摆地摊”风潮,让原本冷清的街道热闹非凡,也让众人发现了那些神龙见首不见尾的大神们。 这不,小毛在下班的途中就遇到了大神“菊长”。一位专治数据库技术相关疑难…

    2023-03-18
    101
  • 《MySQL面试小抄》索引失效场景验证[亲测有效]

    《MySQL面试小抄》索引失效场景验证[亲测有效]面试官考点之谈谈索引维护过程?页分裂?页合并?
    面试官考点之简述一下查询时B+树索引搜索过程?
    面试官考点之什么是回表?
    面试官考点之什么是索引覆盖?使用场景?
    面试官考点之什么情况下会索引失效?

    2023-04-18
    107
  • 【12c】RMAN 与 DataGuard「终于解决」

    【12c】RMAN 与 DataGuard「终于解决」由于主库和备库的db_name相同的,只是db_unique_name不同,可以使用备库进行数据库的备份,从而减轻主库备份的负担。本篇演示DataGuard环境下RMAN工具的使用。 1 查看主库RM

    2023-03-05
    94
  • MySQL-JDBC Loadbalance深入解析[亲测有效]

    MySQL-JDBC Loadbalance深入解析[亲测有效]背景说明公司的整个电商系统搭建在华为云上,根据老总的估计,上线3个月之后日订单量会达到百万级别,保守估计3个月之后总订单个数预计会有5千万。MySQL单表达到千万级别,就会出现明显的性能问题。根据如…

    2023-04-06
    112
  • 平时常用sql_sql常用函数

    平时常用sql_sql常用函数总结一下平时用到最多的sql语句 1.特殊日期 –今天凌晨SELECT DATEADD(dd,DATEDIFF(dd,0,GETDATE()),0)–明天凌晨SELECT DATEADD(dd,D

    2022-12-27
    108
  • Mysql的学习

    Mysql的学习数据库的基本概念 1. 数据库的英文单词: DataBase 简称 : DB 2. 什么数据库? * 用于存储和管理数据的仓库。 3. 数据库的特点: 1. 持久化存储数据的。其实数据库就是一个文件系

    2023-03-20
    105
  • Python正则表达式:强大的文本匹配工具

    Python正则表达式:强大的文本匹配工具正则表达式是一种处理字符串的方法。在文本处理中,经常需要对字符串进行操作,例如字符串的匹配、替换以及删除等操作。Python中的正则表达式库re提供了一套强大的工具,能够对文本进行全面的匹配和操作。

    2024-02-23
    65

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注