Redis缓存哪些事儿
一提到Redis缓存,我们不得不了解的三个问题就是:缓存雪崩、缓存击穿和缓存穿透。这三个问题一旦发生,会导致大量的请求直接请求到数据库层。如果并发压力大,就会导致数据库崩溃。那p0级的故障是没跑了。
今天我们就来详细的了解这个三个问题诱因以及如何解决。没有点关注,记得先点个关注吧。 废话不多说,我们直接开搞!!!
一、缓存雪崩
什么是缓存雪崩?缓存雪崩就是大量请求无法在redis缓存中进行处理,而是直接发送到了数据库层,使得数据库压力陡增。就好像redis一下子突然失效了一样。一般造成缓存雪崩主要有两个原因,我们来一一分析一下。
1.缓存中大量数据同时过期
缓存中大量数据同时过期,就会导致大量请求无法在redis缓存层面进行处理。具体来说,就是给redis中大量数据设置了相同的过期时间,一旦它们同时失效,应用就会把请求直接发送给数据库,直接从数据库中读取数据。如果应用的并发量很大,那数据库的压力就会很大。如下图所示:
针对大量数据同时失效带来的缓存雪崩问题,我们一般采取以下两种解决方案。 (1)我们在开发过程中要避免给大量数据设置相同的过期时间。我们可以在给数据设置过期时间时给时间加一个很小的随机数,这样不同数据的过期时间就会有所差别,但差别也不会太大,保证数据在一定范围内过期,从而满足业务层要求同时过期的需要。 (2)服务降级。所谓的服务降级,是指发生缓存雪崩后,针对不同的数据采取不同的策略。
- 当业务访问非核心数据时(例如商品属性信息),我们直接返回预定义的信息。
- 当业务访问的是如库存数据等核心数据时,仍然允许查询缓存,如果缓存缺失,也可以从数据库中继续读取。
这样一来,只有部分过期的数据会访问数据库,所以数据库压力就没那么大。
2.Redis实例发生故障
当Redis实例发生故障,那就相当于缓存已经废掉了,所以大量请求会直接请求数据库,造成数据库压力变大,甚至宕机。针对这种情况发生的缓存雪崩,我们有以下两种处理方式。 (1)在业务系统侧实现服务熔断或请求限流机制 所谓的服务熔断,就是指在发生缓存雪崩时,为了防止大流量直接打到数据库,我们会暂停对缓存系统的访问。当上层应用访问缓存时,缓存接口不会去访问Redis实例,而是直接返回。等redis恢复后,再允许应用程序请求缓存系统。这样就会避免因为redis缓存宕机,导致数据库压力陡增的情况。
服务熔断虽然可以保证数据库不被崩溃,但是暂停了整个服务的访问,对业务的影响范围大,为了减小对上层服务的影响,我们一般采用请求限流。请求限流是指业务系统去控制每秒进入系统的请求数,避免过多的请求被发送到数据库。比如正常运行时,业务系统每秒进入的请求是1万个,其中有80%在缓存中就可以处理了,有20%会去数据库中处理。一旦发生缓存雪崩,100%的流量就会请求数据库,为了不造成数据库崩溃,我们就可以启动请求限流机制。业务系统只允许30%的流量进入,而70%的流量被拒绝服务。这也是目前主流大厂常用的方法,比如在某个明星爆出大瓜后,我们刷微博经常刷不出来,多刷几次就能进入,那就是因为做了服务降级。只允许一部分流量进入。
(2)使用高可靠集群
我们可以通过主从节点来部署高可靠的Redis集群。当主节点挂掉后,从节点还可以切换成主节点。
二、缓存击穿
缓存击穿是指针对某个热点数据,无法在缓存中进行处理,然后访问该数据的大量请求,一下子都发到后端数据库中,导致数据库压力激增。对于缓存击穿的情况,经常发生在热点数据过期失效时。
为了避免这种情况发生,最常采取的措施就是对于访问特别频繁的热点数据,我们就不设置过期时间了。这样一来,对热点数据的访问,都可以在缓存中进行。
三、缓存穿透
缓存穿透是指要访问的数据既不在缓存中,也不在数据库中,会导致请求缓存时,发生缓存缺失,然后请求数据库,发现数据库中也没有需要的数据。这样一来,缓存就成了“摆设”,如果有大量的这种请求,就会给数据库带来很大的压力。
这个问题一般都是黑客进行恶意攻击造成的。为了避免这种问题发生,我们有三种解决方式。
1、缓存空值或者缺省值
一旦发生缓存穿透,我们就可以在redis中设置一个空值或者给定的某个缺省值。这样,业务应用的后续这种请求,都可以命中缓存。这样就避免了把大量请求发送给数据库了。
2、使用布隆过滤器来快速判断数据是否存在
这里我们先来解释一下什么是布隆过滤器。
布隆过滤器由一个初值都为0的bit数组和N个哈希函数组成,可以用来快速判断某个数据是否存在。当我们想标记某个数据存在时,布隆过滤器会通过三个操作来完成标记:
- 首先,使用N个哈希函数,分别计算数据的哈希值,得到N个哈希值。
- 然后把这N个哈希值对bit数组的长度取模,得到每个哈希值在数组中的位置。
- 最后,我们把对应位置的bit位设置为1,这样就完成了布隆过滤器中标记数据的操作。
如果数据不存在,也就是我们没有用布隆过滤器标记过,bit数组对应的bit位为0。 当我们需要判断某个数据是否存在时,我们就执行上面的计算过程,我们先求出这个数据对应的hash值,然后取模,然后去bit数组查这N个位置上的bit值。只要这N个bit值有一个不为1,就表明这个数据没有被标记过。 基于布隆过滤器的快速检测特性,我们可以把数据写入数据库时,使用布隆过滤器做个标记,当缓存失效后,上层应用查询数据库时,可以通过查询布隆过滤器快速判断数据是否存在。如果不存在,就不用在去数据库中去查了。这样一来,即使发生缓存穿透,也不会对数据库造成压力。
3、业务层对请求进行检测
缓存穿透发生的原因主要就是恶意请求访问不存在的数据,所以业务层接受到请求后,一定要进行合法性检测,把恶意请求给过滤掉,这样就可以避免缓存穿透的问题了。
今天我们就聊到这里,如果感兴趣,记得关注一波哦。

