[Redis][典型运用][缓存]详细讲解

news2024/11/17 21:35:33

目录

  • 0.什么是缓存?
  • 1.使用Redis作为缓存
    • 1.为什么用?
    • 2.如何用?
  • 2.缓存的更新策略
    • 0.前言
    • 1.定期生成
    • 2.实时生成
  • 3.缓存相关问题
    • 1.缓存预热(Cache Preheating)
    • 2.缓存穿透(Cache Penetration)
    • 3.缓存雪崩(Cache Avalanche)
    • 4.缓存击穿(Cache Breakdown)


0.什么是缓存?

  • 缓存核心思路:把⼀些常⽤的数据放到触⼿可及(访问速度更快)的地⽅,⽅便随时读取
  • 缓存是更快,但是空间上往往是不足的,因此大部分时候,缓存只放一些(热点数据)
  • 二八定律:20%的热点数据,能够应对80%的访问场景

1.使用Redis作为缓存

1.为什么用?

  • 关系型数据库虽然功能强⼤,但是有⼀个很⼤的缺陷:性能不⾼
    • 换⽽⾔之,进⾏⼀次查询操作消耗的系统资源较多
  • 为什么说关系型数据库性能不高?
    • 硬件层面
      • 数据库把数据存储在硬盘上,硬盘的IO速度并不快,尤其是随机访问
      • 如果查询不能命中索引,就需要进⾏表的遍历,这就会⼤⼤增加硬盘IO次数
    • 软件层面
      • 关系型数据库对于SQL的执⾏会做⼀系列的解析,校验,优化⼯作
      • 如果是⼀些复杂查询,⽐如联合查询,需要进⾏笛卡尔积操作,效率更是降低很多
  • 因此,如果访问数据库的并发量比较高,对于数据库的压力是很大的,很容易就会使数据库服务器宕机
  • 如何让数据库能够承担更大的并发量呢?
    • 开源:引入更多的机器,部署更多的数据库实例,构成数据库集群(主从复制,分库分表等)
    • 节流:引入缓存,使用其他的方式保存经常访问的热点数据,从而降低直接访问数据库的请求数量
    • 实际开发中,两种方案往往会搭配使用
  • Redis就是一个用来作为数据库缓存的常见方案
  • Redis访问速度比MySQL快很多,或者说处理同一个访问请求,Redis消耗的系统资源比MySQL少很多,因此Redis能支持的并发量更大
    • Redis数据在内存中,访问内存比硬盘快很多
    • Redis只是支持简单的key-value存储,不涉及复杂查询的那么多限制规则

2.如何用?

  • Redis像一个"护盾"一样,把MySQL给罩住了

    • 客户端访问业务服务器,发起查询请求
    • 业务服务器先查询Redis,看想要的数据是否在Redis中存在
      • 如果已经在Redis中存在了,就直接返回,此时不必访问MySQL了
      • 如果在Redis中存在,再查询MySQL
        请添加图片描述
  • 根据"二八定律",只需要在Redis中放20%的热点数据,就可以使80%的请求不再真正查询数据库了,虽然业务场景可能不同,但是至少绝大多数情况下,使用缓存都能够大大提升整体的访问效率,降低数据库的压力

  • 注意

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

2.缓存的更新策略

0.前言

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

1.定期生成

  • 每隔⼀定的周期(⽐如⼀天/⼀周/⼀个⽉),对于访问的数据频次进⾏统计,挑选出访问频次最⾼的前N%的数据
    • 把访问的数据,以日志的形式记录下来
    • 数据量非常大,通常写个程序来统计
  • 这种做法实时性较低,对于一些突然情况应对的并不好
    • 例如:春节期间,春晚这样的词会成为高频词,但是平常则很少会有人搜索
  • 一般性的操作流程?
    • 写一套离线的流程,通过定时任务触发
      • 完成统计热词的过程
      • 根据热词,找到数据
      • 把得到的缓存数据同步到缓存服务器上
      • 控制这些缓存服务器自动重启
  • 优点:上述过程,实际上实现比较简单,过程更可控,方便排查问题
  • 缺点:实时性不够,如果出现一些突发性事件,有一些本不是热词的内容,成了热词,新的热词就可能给后面的数据库啥的带来较大压力

