聊聊缓存相关知识

2023-11-10


缓存原理

在这里插入图片描述

缓存穿透

缓存穿透:指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。

解决方案

  1. 缓存空值/缺省值
    如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。通过这个直接设置的默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。
  2. 布隆过滤器
    快速判断数据是否存在,避免从数据库中查询数据是否存在,减轻数据库压力。
    将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

布隆过滤器
布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。

  • 优点:空间效率和查询时间都远远超过一般的算法。
  • 缺点:有一定的误识别率,删除困难。

布隆过滤器原理
布隆过滤器本质上是一个初始值都为 0 的 二进制数组和 N 个哈希函数组成。

当我们想标记某个数据存在时(例如,数据x已被写入数据库),布隆过滤器会通过三个操作完成标记:

  • 首先,使用 N 个哈希函数,分别计算这个数据的哈希值,得到 N 个哈希值。
  • 然后,我们把这 N 个哈希值对 bit 数组的长度取模,得到每个哈希值在数组中的对应位置。
  • 最后,我们把对应位置的 bit 位设置为 1,这就完成了在布隆过滤器中标记数据的操作。

具体了解布隆过滤器可参考文章:谈谈布隆过滤器

缓存击穿

缓存击穿:缓存中没有数据(一般是缓存时间到期),导致并发请求同时先去取缓存数据,没取到数据,所以又同时去数据库取数据,引起数据库压力瞬间增大,造成过大压力。

缓存击穿一般针对的是后一个Key。当缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

解决方案

  1. 使用互斥锁
    单机可以使用synchronized、lock,分布式可以使用lua脚本。
    在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。
  2. 设置热点数据永不过期
    缓存不设置失效时间,有更新的话,需要更新缓存。

缓存雪崩

缓存雪崩:原有缓存失效,新缓存未到期间所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。

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

解决方案

  1. 不同key设置不同的缓存失效时间(给每个key的失效时间加一个随机值);
    防止同一时间大量数据过期现象发生。
  2. 热点数据永不过期
    不设置失效时间,有更新的话,需要更新缓存。
  3. 缓存失效标记
    给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
  4. 加锁
    避免失效时大量的并发请求同时到数据库。

穿透、击穿、雪崩对比

缓存问题 针对数据 描述
缓存穿透 某个数据 某个数据缓存中没有,该数据的并发请求每次都要去数据库查
缓存击穿 某个数据 某个数据刚好过期,该数据的并发请求全都去数据库查
缓存雪崩 不同数据 不同数据都刚好过期,并发请求全都去数据库查

缓存预热

缓存预热:系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

缓存更新

除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:

  1. 定时去清理过期的缓存;
  2. 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。

缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。

降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务(核心业务)是无法降级的(如加入购物车、结算)。

针对不同的数据采用不同的处理方式:

  • 非核心数据,直接返回预定义信息、空值或者报错;
  • 核心数据,则允许访问缓存,如果缓存缺失,可以读取数据库。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

