Redis 典型应用——缓存(缓存预热,穿透,雪崩,击穿)

一、缓存

缓存是计算机中一个很经典的概念,核心思路是把一些常用的数据放到访问速度更快的地方,方便随时读取;

但对于计算机硬件来说,往往访问速度越快的设备,成本越高,存储空间越小,缓存是更快,但空间上是不足的,因此大部分时候,缓存只存放一些热点数据;

二、Redis 用作缓存

在一个网站中,我们经常会使用关系型数据库来存储数据(例如 MySQL),虽然关系型数据库功能强大,但是性能不高(进行一次查询操作消耗的系统资源较多),性能不高的原因体现为:

  • 数据库把数据存储在硬盘上,硬盘的 IO 速度并不快,尤其是随机访问;
  • 如果查询没有命中索引,就需要进行表的遍历,大大增加硬盘 IO 次数;
  • 关系型数据库对于 SQL 的执行会做一系列的解析,校验,优化工作;
  • 如果是一些复杂查询,如联合查询,需要进行笛卡尔积操作,效率更是降低很多;

因此,如果访问数据库的并发量比较高,就很容易使数据库服务器宕机;服务器每处理一次请求,都要消耗一定的硬件资源的(CPU,内存,硬盘,网络带宽等),当一个服务器的硬件资源被耗尽的时候,后续的请求没有资源可用,就无法处理请求,甚至导致服务器代码出现崩溃; 

让数据库能够承担更大的并发量的措施主要有以下两个思路

  • 开源:引入更多的机器,部署更多的数据库实例,构成数据库集群;
  • 节流:引入缓存,保存经常访问的热点数据,从而降低直接访问数据库的请求数量;

Redis 就是一个用来作为数据库缓存的常见方案;

Redis 访问速度比 MySQL 快很多,或者说处理同一个访问请求,Redis 消耗的系统资源比  MySQL 少很多,因此 Redis 能支持的并发量更大,并且 Redis 数据在内存中,访问内存比硬盘快很多,Redis 只是支持简单的 key-value 存储,不涉及复杂查询的那么多限制规则; 

当客户端访问业务服务器,发起查询请求,业务服务器先查询 Redis,看要查询的数据是否在 Redis 中存在,如果在 Redis 中,则就直接返回,此时就不会访问 MySQL 了,如果在 Redis 中不存在,再去查询 MySQL;

缓存是用来加快 "读操作" 的速度的,如果是 "写操作",还是要写数据库,缓存并不能提高性能;

三、缓存的更新策略

缓存中应该存储哪些数据呢?如何知道哪些数据是热点数据呢?

1. 定期生成

每隔一定的周期(比如一天/一周/一个月),对于访问的数据频次进行统计(写程序来统计),挑选出访问频次最高的前 N% 的数据,存储在缓存中;

  • 优点:实现起来较简单,过程更可控(缓存中有什么是固定,更方便排查问题);
  • 缺点:实时性较低,对于一些突然情况应对的并不好;
    • 例如:平时很少会有人搜索 "春晚",因此这个关键词就不会在缓存中,而在除夕夜时,这个词就会成为非常高频的词,导致缓存失效;

2. 实时生成

先给缓存设定容量上限(可以通过 Redis 配置文件的 maxmemory 参数设定)然后用户每次查询

  • 如果在 Redis 中查到了,就直接返回;
  • 如果在 Redis 中不存在,就从数据库中查找,如果在数据库中查到了,则将查到的结果写入 Redis,否则,说明数据库中也不存在该数据;

当缓存满了的时候(缓存容量达到上限),就会触发缓存淘汰策略,把一些 "不太热门的数据" 淘汰掉;

常见的缓存淘汰策略

  • FIFO(First In First Out)先进先出:把缓存中存在时间最久的 key(最先存的)淘汰掉;
  • LRU(Least Recently Used)淘汰最久未使用的:记录每个 key 的最近访问时间,把最近访问时间最老的 key 淘汰掉;
  • LFU(Least Frequently Used)淘汰访问次数最少的:记录每个 key 最近一段时间的访问次数,把访问次数最少的 key 淘汰掉;
  • Random 随机淘汰:从所有的 key 中随机进行淘汰;

Redis 内置的淘汰策略

volatile-lru:当内存不足以容纳新写数据时,从设置了过期时间的 key 中使 LRU(最近最少使)算法进行淘汰  ;

allkeys-lru:当内存不足以容纳新写数据时,从所有 key 中使用 LRU(最近最少使)算法进 行淘汰;

volatile-lfu 4.0 版本新增:当内存不足以容纳新写数据时,在过期的 key 中,使用 LFU 算法进行删除 key;

allkeys-lfu 4.0 版本新增:当内存不足以容纳新写数据时,从所有 key 中使用 LFU 算法进行淘汰;

