当前位置: 首页 > news >正文

Redis 典型应用-缓存

目录

1. 什么是缓存

2. 使用 Redis 作为缓存

3. 缓存的更新策略

4. 缓存预热、缓存穿透、缓存雪和缓存击穿

4.1 缓存预热(Cache preheating)

4.2 缓存穿透(Cache penetration)

4.3 缓存雪崩(Cache avalanche)

4.4 缓存击穿(Cache breakdown)


1. 什么是缓存

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

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

2. 使用 Redis 作为缓存

我们经常会使用关系型数据库 MySQL 来存储数据,关系型数据库虽然强大,但是有一个很大的缺陷,就是性能不高,也就是一次查询操作消耗的系统资源较多

关系型数据库性能不高的原因:

1)数据库把数据存储在硬盘上,硬盘的 IO 速度并不快,尤其是随机访问

2)如果查询不能命中索引,就需要进行表的遍历,这就会大大增加硬盘 IO 次数

3)关系型数据库对于 SQL 的执行会做⼀系列的解析,校验,优化⼯作
4)如果是⼀些复杂查询,比如联合查询,需要进行笛卡尔积操作,效率更是降低很多

因此,如果访问数据的并发量比较高,对于数据库的压力是非常大的,就很容易使数据库服务器宕机,要想使数据库能够承担更大的并发量,核心思路主要有两个

1)开源:引入更多的机器,部署更多的数据库实例,构成数据库集群

2)节流:引入缓存,使用其他方式保存经常访问的热点数据,从而降低直接访问数据库的请求数量

其中 Redis 就是一个用来作为数据库缓存的常见方案,因为 Redis 访问的速度要比 MySQL 快很多,Redis 消耗的系统资源比 MySQL 少很多,因此 Redis 能支持的并发量更大

Redis 数据存储在内存中,访问内存比访问硬盘快很多

Redis 只是支持简单的 key-value 存储,不涉及复杂查询的规则限制

客户端访问业务服务器,发起查询操作,业务服务器先查询 Redis,如果要查询的数据在 Redis 中,直接返回,不必再查询 MySQL,如果不在,再查询 MySQL

只需要在 Redis 中放入 20% 的热点数据,就可以使 80% 的请求不在真正查询数据库了,大大缓解了数据库的压力

3. 缓存的更新策略

哪些数据被称为热点数据

1)定期生成

每个一定的周期(1 天/ 1 周),对于访问的数据进行频次统计,挑选出访问频次最高的前 N%的数据

2)实时生成

献给缓存设定容量上限,接下来每次查询,如果在 Redis 中就直接返回,如果不在就从数据库中查询,把查到的结果同时写入 Redis 中,如果缓存已经满了,就触发缓存淘汰策略,把一些相对不热门的数据淘汰掉,按照这种方式,持续一段时间之后 Redis 内部的数据自认就是热点数据了

通用的淘汰策略主要有以下几种:

1)FIFO(First In First Out)先进先出

把缓存中存在时间最久的(也就是先来的数据)淘汰掉

2)LRU (Least Recently Used)淘汰最久未使用的

记录每个 key 的最近访问时间,把最近访问时间最老的 key 淘汰掉

3)LFU (Least Frequently Used)淘汰访问次数最少的

记录每个 key 最近一段时间的访问次数,把访问次数最少的淘汰掉

4)Random 随机淘汰

从所有 key 中随机淘汰一个

Redis 内置的淘汰策略

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

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

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

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

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

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

7)volatile-ttl 在设置了过期时间的 key 中,根据过期时间进行淘汰,越早过期的优先被淘汰

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

4. 缓存预热、缓存穿透、缓存雪和缓存击穿

4.1 缓存预热(Cache preheating)

缓存中的数据:

1)定时生成,不涉及缓存预热

2)实时生成,涉及缓存预热

在 Redis 服务器首次连接之后,服务器是没有数据的,客户端先查询 redis,没有查到就在查 mysql,然后把数据写入到 redis 中,此时所有的请求都会访问 mysql,mysql 的压力并没有减小

