前言

如何有效的理解并且区分 Reids 穿透、击穿和雪崩之间的区别,一直以来都挺困扰我的。特别是穿透和击穿,过一段时间就稀里糊涂的分不清了。

为了有效的帮助笔者自己,以及拥有同样烦恼的朋友们区分这三种场景。笔者总结了一些关键词,希望大家可以和我一样通过联想的方式来区分并理解这三种场景的区别!

缓存穿透:

关键词穿过 Redis 和 数据库

当 Redis 和数据库中都没有我们想要的数据时,就需要考虑缓存穿透的问题了

下面这段逻辑大家用的会比较多:先去 Redis 中查找某资源,Redis 中查不到就去 DB 中查,DB 中查到后回写一份数据到 Redis 中。

这段逻辑正常情况下问题并不大,但是如果用户恶意重复请求资源 X,该资源在 Redis 和 DB 中都不存在。那么每次请求都会直接打到 DB 上,甚至导致物理 DB 宕机。

解决方案

1、缓存空结果

如果系统发现 Redis 及 DB 中都不存在该资源,就缓存空结果一段时间。需要注意哈,这次的失效时间不能设置的太长,否则数据的实效性会产生很大的问题。

2、用户合法性校验

对用户的请求合法性进行校验,拦截恶意重复请求

3、布隆过滤器

看到这个名词不要慌。简单来说布隆过滤器的用途就是帮助你判断某个值是否存在。

举个例子来看下:

假设我们现在有一个长度为 9 的 bit 数组,该数组的每个位置上只能保存 1 或者 0,1 标识该位置被占用,0 标识该位置未被使用。

  1. 对于 key1,我们借助三个 Hash 函数分别对其哈希运算
  2. 再将得到的这三个哈希值对 9 求模。
  3. 最后将这三个模值落入到 bit 数组上。
  4. key2、key3 按照同样的方式再处理一遍。
key值 模值
key1 1、4、6
key2 2、5、7
key3 6、8、9



最后,我们会发现这个 bit 数组里只有位置 3 还是空着的。如果此时来了一个新的 key4 通过三个Hash算法求出的哈希值为 1、2、3,我们则可以断定 key4 一定不存在。

布隆过滤器的原理还是比较简单的。这里我们需要注意,布隆过滤器可能存在一定误判的可能性,但它依然可以帮助你拦截掉大部分一定不存在的数据。

缓存击穿

关键词定点打击

试想如果所有请求对着一个 key 照死里搞,这是不是就是一种定点打击呢?

怎么理解呢?举个极端的例子:比如某某明星爆出一个惊天狠料,海量吃瓜群众同时访问微博去查看该八卦新闻,而微博 Redis 集群中数据在此刻正好过期了,那么无数的请求则直接打到了微博系统的物理 DB 上,DB 瞬间挂了。

解决方案

1、热点数据永远不过期

比如我们可以将某个 key 的缓存时间设置为 25 小时,然后后台有个 JOB 每隔 24 小时就去批量刷新一下热点数据。就可以解决这个问题了

2、使用互斥锁

容易影响吞吐量,大部分项目设置热点 key 永不过期就妥妥的了

缓存雪崩

关键词:Redis 崩了,没有数据了

这里的 Redis 崩了指的并不是 Redis 集群宕机了。而是说在某个时刻 Redis 集群中的热点 key 都失效了。

如果集群中的热点 key 在某一时刻同时失效了的话,试想海量的请求都将直接打到 DB 上,DB 可能在瞬间就被打爆了。

解决方案

1、Redis 失效时间加上随机数

Redis 失效时间加上随机数,是一种比较取巧的解决方案。在一定程度上减轻了 DB 的瞬时压力,但是这种方案也在一定程度上增加了维护的成本。

2、Redis 永不过期

实现方案在上文中简单提过了

总结

最后我们再回归到主题!

如何轻松的通过联想的方式来区分 Redis 缓存穿透、击穿、雪崩的区别
  • 缓存穿透---穿过(绕过) Redis 和 DB 来搞你

  • 缓存击穿---定点打击来搞你

  • 缓存雪崩---热点 key 在某一个时刻同时失效

如果你觉得文章写的还不错,快给笔者点个赞吧,你的鼓励是笔者创作最大的支持!!!!!!