聊聊缓存相关知识 的相关文章

  • 为什么Redis中不建议使用KEYS?

    在Redis中 建议不要使用按键命令 https redis io commands KEYS 为什么会这样呢 是因为它的时间复杂度是 O N 吗 或者是别的什么原因 我做了下面的实验来证明KEYS命令有多么危险 当带有 KEYS 的一个命
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • Redis INCRBY 有限制

    我想知道是否有一种方法可以通过我的应用程序的单次往返在 Redis 中执行此操作 对于给定的键K 其可能值V是范围内的任意整数 A B 基本上 它有上限和下限 When an INCRBY or DECRBY发出命令 例如INCRBY ke
  • 在 Kubernetes/Openshift 中将客户端-服务器流量保持在同一区域的最佳方法?

    我们运行兼容 Kubernetes OKD 3 11 的本地 私有云集群 其中后端应用程序与用作缓存和 K V 存储的低延迟 Redis 数据库进行通信 新的架构设计将在两个地理上分布的数据中心 区域 之间平均划分工作节点 我们可以假设节点
  • 使用 Redis 命令 incr 和 expire 时的竞争条件

    根据redis文档 http redis io commands incr http redis io commands incr 在段落模式 速率限制器 2 较短的版本代码 value INCR ip IF value 1 THEN EX
  • 如何设置和获取Redis中存储的对象?

    我试图在 redis 中存储一个对象 当我获取该对象时 它似乎不起作用 I tried u User new u name blankman redis set test u x redis get test x name error 我想
  • Lua中按字符分割字符串

    我有像这样的字符串 ABC DEF 我需要将它们分开 字符并将两个部分分别分配给一个变量 在 Ruby 中 我会这样做 a b ABC DEF split 显然Lua没有这么简单的方法 经过一番挖掘后 我找不到一种简短的方法来实现我所追求的
  • Redis Cluster 与 Pub/Sub 中的 ZeroMQ,用于水平扩展的分布式系统

    如果我要设计一个巨大的分布式系统 其吞吐量应随系统中的订阅者数量和通道数量线性扩展 哪个会更好 1 Redis集群 仅适用于Redis 3 0 alpha 如果是集群模式 您可以在一个节点上发布并在另一个完全不同的节点上订阅 消息将传播并到
  • 为什么 Redis TimeSeries 不捕获聚合中的最后一个元素?

    我试图了解 Redis 的时间序列规则创建的工作原理 但我很困惑为什么 Redis 会忽略聚合中的最后一项 并想知道这是否是预期的行为 我在中创建了示例代码redis cli为了显示 127 0 0 1 6379 gt FLUSHALL O
  • Java 将字节转换为二进制安全字符串

    我有一些以字节为单位的数据 我想将它们放入Redis中 但是Redis只接受二进制安全字符串 而我的数据有一些二进制非安全字节 那么如何将这些字节转换为二进制安全字符串以便将它们保存到 Redis 中呢 Base64 对我有用 但它使数据更
  • 2 个具有共享 Redis 依赖的 Helm Chart

    目前 我有 2 个 Helm Charts Chart A 和 Chart B Chart A 和 Chart B 对 Redis 实例具有相同的依赖关系 如Chart yaml file dependencies name redis v
  • redis - 使用哈希

    我正在使用 redis 为我的 Web 应用程序实现社交流和通知系统 我是 redis 的新手 我对哈希值及其效率有一些疑问 我读过这篇很棒的文章Instagram 帖子 http instagram engineering tumblr
  • redis dump.rdb / 保存小文件

    Context 我正在使用redis 数据库小于 100 MB 但是 我想进行每日备份 我也在 Ubuntu Server 12 04 上运行 当输入 redis cli save 我不知道 dump rdb 保存到哪里 因为 redis
  • 为什么Redis中没有有序的hashmap?

    Redis 数据类型 http redis io topics data types包括排序集 http redis io topics data types intro sorted sets以及其他用于键值存储的必要数据结构 但我想知道
  • 在 Redis 上为 Django 和 Express.js 应用程序共享会话存储

    我想创建一个包含一些登录用户的 Django 应用程序 另一方面 由于我想要一些实时功能 所以我想使用 Express js 应用程序 现在的问题是 我不希望身份不明的用户访问 Express js 应用程序的日期 因此 我必须在 Expr
  • 想要在后台不间断地运行redis-server

    我已经下载了 redis 2 6 16 tar gz 文件并安装成功 安装后我运行 src redis server 它工作正常 但我不想每次都手动运行 src redis server 而是希望 redis server 作为后台进程持续
  • Scala 使用的 Redis 客户端库建议

    我正在计划使用 Scala 中的 Redis 实例进行一些工作 并正在寻找有关使用哪些客户端库的建议 理想情况下 如果存在一个好的库 我希望有一个为 Scala 而不是 Java 设计的库 但如果现在这是更好的方法 那么仅使用 Java 客
  • 如何配置Lettuce Redis集群异步连接池

    我正在配置我的生菜重新分配池 当我按照官方文档配置时 连接池无法正常初始化 无法获取连接 官方文档指出 RedisClusterClient clusterClient RedisClusterClient create RedisURI
  • Laravel Redis 配置

    我目前正在使用 Laravel 和 Redis 创建一个应用程序 几乎一切都工作正常 我按照文档中的说明扩展了身份验证 用户可以订阅 登录 注销 我可以创建内容 所有内容都存储在 Redis 中 但我有一个问题 我无法运行 php arti
  • 由于配置文件错误,无法启动 Redis 服务器

    我刚刚按照此处的说明安装了 Redis http redis io download http redis io download 当我运行 redis server redis conf 时出现以下错误 FATAL CONFIG FILE