缓存预热就是把定期生成和实时生成结合起来,先通过离线的方式,通过一些统计的途径,先把热点数据找到一批导入 redis 中,此时导入的热点数据就能够帮 mysql 承担很大的压力,随着时间的推移,逐渐使用新的热点数据淘汰掉旧的数据

4.2 缓存穿透(Cache penetration)

当访问的 key 在 Redis 和 mysql 中都不存在,此时的 key 就不会放到缓存中,后续如果继续访问这个 key,依然会访问到数据库,就会导致数据库一致承担很大的压力,这种情况被称为缓存穿透

产生的原因:

1)业务设计不合理,比如缺少必要的参数校验环节,导致非法的 key 也被进行查询了

2)不小心把部分数据从数据库上误删了

3)黑客恶意攻击

解决:

1)针对要查询的参数进行严格的合法性校验

2)针对数据库上也不存在的 key,也存储到 redis 中,设置其 value 为一个" ",避免后续频繁访问数据库

3)使用布隆过滤器先判定 key 是否存在,在真正查询

4.3 缓存雪崩(Cache avalanche)

短时间内大量的 key 在缓存上失效,导致数据库压力骤增,甚至出现宕机

产生原因:

1)Redis 挂了,导致 redis 集群模式下大量节点宕机

2)Redis 上的大量 key 同时过期

解决:

1)加强监控报警,加强 redis 集群的可用性保证

2)不给 key 设置过期时间 / 设置过期时间时添加随机因子(避免有很多 key 同一时刻过期)

4.4 缓存击穿(Cache breakdown)

相当于缓存雪崩的特殊情况,针对热点 key 突然过期了,导致大量的请求直接访问在数据库上,甚至直接引起数据库宕机

解决:

1)基于统计的方式发现热点 key,并设置永不过期

2)进行必要的服务降级,例如访问数据库的时候使用分布式锁,限制同时请求数据库的并发数

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Phalco安装过程以及踩的一些坑(mac环境)
  • 直播狂欢下的隐忧|专题报告集
  • 深入解读人工水母算法:原理、实现与应用
  • 鸿蒙开发所有装饰器
  • C++|设计模式(七)|⭐️观察者模式与发布/订阅模式,你分得清楚吗
  • 2024河南萌新联赛第(三)场 河南大学
  • 自闭症儿童上普校真的好吗
  • 基于boost asio实现的定时器
  • C++后端开发找了一个MFC桌面开发的实习(已投降)
  • 【软件设计书】详细设计说明书和概要设计说明书(Word原件直接套用)
  • idea的git与SVN切换
  • 前端初期知识点回顾
  • 运行pytorch自带的单元测试
  • MySQL:ORDER BY 排序查询
  • BEVGPT展示自动驾驶的“全知视角”,预测决策规划三合一的革新之作!
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • Angular 响应式表单 基础例子
  • JavaScript服务器推送技术之 WebSocket
  • JavaScript类型识别
  • jquery cookie
  • js ES6 求数组的交集,并集,还有差集
  • JS实现简单的MVC模式开发小游戏
  • October CMS - 快速入门 9 Images And Galleries
  • PhantomJS 安装
  • React组件设计模式(一)
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 从0到1:PostCSS 插件开发最佳实践
  • 机器学习中为什么要做归一化normalization
  • 区块链将重新定义世界
  • 数据科学 第 3 章 11 字符串处理
  • 原生Ajax
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 白色的风信子
  • postgresql行列转换函数
  • #、%和$符号在OGNL表达式中经常出现
  • (1)Jupyter Notebook 下载及安装
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (c语言)strcpy函数用法
  • (八)Spring源码解析:Spring MVC
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (译) 函数式 JS #1:简介
  • (转)四层和七层负载均衡的区别
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET MVC之AOP
  • .NET Project Open Day(2011.11.13)
  • .Net程序帮助文档制作
  • .NET的数据绑定
  • .NET企业级应用架构设计系列之技术选型
  • /etc/sudoers (root权限管理)
  • @Autowired 和 @Resource 区别的补充说明与示例