【干货!!】三句话搞懂 Redis 缓存穿透、击穿、雪崩的更多相关文章

  1. NoSQL & Redis 介绍、缓存穿透 & 击穿 & 雪崩

    1. NoSql 简介 2. Redis 简介 2.1 Redis 的起源 2.2 缓存过期 & 缓存淘汰 3. 缓存异常 1)缓存穿透 2)缓存击穿 3)缓存雪崩 4)总结 1. NoSQL ...

  2. Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了

    Redis中几个“看似”高大上的概念,经常有人提到,某些好事者喜欢死扣概念,实战没多少,嘴巴里冒出来的全是高大上的名词,个人一向鄙视概念党,呵呵! 其实这几个概念:缓存穿透/缓存击穿/缓存雪崩,有一个 ...

  3. Redis缓存穿透和雪崩

    缓存穿透 用户想要查询一个数据 在redis缓存数据库中没有获取到 就会向后端的数据库中查询. 当用户很多 都去访问后端数据库的话,这就会给数据库带来很大的压力. 常见场景:秒杀活动 等 解决方法: ...

  4. 几句话搞懂URI、URL、URN之间的关系

    1.URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源. 2.RL是uniform resource locator,统一资源定位器,它是一种具体 ...

  5. 三句话搞定FireDAC连接池

    form上拖入: FDManager1: TFDManager; FDConnection1: TFDConnection; //初始化连接池procedure TForm1.InitDBPool;b ...

  6. 三句话看明白jdk收费吗

    对于从oracle下载的jdk8:JDK8u200(含)以下版本不收费. 对于从oracle下载的jdk11:JDK 11.0.0不收费,JDK 11.0.1不收费. 对于openjdk:免费 ——— ...

  7. Redis缓存穿透、缓存雪崩、redis并发问题 并发竞争key的解决方案 (阿里)

    阿里的人问我 缓存雪崩(大量数据在同一时间过期了)了如何处理,缓存击穿了如何处理,回答的很烂,做了总结: 把redis作为缓存使用已经是司空见惯,但是使用redis后也可能会碰到一系列的问题,尤其是数 ...

  8. redis缓存穿透穿透解决方案-布隆过滤器

    redis缓存穿透穿透解决方案-布隆过滤器 我们先来看一段代码 cache_key = "id:1" cache_value = GetValueFromRedis(cache_k ...

  9. Redis缓存穿透、缓存击穿以及缓存雪崩

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

随机推荐

  1. PHP is_writable() 函数

    定义和用法 is_writable() 函数检查指定的文件是否可写. 如果文件可写,该函数返回 TRUE. 语法 is_writable(file) 参数 描述 file 必需.规定要检查的文件. 提 ...

  2. PHP decoct() 函数

    实例 把十进制转换为八进制: <?phpecho decoct("30") . "<br>";echo decoct("10&quo ...

  3. PHP lcfirst() 函数

    实例 把 "Hello" 的首字符转换为小写.: <?php高佣联盟 www.cgewang.comecho lcfirst("Hello world!" ...

  4. 5.29 省选模拟赛 波波老师 SAM 线段树 单调队列 并查集

    LINK:波波老师 LINK:同bzoj 1396 识别子串 不过前者要求线性做法 后者可以log过.实际上前者也被我一个log给水过了. 其实不算很水 我自认跑的很快罢了. 都是求经过一个位置的最短 ...

  5. mac 教你如何在Mac上搭建自己的服务器——Nginx

    WHAT 本篇主要是基于Nginx在Mac上搭建自己的服务器. 我相信很多朋友肯定是第一次听到Nginx,关于它具有怎样的传奇,这儿肯定说不完也说不透. 有兴趣的朋友可以自行google或者baidu ...

  6. Nginx.conf参数配置详解

    Nginx的配置文件nginx.conf配置详解如下: user nginx nginx; #Nginx用户及组:用户 组.window下不指定 worker_processes 8; #工作进程:数 ...

  7. 连通图算法详解之① :Tarjan 和 Kosaraju 算法

    相关阅读: 双连通分量 ,割点和桥 简介 在阅读下列内容之前,请务必了解 图论相关概念 中的基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly ...

  8. java web应用启动报错:Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.

    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use. The serve ...

  9. java循环语句for与无限循环

    一 for循环 for循环语句是最常用的循环语句,一般用在循环次数已知的情况下. 格式: for(初始化表达式; 循环条件; 操作表达式){ 执行语句 ……… } 循环流程: for(① ; ② ; ...

  10. Qt之先用了再说系列-多线程方式1

    Qt 多线程的用法还是比较简单的,也比较好用,接下来我们就分析分析如何使用. 说起Qt 线程的使用方式,一般有2种使用方式,具体哪种比较好看自己心情了,现在有官方的推荐用法,用不用还是看你心情的 好, ...