volatile-random:当内存不足以容纳新写数据时,从设置了过期时间的 key 中,随机淘汰数 据;

allkeys-random:当内存不足以容纳新写数据时,从所有 key 中随机淘汰数据;

volatile-ttl:在设置了过期时间的 key 中,根据过期时间进行淘汰,越早过期的优先被淘汰;(相当于 FIFO只不过是局限于过期的 key)   ;

noeviction:默认策略,当内存不足以容纳新写数据时,新写操作会报错;

下面内容以使用 Redis 作为 MySQL 的缓存为例

四、缓存预热(Cache preheating)

1. 解释

当 Redis 刚刚启动,或者 Redis 大批 key 失效之后,此时由于 Redis 内部相当于是空着的,没啥缓存数据,那么 MySQL 就会被直接访问到,从而使 MySQL 面临较大的压力;

2. 解决办法

因此就需要提前把热点数据准备好,直接写入到 Redis 中,使 Redis 可以尽快为 MySQL 撑起保护伞,热点数据可以基于统计生成;

这份热点数据不一定非得那么 "准确",只要能帮 MySQL 抵挡大部分请求即可,随着程序运行的推移,缓存的热点数据会逐渐自动调整,来更适应当前情况;

五、缓存穿透(Cache penetration)

1. 解释

访问的 key 在 Redis 和数据库中都不存在,此时这样的 key 不会被放到缓存上,后续如果仍然在访问该 key,依然会访问到数据库,这就会导致数据库承担的请求太多,压力很大;

2. 产生原因

  • 业务设计不合理,比如缺少必要的参数校验环节,导致非法的 key 也被进行查询了;
  • 误操作不小心把部分数据从数据库上误删了;
  • 黑客恶意攻击

3. 解决办法

  • 针对数据库上也不存在的 key,也存储到 Redis 中,比如 value 就随便设成一个 "",避免后续频繁访问数据库;
  • 使用布隆过滤器(hash + bitmap)先判定 key 是否存在,再真正查询;

六、缓存雪崩(Cache avalanche)

1. 解释

短时间大量的 key 在缓存上失效,导致数据库压力骤增,甚至宕机;比如,我们在同一时间,针大量的 key 设置了相同的过期时间,那当过期时间到来时,大量的 key 就会被删除从而失效;

2. 产生原因

  • Redis 宕机;
  • Redis 上大量的 key 同时过期;

3. 解决办法

  • 部署高可用的 Redis 集群,并且完善监控报警体系;
  • 不给 key 设置过期时间,或设置过期时间时添加随机时间因子(避免同时过期);

七、缓存击穿(Cache breakdown)

1. 解释

缓存雪崩的特殊情况,针对热点 key,突然过期了,导致大量访问该 key 的请求直接访问到数据库,引起数据库宕机;

2. 解决办法

  • 基于统计的方式发现热点 key,并设置永不过期或逻辑过期;
  • 访问数据库时,使用分布式锁,限制同时请求数据库的并发数;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/864702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年【四川省安全员A证】试题及解析及四川省安全员A证模拟考试

题库来源:安全生产模拟考试一点通公众号小程序 四川省安全员A证试题及解析根据新四川省安全员A证考试大纲要求,安全生产模拟考试一点通将四川省安全员A证模拟考试试题进行汇编,组成一套四川省安全员A证全真模拟考试试题,学员可通…

前后端数据交互流程

一、前言 用户在浏览器访问一个网站时,会有前后端数据交互的过程,前后端数据交互也有几种的情况,一下就简单的来说明一下 二、原理 介绍前后端交互前先来了解一下浏览器的功能,浏览器通过渲染引擎和 JavaScript 引擎协同工作&am…

Java 判断两个日期 相差几天

// 入参 为 Date 例如 :Date1 datenew Date();long dayCount (date1.getTime() - date1.getTime()) / 86400000;

消息中间件常用命令

一、Nginx篇 1.1 启动Nginx start nginx 1.2 停止Nginx nginx.exe -s stop 1.3 清理缓存 nginx.exe -s reload 1.4 重新打开日志文件 nginx.exe -s reopen 1.5 查看Nginx版本 nginx -v 1.6 彻底停用Nginx taskkill /f /t /im nginx.exe

简明万年历编制(C语言)

简明万年历编制(C语言 ) 编制万年历的要素: 农历公历对照,显示星期,农历干支年,当年生肖,国定节假日,寒天九九,暑日三伏,入梅出梅,节气时间&#…

回调函数在异步编程中的作用与实现方式

回调函数在异步编程中的作用与实现方式 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 在计算机编程中,回调函数是指通过将函数作为参数传递给其他函数,使得该函数在特定事件…

