Redis—缓存机制

news2025/2/25 18:15:41

Redis 缓存机制

  • 1. 缓存三兄弟
    • 1.1 缓存击穿
    • 1.2 缓存穿透
    • 1.3 缓存雪崩
  • 2. 布隆过滤器
  • 3. 缓存和数据库数据一致性
    • 3.1 缓存更新策略
    • 3.2 缓存不一致处理
  • 4. 热点 key
    • 4.1 热点 key 处理
    • 4.2 热点 key 重建
  • 5. 缓存预热

Redis,一个轻量级的开源内存数据结构存储系统,以其卓越的性能和灵活性,成为实现高效缓存策略的不二选择。

1. 缓存三兄弟

1.1 缓存击穿

一个并发访问量比较大的 key 在某个时间过期,导致所有的请求直接打到 DB 上。

解决方案

  • 加锁更新:加互斥锁更新,强一致,性能差。比如请求查询 A,发现没有命中缓存,则对 A 这个key加锁,同时去数据库查询数据,写入缓存,再返回给用户,释放锁。
  • 逻辑过期:不设置过期时间,过期时间存放在缓存中。通过异步的方式不断地刷新过期时间,防止缓存击穿现象出现。

1.2 缓存穿透

查询缓存和数据库中都不存在的数据,这样每次请求直接打到数据库,就好像缓存不存在一样。

缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。

缓存穿透可能会使后端存储负载加大,如果发现大量存储层空命中,可能就是出现了缓存穿透问题。

可能发生的原因:

  1. 自身业务代码问题
  2. 恶意攻击、爬虫导致空命中

解决方案

  • 缓存空值/默认值:在数据库不命中之后,把一个空对象或者默认值保存到缓存,之后再访问这个数据,就会从缓存中获取,这样就保护了数据库。
  • 布隆过滤器:存储与缓存之间加一层布隆过滤器,判断数据是否存在,如数据不存在,则不访问存储

缓存空值存在问题:

  1. 缓存中存在更多的无效键值对,需要更多的内存空间。可以针对此类数据设置一个较短的过期时间,让其自动失效剔除
  2. 缓存层和存储层的数据会有一段时间窗口的不一致(空值过期前,存储层更新了该值),可能会对业务造成影响。可以利用消息队列或其他异步方式清理缓存中的空对象。

1.3 缓存雪崩

某一时刻,发生大规模的缓存失效情况,例如缓存服务宕机、大量 key 在同一时间过期,导致大量请求打在 DB 上,可能导致整个系统的崩溃,称为缓存雪崩。

解决方案:

  • 提高缓存可用性
    • 集群部署:通过集群中提升缓存的可用性,可以利用 Redis Cluster 或者第三方的集群方案等
    • 多级缓存:设置多级缓存,第一级缓存失效的基础上,访问二级缓存,每一级缓存失效的时间都不相同
  • 过期时间:
    • 均匀过期,随机过期时间,避免过期时间太过集中
    • 热点数据永不过期
  • 熔断降级:
    • 服务熔断:当缓存服务器宕机或超时响应时,为了防止整个系统出现雪崩,暂时停止业务服务访问缓存系统
    • 服务降级:当出现大量缓存失效,而且处在高并发高负荷的情况下,在业务系统内部暂时舍弃对一些非核心的接口和数据的请求而直接返回一个提前准备好的fallback错误处理信息

2. 布隆过滤器

布隆过滤器,一个连续的数据结构,每个存储位置都是一个 bit,来标识数据是否存在

存储数据的时候,使用 K 个不同的哈希函数将这个变量映射为 bit 列表的 K 个点,把他们置为 1

判断缓存 key 是否存在,同样使用 K 个不同的哈希函数,映射到 bit 列表上,判断是不是 1

  • 如果不全是 1,那么 key 不存在
  • 如果全是 1,也只是表示 key 可能存在

缺点:

  1. 它在判断元素是否在集合中时,存在一定的错误几率,因为哈希算法有一定的碰撞概率
  2. 不支持删除元素

3. 缓存和数据库数据一致性

根据CAP理论,在保证可用性和分区容错性的前提下,无法保证一致性,所以缓存和数据库的绝对致是不可能实现的,只能尽可能保存缓存和数据库的最终一致性。

3.1 缓存更新策略

  • 删除缓存而不是更新缓存

    • 当一个线程对缓存的key进行写操作的时候,如果其它线程进来读数据库的时候,读到的就是脏数据,产生了数据不一致问题。相比较而言,删除缓存的速度比更新缓存的速度快很多,所用时间相对也少很多,读脏数据的概率也小很多
  • 先更数据,后删缓存

    • 更新数据,耗时可能在删除缓存的百倍以上。在缓存中不存在对应的 key,数据库又没有完成更新的时候,如果有线程进来读取数据,并写入到缓存,那么在更新成功之后,这个 key就是一个脏数据
    • 毫无疑问,先删缓存,再更数据库,缓存中key不存在的时间的时间更长,有更大的概率会产生脏数据

3.2 缓存不一致处理

原因:

  1. 缓存 key 删除失败
  2. 并发导致写入了脏数据