Redis缓存哪些事儿的更多相关文章
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十四)Redis缓存正确的使用姿势
作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 简介 这是一篇关于Redis使用的总结类型文章,会先简单的谈一下缓存 ...
- 如约而至,Java 10 正式发布! Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十四)Redis缓存正确的使用姿势 努力的孩子运气不会太差,跌宕的人生定当更加精彩 优先队列详解(转载)
如约而至,Java 10 正式发布! 3 月 20 日,Oracle 宣布 Java 10 正式发布. 官方已提供下载:http://www.oracle.com/technetwork/java ...
- 缓存工厂之Redis缓存
这几天没有按照计划分享技术博文,主要是去医院了,这里一想到在医院经历的种种,我真的有话要说:医院里的医务人员曾经被吹捧为美丽+和蔼+可亲的天使,在经受5天左右相互接触后不得不让感慨:遇见的有些人员在挂 ...
- Windows下Redis缓存服务器的使用 .NET StackExchange.Redis Redis Desktop Manager
Redis缓存服务器是一款key/value数据库,读110000次/s,写81000次/s,因为是内存操作所以速度飞快,常见用法是存用户token.短信验证码等 官网显示Redis本身并没有Wind ...
- 总结:如何使用redis缓存加索引处理数据库百万级并发
前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1000万条数据,可以参考我之前的文章插入数据, ...
- .NET基于Redis缓存实现单点登录SSO的解决方案[转]
一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...
- Redis缓存连接池管理
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.util.Assert;import ...
- ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存
基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...
- Windows Azure Redis 缓存服务
8月20日,Windows Azure (中国版)开始提供Redis缓存服务,比较国际版的Microsoft Azure晚了差不多一年的时间.说实话,微软真不应该将这个重要的功能delay这么长时间, ...
随机推荐
- 16、如何将安装在chrome上的插件(扩展程序)打包成".crx"文件
1.打开扩展程序: 2.打开开发者模式并选择要打包的插件: 3.打包扩展程序: (1) (2) (3)
- Dubbo:dubbo管理界面安装
首先需要Tomcat.Zookeeper安装后在进行安装Dubbo管理界面 提供Dubbo-admin管理界面war包: https://github.com/zhaoyue123ABC/Publi ...
- CentOS查看和修改PATH环境变量的方法 (转)
查看PATH:echo $PATH以添加mongodb server为列修改方法一:export PATH=/usr/local/mongodb/bin:$PATH//配置完后可以通过echo $ ...
- C# 8.0和.NET Core 3.0高级编程 分享笔记一:C#8.0与NET Core 3.0入门
在学习C#相关知识的过程中,我们使用Visual Studio Code来入门整个C#. 一.安装Visual Studio Core环境 通过https://code.visualstudio.co ...
- C语言:赋值
#include <stdio.h> //=赋值运算符 //具有方向性,只能将赋值号右边的表达式的值给左边的变量 //赋值语句具有计算功能,赋值号右边可以是常量,变量或表达式都可以 //赋 ...
- 高校表白App-团队冲刺第二天
今天要做什么 今天要把昨天的activity进行完善,并且加上计时跳转的功能,将其设置为主页面,设置两种跳转功能. 遇到的问题 今天没遇到什么大的问题,只是在进行编写的时候,又出现了R文件无法找到的情 ...
- SLAM的数学基础(1):什么是方差,有什么意义?
小红班上有两组同学的数学考试分数为: 第一组:小红:100分,小明:60分,小宇:20分 第二组:小蓝:70分,小华:60分,小杰:50分 那么很容易算出,第一组的平均分是60分,第二组的平均分也是6 ...
- 【LeetCode】974. 和可被 K 整除的子数组
974. 和可被 K 整除的子数组 知识点:数组:前缀和: 题目描述 给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续.非空)子数组的数目. 示例 输入:A = [4,5,0,-2,-3, ...
- bash shell 遍历一个数组
var[@] 数组的一个元素 var=("first" "second" "three") for str in ${var[@]}; d ...
- python + pytest基本使用方法(参数化)
import pytestimport math#pytest 参数化#'base,exponent,expected'用来定义参数的名称.# 通过数组定义参数时,每一个元组都是一条测试用例使用的测试 ...