使用 HTTPS 已成为网站的标配了

网站使用HTTPS的原因 背景:十年前,HTTPS并不普遍,但随着网络安全意识的提高,现在已成为网站标配。 网站升级到HTTPS的动机 安全问题:HTTP缺乏安全机制,易被窃取和篡改数据。例如,电信运营商劫…

剑神诀_单机架设_无需虚拟机_小白专用

前言 今天给大家带来一款单机游戏的架设:剑神诀,一键端 无需虚拟机 如今市面上的资源参差不齐,大部分的都不能运行,本人亲自测试,运行视频如下: 剑神诀 搭建教程 此游戏架设不需要安装虚拟机,…

单模光纤(SMF)市场规模不断增长 非色散位移单模光纤为其代表产品

单模光纤(SMF)市场规模不断增长 非色散位移单模光纤为其代表产品 单模光纤(SMF)指芯径为8-10微米,用于单一传输模式的光纤。单模光纤具有频带宽、芯径细、适合长距离传输、传输耗损低、抗干扰能力强、传输速度快等优势…

【java12】java12新特性之switch表达式

Java12引入了对switch语句的增强,允许在switch语句中使用表达式来代替传统的语句列表。这样可以使得代码更加简洁和易读。 switch表达式也是作为预览语言功能的第一个语言改动被引入新版Java中来的,这是一种引入新特性的测试版的方法。通过这种方式&…

MySQL实训项目——餐饮点餐系统

项目简介:餐饮点餐系统是一款为餐厅和顾客提供便捷点餐服务的在线平台。通过该系统,餐厅能够展示其菜单,顾客可以浏览菜品,并将其加入购物车或直接下单。系统还提供了订单管理功能,方便餐厅跟踪和处理顾客的订单。 1. …

IT启航:高考后的IT学习之旅与未来规划

随着高考分数的揭晓,你们即将迎来人生新的篇章。对于有志于踏入IT领域的你们来说,这个假期是开启探索之旅的绝佳时机。作为一位已经在社会大学摸爬滚打多年的牛马来说,我想从自己的经历和观察出发,给你们提供一些实质性的建议和学…

LangChain+ChatGLM基本原理及私有化部署

一、LangChain 1.作用:用于提升大型语言模型(LLMs)功能的框架,能够让大型语言模型结合外部的计算和数据源,并根据信息执行指定操作。 结合LLM大模型外部数据等,外部工具及数据等实现特定文档问答、聊天机器…

【计算机网络】传输层(作业)

1、OSI参考模型中,提供端到端的透明数据传输服务、差错控制和流量控制的层是(C)。 A. 物理层B. 网络层C. 运输层D. 会话层 2、运输层为(B)之间提供逻辑通信。 A. 主机B. 进程C. 路由器D. 操作系统 3、运输层面向连接…

开发个人OpenUI--2 环境搭建

开发个人OpenUI–2 环境搭建 2.1 环境要求 Golang 1.22 Etcd Docker Redis Mysql 2.2Docker本地开发环境搭建 这里使用 Docker Compose 来编排管理我们的容器,docker-compose.yaml: version: 3.8services:mysql:image: mysql:8.0.18container_n…

RT-Thread Studio与CubeMX联合编程之rtthread stm32h743的使用(十一)spi设备SFUD驱动的使用

我们要在rtthread studio 开发环境中建立stm32h743xih6芯片的工程。我们使用一块stm32h743及fpga的核心板完成相关实验,核心板如图: 1.建立新工程,选择相应的芯片型号及debug引脚及调试器 2.编译下载,可以看到串口打印正常 3.…

Hubstudio指纹浏览器:海外代理IP新选择,IPXProxy为何备受推崇?

许多人都会把Hubstudio指纹浏览器和代理IP进行搭配使用,为了保证网络操作的顺利进行,例如亚马逊的多账号管理。那有没有好用的海外代理IP呢,如何在Hubstudio指纹浏览器中使用代理IP呢? 下面就给大家推荐好用的一家海外IP代理&…

积鼎CFD:基于Virtualflow在溃坝洪水演进数值仿真分析

近期,多地遭受了前所未有的洪水侵袭,每一次灾害都如同警钟长鸣,提醒我们水库大坝安全的重要性,超标准暴雨的突袭让大坝的安全防线面临前所未有的考验。面对这一挑战,CFD技术可为溃坝洪水的预测与管理开辟新的路径。凭借…

cesium 实现三维无人机航拍过程实景效果

需求背景 需要实现一个动态的三维无人机航拍过程实景效果 代码开发中&#xff0c;迭代功能待续... 解决效果 cesium 实现三维无人机航拍过程实景效果 index.vue <template><div><el-button class"btn" click"start">开始</el-butt…