解决方案:

1、消息队列保证 key 被有效删除

思路:可以引入消息队列,把要删除的 key 或者删除失败的 key 加入消息队列中,利用消息队列的重试机制,重新删除对应的 key

缺点:对业务代码有一定的侵入性

2、数据库订阅 + 消息队列保证

思路:可以用一个服务 (比如阿里的 canal) 去监听数据库的 binlog,获取需要操作的数据。然后用一个公共的服务获取订阅程序传来的信息,进行缓存删除操作。

3、延时双删防止脏数据

这种情况主要来自“先删缓存,再更数据”,并发情况下产生脏数据

在这里插入图片描述

解决方案是 延时双删,在第一次删除缓存之后,过一段时间,再次删除缓存

4、设置缓存过期时间兜底

设置缓存过期时间,即使发生不一致问题,总有过期的时候

4. 热点 key

4.1 热点 key 处理

在 Redis 集群部署中,热 key 可能会造成整体流量不均衡,个别节点出现 OPS 过大甚至超载的情况

在客户端、代理端和服务端监控,识别 热点 key

客户端:设置全局字典(key 和调用次数),每次调用 Redis 命令时,更新字典

Redis 服务端:使用 monitor 命令可以监控到 Redis 执行的所有命令,统计热点 key

处理方法:

  1. 热 key 打散到不同的服务器,降低压力
  2. 加入二级缓存,提前加载热 key 数据到内存中,如果 Redis 宕机,走内存查询
    热 key 处理

4.2 热点 key 重建

开发的时候一般使用 “缓存 + 过期时间” 的策略,既可以加速数据读写,又保证数据的定期更新,这种模式基本能够满足绝大部分需求

但是有两个问题如果同时出现,可能就会出现比较大的问题:

  • 当前key是一个热点key (例如一个热门的娱乐新闻),并发量非常大。
  • 重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的 SQL、多次 IO、多个依赖等。 在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能会让应用崩溃。

问题要点:

  • 减少重建缓存次数
  • 数据尽可能的一致
  • 较少的潜在风险

解决方案:

  • 互斥锁:这种方法只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。
  • 永不过期:缓存不设置过期时间,也即物理不过期;为每个 value 设置一个 逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存

5. 缓存预热

缓存预热,就是提前把数据库里的数据刷到缓存里,通常有这些方法

  1. 直接写个缓存刷新页面或者接口,上线时手动操作
  2. 数据量不大,可以在项目启动的时候自动进行加载
  3. 定时任务刷新缓存

参考二哥的面渣逆袭 & 《Redis设计与实现》,加油!

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

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

相关文章

Java:循环练习