2.实时生成

  • 先给缓存设定容量上限(通过Redis配置⽂件的maxmemory参数设定)
  • 流程
    • 用户的每次查询
      • 如果在Redis中查到了,就直接返回
      • 如果在Redis中不存在,就从数据库查,把查到的结果同时也写入Redis
    • 如果缓存已经满了(达到上限),就触发缓存淘汰策略,把⼀些"相对不那么热⻔"的数据淘汰掉
    • 按照上述流程,持续一段事件之后,Redis内部的数据自然就是"热门数据"了
  • 通用的淘汰策略
    • FIFO(First In First Out)先进先出:把缓存中存在时间最久的(也就是先来的数据)淘汰掉
    • LRU(Least Recently Used)淘汰最久未使⽤的:记录每个key的最近访问时间,把最近访问时间最⽼的key淘汰掉
    • LFU(Least Frequently Used)淘汰访问次数最少的:记录每个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提供的策略和上述介绍的通⽤策略是基本⼀致的,只不过Redis这⾥会针对"过期key"和"全部key"做分别处理
    • 除⾮是Redis中的数据完全不关键,否则不应该使⽤allkeys系列的策略

3.缓存相关问题

1.缓存预热(Cache Preheating)

  • 什么是缓存预热?
    • 使⽤Redis作为MySQL的缓存的时候,当Redis刚刚启动,或者Redis⼤批key失效之后
    • 此时由于Redis⾃⾝相当于是空着的,没啥缓存数据,那么MySQL就可能直接被访问到,从⽽造成较⼤的压⼒
    • 因此就需要提前把热点数据准备好,直接写⼊到Redis中,使Redis可以尽快为MySQL撑起保护伞
  • 热点数据可以基于之前介绍的统计的⽅式⽣成即可,这份热点数据不⼀定⾮得那么"准确",只要能帮助MySQL抵挡⼤部分请求即可
  • 随着程序运⾏的推移,缓存的热点数据会逐渐⾃动调整,来更适应当前情况

2.缓存穿透(Cache Penetration)

  • 什么是缓存穿透?
    • 访问的key在Redis和数据库中都不存在,此时这样的key不会被放到缓存上,后续如果仍然在访问该key,依然会访问到数据库
    • 这就会导致数据库承担的请求太多,压⼒很⼤
  • 如何产生?
    • 业务设计不合理,⽐如缺少必要的参数校验环节,导致⾮法的key也被进⾏查询了
      • 典型问题
    • 开发/运维误操作,不⼩⼼把部分数据从数据库上误删了
      • 没那么典型,表现也是缓存穿透,误删操作不一定能及时发现
    • ⿊客恶意攻击
  • 如何解决?
    • 针对要查询的参数进⾏严格的合法性校验
      • 例如:要查询的key是⽤⼾的⼿机号,那么就需要校验当前key是否满⾜⼀个合法的⼿机号的格式
    • 针对数据库上也不存在的key,也存储到Redis中,可以设成一个非法值
      • 例如value就随便设成⼀个"",避免后续频繁访问数据库
    • 使⽤布隆过滤器先判定key是否存在,再真正查询

3.缓存雪崩(Cache Avalanche)

  • 什么是缓存雪崩?
    • 短时间内⼤量的key在缓存上失效,导致数据库压⼒骤增,甚⾄直接宕机
    • 本来Redis是MySQL的⼀个护盾,帮MySQL抵挡了很多外部的压⼒,⼀旦护盾突然失效了,MySQL⾃⾝承担的压⼒骤增,就可能直接崩溃
  • 如何产生?
    • Redis挂了 -> Redis宕机 / Redis集群模式下大量节点宕机
    • Redis大量的key同时过期
      • Redis正常,但是之前短时间内设置了大量的key,并且设置的过期时间是相同的
  • 如何解决?
    • 部署⾼可⽤的Redis集群,并且完善监控报警体系
    • 不给key设置过期时间或者设置过期时间的时候添加随机时间因⼦(避免同一时间过期)

