Redis基础知识(三):缓存穿透、缓存击穿、缓存雪崩

2023-11-17


 我们在项目中大量使用Redis承接海量数据的冲击,但是使用过程中也会遇到一些特殊的情况,这个就是缓存击穿、缓存穿透、缓存雪崩。

一、缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。
即:缓存无数据,数据库也无数据

出现过程

假如客户端每秒发送5000个请求,其中4000个为黑客的恶意攻击,即在数据库中也查不到。举个例子,用户id为正数,黑客构造的用户id为负数,如果黑客每秒一直发送这4000个请求,缓存就不起作用,数据库也很快被打死。

在这里插入图片描述

解决方法

对请求参数进行校验,不合理直接返回
查询不到的数据也放到缓存,value为空,如 set -999
使用布隆过滤器,快速判断key是否在数据库中存在,不存在直接返回

第一种是最基本的策略,第二种其实并不常用,第三种比较常用。

为什么第二种并不常用呢?

因为如果黑客构造的请求id是随机数,第二种并不能起作用,反而由于缓存的清空策略,(例如清除最近没有被访问的缓存)导致有用的缓存被清除了。

二、缓存击穿

缓存击穿就是当请求参数过来,缓存中的数据瞬间过期,此时并发量又大,全部请求直接同时转为去请求数据库,瞬间给数据库带来巨大压力。
即:缓存无数据,数据库有数据,key比较集中

出现过程

设置了过期时间的key,承载着高并发,是一种热点数据。从这个key过期到重新从MySQL加载数据放到缓存的一段时间,大量的请求有可能把数据库打死。缓存雪崩是指大量缓存失效,缓存击穿是指热点数据的缓存失效。

解决方法

设置key永远不过期,或者快过期时,通过另一个异步线程重新设置key
当从缓存拿到的数据为null,重新从数据库加载数据的过程上锁,下面写个分布式锁实现的demo

三、缓存雪崩

缓存雪崩是指缓存中数据大批量同时到过期时间。
即:缓存无数据,数据库有数据,key比较分散

和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

出现过程

假设有如下一个系统,高峰期请求为5000次/秒,4000次走了缓存,只有1000次落到了数据库上,数据库每秒1000的并发是一个正常的指标,完全可以正常工作,但如果缓存宕机了,或者缓存设置了相同的过期时间,导致缓存在同一时刻同时失效,每秒5000次的请求会全部落到数据库上,数据库立马就死掉了,因为数据库一秒最多抗2000个请求,如果DBA重启数据库,立马又会被新的请求打死了,这就是缓存雪崩。
在这里插入图片描述

解决方法