目录 1. 回文判断 2. 减法求商余 3. 求平方根 4.求质数 5. 猜数字 1. 回文判断 输入一个数字,判断是否为回文,回文就是正着读和反着读都一样,如121是回文,123则不是。 import java.util.Scanner;public class DemoNew {publ…

白卡无法注册TDSCDMA问题分析

1、问题描述 MTK平台 实验室白卡测试TDSCDMA,默认无法注册。使用移动卡测试,无此问题。 2、问题分析 查看Radio log,Radio中反复下发EFUN去开关飞行模式。 39191: 08-14 22:45:57.159210 1469 1512 D RmcWp : [0] ECSRA info E…

CART决策树-基尼指数(全网最详解)

文章目录 一、基尼指数的定义二、基尼指数在CART决策树中的应用三、基尼指数与CART决策树的构建1.计算每个子集的基尼系数:2.计算基尼指数3.选择最优特征4.其余基尼指数5.构建决策树 四、总结 CART决策树基尼指数是CART(Classification And Regression T…

稳石机器人 | 工业级AMR S1200L,专为多样化需求设计,柔性拓展更易用

近日,稳石机器人重磅推出基于新品控制器ROC1000的全新移动机器人AMR S1200L,专为满足生产制造和仓储物流的多样化需求而设计,无需改造现场,最快可在1周内完成部署。 重载型AMR-S1200L设计注重实用性和灵活性,可在室内…

Excel 中找出每列第一个和最后一个非空格对应的行--Excel难题#87

Excel表格的第2-6列有空格。 ABCDEF1StartDateQID1QID2QID3QID4QID5210/03/2024 10:561yes32310/03/2024 03:102no423409/03/2024 19:253yes22509/03/2024 11:404no1yes609/03/2024 03:555yes5no708/03/2024 20:106808/03/2024 12:257no908/03/2024 04:408yes1007/03/2024 20:…

Linux云计算 |【第二阶段】SECURITY-DAY4

主要内容: Kali系统、扫描与抓包、Nginx安全加固、Linux基本防护 补充:使用Curl命令查看网页头部信息和页面内容 不加选项,默认查看网页的内容; [ -I ] 选项:访问服务器页面时,显示HTTP的头部信息&#xf…

用阿里云“无影”搭建《黑神话:悟空》电脑环境

目录 《黑神话:悟空》 阿里云无影试用版概述 阿里云无影云电脑试用版情况 具体详细过程(搭建环境) 《黑神话:悟空》 《黑神话:悟空》作为一款高品质的国产游戏,对硬件配置有一定的要求。根据公开发布的…

【鸿蒙学习】HarmonyOS应用开发者高级认证 - 应用性能优化一(界面层面)

学完时间:2024年8月22日 学完排名:第1801名 一、介绍 在开发HarmonyOS应用时,优化应用性能是至关重要的。通过/ArkTS高性能编程、减少丢帧卡顿、提升应用启动和响应速度 可以有效提升用户体验。本文将介绍一些优化HarmonyOS应用性能的方法。 一、Ark…

Go开发桌面客户端软件小试:网站Sitemap生成

在前一篇【手把手教你用Go开发客户端软件(使用Go HTML)】中,我们详细介绍了如何通过Go语言开发一个简单的桌面客户端软件。本次,我们将继续这个系列,使用Go语言结合Sciter的Go绑定库——go-sciter,实战开发…

14.C基础_结构体

定义与使用 1、定义 定义结构体: 定义结构体时,需要注意最后的分号必须加上。 定义结构体时,成员只去声明类型,不进行赋值。赋值在定义结构体变量时进行。 struct 结构体名{结构体成员列表 }; //注意这里的分…

Qt入门学什么?

Qt是一个跨平台的C图形用户界面应用程序框架,它为应用程序开发者提供建立图形界面所需的所有功能。Qt框架以其面向对象、易于扩展的特性而受到广泛欢迎,并且支持多种平台,包括桌面、嵌入式和移动平台 。 对于Qt的入门学习,可以通过…

uniapp+vue3的defineProps传递

//index.vue <view class"topic"><!-- 磨砂背景 --><view class"content"><matte v-for"(item,index) in 8" :key"index"></matte><matte isMore"false"></matte></view>&…

0成本学习Liunx系统【只需要一台笔记本电脑,无需购买云服务器】

【准备工作&#xff0c;需要软件】&#xff1a; 1&#xff1a;MobaXterm 【服务器连接工具&#xff08;免费开源&#xff09;】 2&#xff1a;CentOS-7-x86_64-DVD-2009.iso 【CentOS-7 镜像】 3&#xff1a;VirtualBox-7.0.20-163906-Win.exe 【虚拟机壳子】 4&…

朴素贝叶斯与决策树分类

朴素贝叶斯分类 1贝叶斯分类理论 选择高概率对应的类别 2条件概率 事件B发生的情况下&#xff0c;事件A发生的概率 &#x1d443;(&#x1d434;|&#x1d435;)&#x1d443;(&#x1d434;∩&#x1d435;)/&#x1d443;(&#x1d435;) > &#x1d443;(&#x1d43…

【前端面试】浏览器原理解读

前端进阶——浏览器篇-CSDN博客 浏览器工作原理与Javascript高级&#xff08;前后端异步&#xff09;-CSDN博客 DOM树的建立过程 前端DOM&#xff08;文档对象模型&#xff09;数的建立过程&#xff0c;实际上是浏览器解析HTML文档并构建DOM树的过程。这一过程大致可以分为以…

声音克隆GPT-SoVITS 2.0软件和详细的使用教程!

天命人&#xff0c;请允许我先蹭个热点&#xff01; 原始声音&#xff1a; 播放 克隆声音&#xff1a; 播放 文章写了一半&#xff0c;被《黑神话悟空》刷屏了。突发奇想&#xff0c;用里面的声音来做个素材试试看。 B站捞了一点声音素材&#xff0c;随便剪一剪&#xff0c…

IOS半越狱工具nathanlr越狱教程

简介 nathanlr 是一款半越狱工具&#xff0c;不是完整越狱。 半越狱只能使用一些系统范围的插件。 无法做到完整越狱 Dopamine 越狱一样插件兼容性。 nathanlr支持 iOS 16.5.1 – 16.6.1 系统。 支持 A12 及以上设备。 肯定有人问&#xff0c;为什么仅仅支持这些系统&#xff…

关于全球影像下载你需要知道这些参数

经常会有客户问我们&#xff0c;如果想要下载全球的影像应该怎么下载&#xff0c;这里我们用数字说话&#xff0c;为你介绍一下全球影像下载的那些关键参数。 TIF文件大小 在开始之前说明一下&#xff0c;以下表格中所有出现的级别均为标准级别&#xff0c;如果想对应水经微图…

Qt系列之数据库(一)

Qt 数据库开发是指在Qt框架下进行数据库操作的开发工作。Qt提供了一套强大的数据库模块&#xff0c;可以方便地与多种数据库进行交互&#xff0c;如SQLite、MySQL、PostgreSQL等。 该模块中接口是使用C语言&#xff0c;也就是说&#xff0c;学习相关的类及类的接口使用。 qt…

我的Markdown简历模板开源了!

我之前写过一篇文章&#xff0c;很详细的讲解了如何使用Markdown写出一份漂亮的简历&#xff0c;并且在各个博客平台都有发布。 为了方便&#xff0c;我在这贴一下这篇文章的链接&#xff1a;✨Markdown制作简历教程 如果你还没有读过&#xff0c;或者恰好需要做一份新的简历…