4.缓存击穿(Cache Breakdown)

  • 此处把breakdown翻译成"击穿",个⼈认为并⾮是⼀个好的选择,容易和缓存穿透混淆
    • 翻译成"瘫痪"或者"崩溃"也许更合适⼀些
  • 什么是缓存击穿?
    • 相当于缓存雪崩的特殊情况,针对热点key突然过期了导致⼤量的请求直接访问到数据库上,甚⾄引起数据库宕机
  • 如何解决?
    • 基于统计的⽅式发现热点key,并设置永不过期
    • 进⾏必要的服务降级
      • 感性理解:本身服务器功能有10个,在特定情况下,适当的关闭一些不重要的功能,只保留核心功能,可以理解成电子设备的"省电模式"
      • 例如:访问数据库的时候使⽤分布式锁,限制同时请求数据库的并发数

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

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

相关文章

一种多版本、多人并行开发GIT分支管理规范

首发公众号: 赵侠客 引言 作为开发者每天在写代码的同时也在写BUG,所以一方面需要开发新的需求,另一方面还要填自己以前挖的坑。目前主流程序员都在使用GIT来管理自己的代码,当GIT仓库有多人维护或者项目有多个版本同时迭代开发时…

c++进阶学习--------多态

前言 需要声明的,本节课件中的代码及解释都是在vs2022下的x86程序中,涉及的指针都是4bytes。 如果要其他平台下,部分代码需要改动。 比如:如果是x64程序,则需要考虑指针是8bytes问题等等 1. 多态的概念 1.1 概念 …

.NET内网实战:白名单文件反序列化执行命令

01阅读须知 此文所节选自小报童《.NET 内网实战攻防》专栏,主要内容有.NET在各个内网渗透阶段与Windows系统交互的方式和技巧,对内网和后渗透感兴趣的朋友们可以订阅该电子报刊,解锁更多的报刊内容。 02基本介绍 本文内容部分节选自小报童…

【易社保-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

Java泛型方法的定义和使用、泛型类、泛型接口、泛型方法、通配符、泛型的上界与下界

文章目录 一、包装类1.1、基本数据类型和对应的包装类1.2、自动装箱和自动拆箱 二、基本介绍2.1、泛型引入背景2.1、什么是泛型2.2、为什么使用泛型 三、常见泛型字母含义四、泛型的使用4.1、泛型类4.2、泛型接口4.3、泛型方法 五、泛型的继承5.1、泛型不具备继承性5.2、何为数…

【Python】递归

专栏文章索引:Python 有问题可私聊:QQ:3375119339 文章内容改自:bilibili博主(又懂啦) 目录 一、递归函数 二、理解递归函数 一、递归函数 一个函数在其函数体内调用函数自身,这样的函数就称为递归函数。递归函数的…

每日一练 2024.9.29(2)

目录 解题思路与代码实现 题目分析 一、解题策略 关键步骤: 二、代码实现 三、代码解析 四、复杂度分析 五、运行示例 示例1: 示例2: 六、总结 解题思路与代码实现 题目分析 这道题目要求我们找到字符串列表 strs 中的相似字符组…

Arch - 架构安全性_验证(Verification)

文章目录 OverView导图1. 引言:数据验证的重要性概述2. 数据验证的基本概念3. 数据验证的层次前端验证后端验证 4. 数据验证的标准做法5. 自定义校验注解6. 校验结果的处理7. 性能考虑与副作用8. 小结 OverView 即使只限定在“软件架构设计”这个语境下&#xff0c…