事前:redis高可用,主从+哨兵,redis cluster,避免全盘崩溃
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL被打死
事后:redis持久化RDB+AOF,快速恢复缓存数据
缓存的失效时间设置为随机值,避免同时失效

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis基础知识(三):缓存穿透、缓存击穿、缓存雪崩 的相关文章

  • Redis发布/订阅:查看当前订阅了哪些频道

    我目前有兴趣查看我拥有的 Redis 发布 订阅应用程序中订阅了哪些频道 当客户端连接到我们的服务器时 我们将它们注册到如下所示的通道 user user id 这样做的原因是我希望能够看到谁 在线 目前 我在不知道客户端是否在线的情况下盲
  • 为什么 Redis TimeSeries 不捕获聚合中的最后一个元素?

    我试图了解 Redis 的时间序列规则创建的工作原理 但我很困惑为什么 Redis 会忽略聚合中的最后一项 并想知道这是否是预期的行为 我在中创建了示例代码redis cli为了显示 127 0 0 1 6379 gt FLUSHALL O
  • StackExchange.Redis Get 函数抛出 TimeoutException

    我在用着StackExchange Redis与 C 和StackExchangeRedisCacheClient Get函数抛出以下异常 myCacheClient Database StringGet txtKey Text myCac
  • 为什么Redis中没有有序的hashmap?

    Redis 数据类型 http redis io topics data types包括排序集 http redis io topics data types intro sorted sets以及其他用于键值存储的必要数据结构 但我想知道
  • 使用redis进行树形数据结构

    我需要为基于树的键值开发一个缓存系统 与Windows注册表编辑器非常相似 其中缓存键是字符串 表示树中到值的路径 可以是原始类型 int string bool double 等 或子树本身 例如 key root x y z w val
  • Laravel 异常队列最大尝试次数超出

    我创建了一个应用程序来向多个用户发送电子邮件 但在处理大量收件人时遇到问题 该错误出现在failed jobs table Illuminate Queue MaxAttemptsExceededException App Jobs ESe
  • 节点应用程序之间共享会话?

    我目前有两个独立的节点应用程序在两个不同的端口上运行 但共享相同的后端数据存储 我需要在两个应用程序之间共享用户会话 以便当用户通过一个应用程序登录时 他们的会话可用 并且他们似乎已登录到另一个应用程序 在本例中 它是一个面向公众的网站和一
  • 在 Spring 4 中干掉通用的 RedisTemplate

    我读到你可以拥有 Autowired从 Spring 4 开始泛型 这太棒了 我有一个摘要RedisService我想参加的课程 Autowired一个通用的 RestTemplate 如下所示 public abstract class
  • 如何配置Lettuce Redis集群异步连接池

    我正在配置我的生菜重新分配池 当我按照官方文档配置时 连接池无法正常初始化 无法获取连接 官方文档指出 RedisClusterClient clusterClient RedisClusterClient create RedisURI
  • Redis 中存储整数和字符串的区别

    这两个命令有什么区别吗 LPUSH myset 123 LPUSH myset 123 我想存储大约 500 万个整数 并且我想以最有效的方式做到这一点 不 没有什么区别 两者都存储为字符串 从redis io http redis io
  • Web API 缓存 - 如何使用分布式缓存实现失效

    我有一个 API 目前不使用任何缓存 我确实有一个正在使用的中间件 它可以生成缓存标头 Cache Control Expires ETag Last Modified 使用https github com KevinDockx HttpC
  • 集合成员的 TTL

    Redis 是否可以不为特定键而是为集合的成员设置 TTL 生存时间 我正在使用 Redis 文档提出的标签结构 数据是简单的键值对 标签是包含与每个标签对应的键的集合 例如 gt SETEX id id 1 100 Lorem ipsum
  • Redis 是否使用用户名进行身份验证?

    我已经在我的环境中设置了Redis 并且只看到了通过密码授权的部分 有没有办法也设置用户名 还是只能通过密码验证 Redis 6 上有 ACL 这些都有一个用户名 查看https redis io topics acl https redi
  • nginx/uwsgi 服务器的持久内存中 Python 对象

    我怀疑这是否可能 但这是问题和提出的解决方案 提出的解决方案的可行性是这个问题的对象 我有一些需要可用于所有请求的 全局数据 我将这些数据保存到 Riak 并使用 Redis 作为缓存层以提高访问速度 目前 数据被分为约 30 个逻辑块 每
  • 使用通配符查找键

    我已经使用分号保存了数据 redis gt keys party 1 party congress president 2 party bjp president 3 party bjp 4 party sena 是否有任何命令可以列出所有
  • redis.exceptions.ConnectionError:连接到本地主机时出现错误-2:6379。名称或服务未知

    当我在服务器中运行代码时出现此错误 我的环境是 debian 并且Python2 7 3 Traceback most recent call last File fetcher py line 4 in
  • Redis 客户端忽略其上设置的配置选项并尝试连接到默认 IP 127.0.01

    在AWS中 我使用ElastiCache Redis服务器并使用节点作为后端和 promise redis 包 这就是我尝试连接到我的 redis 服务器端点的方法 client redis createClient host my red
  • Microsoft.Extensions.Caching.Redis 选择与 db0 不同的数据库

    一个关于了解使用哪个redis数据库以及如何配置它的问题 我有一个默认值ASP NET Core Web 应用程序和默认配置的本地redis服务器 含15个数据库 通过包管理控制台我已经安装了 Install Package Microso
  • Redis如何存储关联数组?设置、散列还是列表?

    我对 Redis 的所有可用存储选项有点困惑 我想做一些简单的事情 并且不想过度设计它 我正在与phpredis and Redis v2 8 6 我有一个需要存储的简单关联数组 我还需要能够通过其键检索项目并循环遍历所有项目 a arra
  • 如何在Redis中存储聚合目录树搜索结果

    我有一个很大的产品目录树 目前包含约 36000 个类别和约 100 万个产品 即叶子 它的结构如下 最大深度为 5 Cat1 Cat11 Cat111 Cat1111 Product1 Cat1112 Product1 Cat1113 P