随机推荐

  • hdu 3879 最大密集子图(点和边均带权)(模板)

    最大权闭合图 可以用最大密集子图来解速度更快复杂度低 题解 胡伯涛 最小割模型在信息学竞赛中的应用 点和边均带权的最大密集子图 s i 权为U 点权绝对值和 边的所有权值 i t 权为U 点的值 点的度 u v 权值为w 意思是选了v后可以
  • Mybatis-plus使用手册

    Mybatis plus 1 定义 MyBatis Plus 是一个 Mybatis 增强版工具 在 MyBatis 上扩充了其他功能没有改变其基本功能 为了简化开发提交效率而存在 2 使用 SpringBoot 集成 MyBatis Pl
  • 相关性分析

    这里的相关性分析主要是线性相关性分析 当然其他的形状的相关性分析可以通过变换转换为线性相关性分析 但是 线性相关性分析始终是相关性分析的基础 线性相关分析的构建主要分为以下几种 直接绘制散点图 通过把点标出来主观上看是否是线性相关 绘制散点
  • 《动手学深度学习》第二十三天---稠密连接网络(DenseNet)

    一 DenseNet DenseNet作为另一种拥有较深层数的卷积神经网络 具有如下优点 1 相比ResNet拥有更少的参数数量 2 旁路加强了特征 feature 的重用 3 网络更易于训练 并具有一定的正则效果 4 缓解了gradien
  • Android Studio按钮背景色

    Android Studio按钮背景色改变 修改style xml theme xml 在Android Studio里写前端界面 修改Button的背景样式一直是系统默认的主题色就像这样 不管怎么改颜色都会是系统的默认主题色 这里我们需要
  • LC并联谐振电路的原理

    LC并联谐振电路的原理 2011 11 26 04 54 353744594 来自 手机知道 分类 电脑 网络 浏览6573次 LC并联谐振电路的原理 我怎么不能理解这个原理 能不能用生活中的例子来说明 谢谢 提问者采纳 2011 11 2
  • Springboot使用maven打包指定mainClass

    http jvm123 com 2019 12 springboot repackage html
  • 六、Linux系统编程:读写锁

    5 读写锁 读写锁 ReentrantReadWriteLock 就是读线程和读线程之间不互斥 读读不互斥 读写互斥 写写互斥 一个资源可以被多个读线程访问 也可以被一个写线程访问 但不能同时存在读写线程 读写互斥 读读共享 5 1 锁操作
  • Meetup预告

    2月份 我们匠心打磨的区块链跨链协作平台WeCross正式开源 技术白皮书同期发布 很多小伙伴认真品读研究之后 给我们提供了非常多及时和有益的反馈 我们深表感谢 关于WeCross的设计哲学 我们思考了四个方向 Synergetic 跨链业
  • Ceph入门到精通-存储集群ceph df 用量统计算法说明

    3 2 5 Ceph 如何计算数据使用量 used 值反映了使用的实际原始存储量 xxx GB xxx GB 代表可用的存储 其中较小的数字 和总存储容量 总容量反映了在复制 克隆或快照前存储数据的大小 因此 实际存储的数据量通常会超过名义
  • Android基础学习(十七)—— Retrofit

    Retrofit本身并没有提供网络访问的能力 但是它底层封装了OkHttp 也是由Square公司贡献的一个处理网络请求的开源项目 A type safe HTTP client for Android and Java https git
  • parent.layer.closeAll();关闭弹出层

    可参考文档 https wenku baidu com view e05a3fe15bf5f61fb7360b4c2e3f5727a5e92486 html 关闭所有页面 parent layer closeAll 先得到当前ifame层的
  • 数据库的备份与恢复

    目录 1 数据库的备份与恢复是什么 2 数据库的备份与恢复的三种常见方法 2 1 使用第三方工具 我用的是navicat 导入 导出 2 2 使用mysqldump命令备份和恢复 导入 导出 2 3 LOAD DATA INFILE 导入
  • ArcGIS制作全球地图并生成纬度统计分布线

    转载 ArcGIS制作全球地图并生成纬度统计分布线https mp weixin qq com s LTA9I2lZ1nwA1xdHlD9vjg
  • MYSQL数据导入导出&视图&索引&执行计划

    目录 一 数据导入 导出 二 视图运用 三 索引 四 执行计划 一 数据导入 导出 创建log数据表 CREATE TABLE t log id varchar 32 NOT NULL COMMENT 唯一标识 ip varchar 15
  • C++STL库之sort函数

    sort函数 sort函数介绍 背景 功能 语法 便捷函数 sort函数应用 普通排序 结构体排序 sort函数介绍 背景 sort函数用于C 中 对给定区间所有元素进行排序 默认为升序 也可进行降序排序 sort函数进行排序的时间复杂度为
  • 【Meta-AI】Sam-分割一切 测试

    什么是 SAM 近日 Meta AI在官网发布了基础模型 Segment Anything Model SAM 并开源 其本质是用GPT的方式 基于Transform 模型架构 让计算机具备理解了图像里面的一个个 对象 的通用能力 SAM模
  • 【数学建模笔记 13】数学建模的差分方程模型

    13 差分方程模型 定义 设函数 x k x k x k x k
  • Go语言从入门到规范-6.9、Go处理yml和ini文件

    Go语言从入门到规范 6 9 Go处理yml和ini文件 文章目录 Go语言从入门到规范 6 9 Go处理yml和ini文件 1 前言 2 ini概念 2 1 概述 2 2 格式 2 3 示例 3 Go语言处理ini文件 1 前言 一般ym
  • 聊聊缓存相关知识

    文章目录 缓存原理 缓存穿透 缓存击穿 缓存雪崩 穿透 击穿 雪崩对比 缓存预热 缓存更新 缓存降级 缓存原理 缓存穿透 缓存穿透 指用户查询数据 在数据库没有 自然在缓存中也不会有 这样就导致用户查询的时候 在缓存中找不到 每次都要去数据