物理学基础精解【40】

文章目录 矢量积矢量积(又称叉积、外积)的几何意义一、面积表示二、垂直性三、方向性四、应用实例五、数学表达 矢量积(叉积)的坐标表示法矢量积的坐标表示法的几何意义矢量积的性质矢量积的应用 矢量积(又称叉积、外积…

Linux——k8s组件

kubernetes 使用1.31.1 版本搭建集群核心组件,选择flannel 网络插件为整体集群的运行提供网络通信功能。 flannel 网络插件 kube-flannel kube-flannel-ds-9fgml 1/1 Running 1 (18m ago) 2d21h kube-flannel kube-flannel-ds-ghwbq …

<<迷雾>> 第 3 章 怎样才能让机器做加法 示例电路

全加器示意图 info::操作说明 鼠标单击开关切换开合状态 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjdmw-examples/assets/circuit/cyjsjdmw-ch03-01-full-adder.txt 原图 由3个全加器组成的3比特加法机 info::操作说明…

Linux——pod的调度

pod的调度 控制器: rc/rs 副本数量控制器 主要保证pod的数量符合管理员要求,并不会对pod进行额外的管理 以下三种控制器,本质上是服务控制器。具备以下特性: 副本数量的控制服务的滚动更新(更新pod)支持更新失…

基于springboot vue 投票系统设计与实现

博主介绍:专注于Java vue .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的…

基于51单片机的2路电压采集proteus仿真

地址:https://pan.baidu.com/s/1oNOJJv78ecfWZkdlMyhNVQ 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C52/AT89C51是一款经典的8位单片机,是意法半导体(STMicroelectron…

Linux:LCD驱动开发

目录 1.不同接口的LCD硬件操作原理 应用工程师眼中看到的LCD 1.1像素的颜色怎么表示 ​编辑 1.2怎么把颜色发给LCD 驱动工程师眼中看到的LCD 统一的LCD硬件模型 8080接口 TFTRGB接口 什么是MIPI Framebuffer驱动程序框架 怎么编写Framebuffer驱动框架 硬件LCD时序分析…

OpenAI全新多模态内容审核模型上线:基于 GPT-4o,可检测文本和图像

在数字时代,内容安全问题愈发受到重视。9月26日,OpenAI 正式推出了一款全新的多模态内容审核模型,名为 “omni-moderation-latest”。 该模型基于最新的 GPT-4o 技术,能够准确地识别检测有害文本图像。这一更新将为开发者提供强大…

Java | Leetcode Java题解之第445题两数相加II

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {Deque<Integer> stack1 new ArrayDeque<Integer>();Deque<Integer> stack2 new ArrayDeque<Integer>();while (l1 ! null) {stack1.…

AI Agent应用出路到底在哪?

1 Agent/Function Call 的定义 Overview of a LLM-powered autonomous agent system&#xff1a; Agent学会调用外部应用程序接口&#xff0c;以获取模型权重中缺失的额外信息&#xff08;预训练后通常难以更改&#xff09;&#xff0c;包括当前信息、代码执行能力、专有信息源…

《深度学习》OpenCV 角点检测、特征提取SIFT 原理及案例解析

目录 一、角点检测 1、什么是角点检测 2、检测流程 1&#xff09;输入图像 2&#xff09;图像预处理 3&#xff09;特征提取 4&#xff09;角点检测 5&#xff09;角点定位和标记 6&#xff09;角点筛选或后处理&#xff08;可选&#xff09; 7&#xff09;输出结果 3、邻域…

深度学习反向传播-过程举例

深度学习中&#xff0c;一般的参数更新方式都是梯度下降法&#xff0c;在使用梯度下降法时&#xff0c;涉及到梯度反向传播的过程&#xff0c;那么在反向传播过程中梯度到底是怎么传递的&#xff1f;结合自己最近的一点理解&#xff0c;下面举个例子简单说明&#xff01; 一、…