随机推荐

  • Python 异常处理指南

    异常处理是编写健壮的 Python 程序时不可或缺的一部分 当程序运行中发生错误时 异常处理机制可以捕获并处理这些错误 从而保证程序的稳定性和可靠性 本文将为您介绍 Python 中的异常处理机制 并提供一些常见的异常处理技巧和示例代码 异
  • git init报错:‘git‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

    背景 已经安装git 但是使用命令行git init的时候 报错 git 不是内部或外部命令 也不是可运行的程序 或批处理文件 原因 因为没有成功配置环境变量 所以我们要手动添加一个环境变量 解决方法 1 在桌面找到此电脑 右键 选择 属性
  • 并发控制五(封锁的粒度)

    封锁对象的大小称为封锁粒度 封锁对象可以是逻辑单元 也可以是物理单元 以关系数据库为例 封锁对象可以是这样一些逻辑单元 属性值 属性值的集合 元组 关系 索引项 整个索引直至整个数据库 也可以是这样一些物理单元 页 数据页或索引页 物理记录
  • CentOS7安装部署wordpress

    环境介绍 CentOS7 3安装部署wordpress 本环境主机运行在阿里云 部署方式为单节点部署 主机配置 系统 CentOS7 3 mini CPU 1核 内存 1GB 硬盘 60G 外网带宽 1Mbs 一 配置主机名 root lo
  • mysql explain ref const_MySQL EXPLAIN 详解

    一 介绍 EXPLAIN 命令用于SQL语句的查询执行计划 这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的 这条命令并没有提供任何调整建议 但它能够提供重要的信息帮助你做出调优决策 先解析一条sql语句 你可以看
  • pytorch 实现LSTM

    Pytorch基础知识点整理 梯度 下降 coding utf 8 from math import pi import torch import torch optim x torch tensor pi 3 pi 6 requires
  • js数组不同类型元素去重

  • Ubuntu 16.04 服务器安装 hadoop3.1.2

    1 事前准备 1 相关配置信息 仅供参考 ubuntu版本为16 04服务器版 服务器配置为1核2GB hadoop版本我选择hadoop3 1 2 2 相关资源获取 服务器可选择国内的腾讯云和阿里云 也可以选择华为云 任君喜好 系统的话在
  • 校园社区app

    此项目是面向在校大学生开发的一个集预约购物 组织活动 实事热帖于一体的社区app 前后台交互数据采用的是json数据格式 网络请求采用的是volley 后台采用mysql数据库 如果有写的不好的地方还望大家指正 主要功能为 预约购物 组织活
  • DataGrip 2022.2.2 Unknown column ‘generation_expression‘ in ‘field list‘

    安装DataGrip 2022 2 2 连接本地数据库 编写脚本时发现无法自动提示数据库表字段 搜索结果 都是在连接属性 Options Introspection using JDBC metadata 在此版本没有发现此选项 查找发现在
  • undefined、null、isNan

    null 和 undefined的区别 在用法上几乎没有区别 if undefined console log undefined is false undefined is false if null console log null i
  • [电动智能汽车-7]:汽车CAN总线详解

    目录 第1章 CAN总线概述 1 1 概述 1 2 发展历史 1 3 标准化 1 4 底层标准 1 5 上层标准 1 6 总线特点 1 7 CAN总线分类 1 8 应用 1 9 局限性 第2章 电路基础 2 1 硬件拓扑 2 2 收发器 2
  • 【微信小程序】小程序点击图片放大(图片预览)

    这个强大的API wx previewImage 嘿嘿嘿 接下来我们来讲一下微信小程序中图片点击放大预览的实现步骤 思路 1 点击事件 2 放大 3 左右滑动查看上 下一张 在绑定点击事件的时候我们需要同时获取到点击图片的url和这一组数据
  • linux 信号传递参数,Qt 信号槽如何传递参数(或带参数的信号槽)

    信号槽如何传递参数 或带参数的信号槽 利用Qt进行程序开发时 有时需要信号槽来完成参数传递 带参数的信号槽在使用时 有几点需要注意的地方 下面结合实例进行介绍 第一点 当信号与槽函数的参数数量相同时 它们参数类型要完全一致 signals
  • 不死神兔详细解释及解题,看不懂算我输

    不死神兔 不死神兔也叫做斐波那契数列或者叫做黄金分割数列或者叫做兔子数列 不死神兔问题 有1对兔子 从出生后的第3个月起每个月都生一对兔子 小兔子长到第三个月后每个月 又生一对兔子 假如兔子都不死 问第n个月有几对兔子 需求 我们这里需要知
  • JDBC工具类封装

    jdbc工具类的封装 package com hyc study02 utils import java io InputStream import java sql import java util Properties public c
  • 数字化和物联网的发展如何改变我们的生活方式?

    数字化和物联网 IoT 的发展已经给我们的生活方式带来了重大变化 而且这些变革将在未来继续发生 以下是数字化和物联网影响我们生活的一些方式 连接设备和智能家居 物联网使日常物品能够连接到互联网并相互通信 这种连通性允许创建智能家居 其中可以
  • SpringBoot学习---yaml配置

    本篇博客目录 一 什么是yaml 二 yaml基础语法与数据类型 1 yaml基础语法 2 数据类型 1 对象类型 2 数组类型 3 复合结构 4 纯量类型 5 引用 三 yaml注入配置文件 1 yaml配置注入到实体类 2 yaml加载
  • Linux 维护日志:今日系统宕机,问题记录

    查看日志 显示包含如下信息 Jul 21 10 55 10 EYKERP1 kernel sd 3 0 0 0 SCSI error return code 0x00010000 Jul 21 10 55 10 EYKERP1 kernel
  • Redis基础知识(三):缓存穿透、缓存击穿、缓存雪崩

    文章目录 一 缓存穿透 出现过程 解决方法 二 缓存击穿 出现过程 解决方法 三 缓存雪崩 出现过程 解决方法 我们在项目中大量使用Redis承接海量数据的冲击 但是使用过程中也会遇到一些特殊的情况 这个就是缓存击穿 缓存穿透 缓存雪崩 一