Resid作为缓存可能遇到的问题

article/2025/8/15 4:17:48

1.缓存的执行流程

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iWhEiDhU-1607051819476)(9.png)]

2.缓存穿透

2.1概念

当查询Redis中没有的数据时,该查询会下沉到数据库层,同时数据库层也没有该数据,当这种情况大量出现或被恶意攻击时,接口的访问全部透过Redis访问数据库,而数据库中也没有这些数据,我们称这种现象为"缓存穿透"。缓存穿透会穿透Redis的保护,提升底层数据库的负载压力,同时这类穿透查询没有数据返回也造成了网络和计算资源的浪费。

在这里插入图片描述

2.2 解决方案

  1. 在接口访问层对用户做校验,如接口传参、登陆状态、n秒内访问接口的次数;
  2. 利用布隆过滤器,将数据库层有的数据key存储在位数组中,以判断访问的key在底层数据库中是否存在;

第一种解决方案很好理解,这里介绍一下第二种方案,在前一篇文章中我们介绍了Redis的布隆过滤器,我们知道布隆过滤器可以判断key一定不在集合内以及key极有可能在集合内。

基于布隆过滤器,我们可以先将数据库中数据的key存储在布隆过滤器的位数组中,每次客户端查询数据时先访问Redis:

  • 如果Redis内不存在该数据,则通过布隆过滤器判断数据是否在底层数据库内;
  • 如果布隆过滤器告诉我们该key在底层库内不存在,则直接返回null给客户端即可,避免了查询底层数据库的动作;
  • 如果布隆过滤器告诉我们该key极有可能在底层数据库内存在,那么将查询下推到底层数据库即可;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-egCuaBWU-1607051819485)(2.png)]

布隆过滤器有误判率,虽然不能完全避免数据穿透的现象,但已经可以将99.99%的穿透查询给屏蔽在Redis层了,极大的降低了底层数据库的压力,减少了资源浪费。

3.缓存击穿

3.1 概念

缓存击穿和缓存穿透从名词上可能很难区分开来,它们的区别是:穿透表示底层数据库没有数据且缓存内也没有数据,击穿表示底层数据库有数据而缓存内没有数据。当热点数据key从缓存内失效时,大量访问同时请求这个数据,就会将查询下沉到数据库层,此时数据库层的负载压力会骤增,我们称这种现象为"缓存击穿"。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kWMjuk9t-1607051819489)(3.png)]

3.2 解决方案

  1. 延长热点key的过期时间或者设置永不过期,如排行榜,首页等一定会有高并发的接口;
  2. 利用互斥锁保证同一时刻只有一个客户端可以查询底层数据库的这个数据,一旦查到数据就缓存至Redis内,避免其他大量请求同时穿过Redis访问底层数据库;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-52iRfEqP-1607051819492)(4.png)]

在使用互斥锁的时候需要避免出现死锁或者锁过期的情况:

  • 使用前面文章介绍过的lua脚本或事务将获取锁和设置过期时间作为一个原子性操作(如:set kk vv nx px 30000),以避免出现某个客户端获取锁之后宕机导致的锁不被释放造成死锁现象;
  • 另起一个线程监控获取锁的线程的查询状态,快到锁过期时间时还没查询结束则延长锁的过期时间,避免多次查询多次锁过期造成计算资源的浪费;

在这里插入图片描述

4.缓存雪崩

4.1 概念

缓存雪崩是缓存击穿的"大面积"版,缓存击穿是数据库缓存到Redis内的热点数据失效导致大量并发查询穿过redis直接击打到底层数据库,而缓存雪崩是指Redis中大量的key几乎同时过期,然后大量并发查询穿过redis击打到底层数据库上,此时数据库层的负载压力会骤增,我们称这种现象为"缓存雪崩"。事实上缓存雪崩相比于缓存击穿更容易发生,对于大多数公司来讲,同时超大并发量访问同一个过时key的场景的确太少见了,而大量key同时过期,大量用户访问这些key的几率相比缓存击穿来说明显更大。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q2KlRMPd-1607051819494)(5.png)]

4.2 解决方案

  1. 在可接受的时间范围内随机设置key的过期时间,分散key的过期时间,以防止大量的key在同一时刻过期;
  2. 对于一定要在固定时间让key失效的场景(例如每日12点准时更新所有最新排名),可以在固定的失效时间时在接口服务端设置随机延时,将请求的时间打散,让一部分查询先将数据缓存起来;
  3. 延长热点key的过期时间或者设置永不过期,这一点和缓存击穿中的方案一样;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M72RkiT9-1607051819495)(6.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ufhl6obU-1607051819496)(7.png)]

5.缓存预热

5.1概念

缓存预热如字面意思,当系统上线时,缓存内还没有数据,如果直接提供给用户使用,每个请求都会穿过缓存去访问底层数据库,如果并发大的话,很有可能在上线当天就会宕机,因此我们需要在上线前先将数据库内的热点数据缓存至Redis内再提供出去使用,这种操作就成为"缓存预热"。

缓存预热的实现方式有很多,比较通用的方式是写个批任务,在启动项目时或定时去触发将底层数据库内的热点数据加载到缓存内。

6.缓存更新

6.1概念

缓存服务(Redis)和数据服务(底层数据库)是相互独立且异构的系统,在更新缓存或更新数据的时候无法做到原子性的同时更新两边的数据,因此在并发读写或第二步操作异常时会遇到各种数据不一致的问题。如何解决并发场景下更新操作的双写一致是缓存系统的一个重要知识点。

第二步操作异常:缓存和数据的操作顺序中,第二个动作报错。如数据库被更新, 此时失效缓存的时候出错,缓存内数据仍是旧版本;

6.2 缓存更新四种设计模式

Cache aside查询:先查缓存,缓存没有就查数据库,然后加载至缓存内;更新:先更新数据库,然后让缓存失效;或者先失效缓存然后更新数据库;

1.为了避免在并发场景下,多个请求同时更新同一个缓存导致脏数据,因此不能直接更新缓存而是另缓存失效。
2.先更新数据库后失效缓存:并发场景下,推荐使用延迟失效(写请求完成后给缓存设置1s过期时间),在读请求缓存数据时若redis内已有该数据(其他写请求还未结束)则不更新。当redis内没有该数据的时候(其他写请求已另该缓存失效),读请求才会更新redis内的数据。这里的读请求缓存数据可以加上失效时间,以防第二步操作异常导致的不一致情况。
3.先失效缓存后更新数据库:并发场景下,推荐使用延迟失效(写请求开始前给缓存设置1s过期时间),在写请求失效缓存时设置一个1s延迟时间,然后再去更新数据库的数据,此时其他读请求仍然可以读到缓存内的数据,当数据库端更新完成后,缓存内的数据已失效,之后的读请求会将数据库端最新的数据加载至缓存内保证缓存和数据库端数据一致性;在这种方案下,第二步操作异常不会引起数据不一致,例如设置了缓存1s后失效,然后在更新数据库时报错,即使缓存失效,之后的读请求仍然会把更新前的数据重新加载到缓存内。

Read through:在查询操作中更新缓存,即当缓存失效时,Cache Aside 模式是由调用方负责把数据加载入缓存,而 Read Through 则用缓存服务自己来加载;

Write through:在更新数据时发生。当有数据更新的时候,如果没有命中缓存,直接更新数据库,然后返回。如果命中了缓存,则更新缓存,然后由缓存自己更新数据库;

Write behind caching:俗称write back,在更新数据的时候,只更新缓存,不更新数据库,缓存会异步地定时批量更新数据库;

推荐使用先失效缓存,后更新数据库,配合延迟失效来更新缓存的模式;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dN51Wzaq-1607051819497)(8.png)]

6.3 四种模式优缺点

  • Cache Aside:实现起来较简单,但需要维护两个数据存储,一个是缓存(Cache),一个是数据库(Repository);
  • Read/Write Through:只需要维护一个数据存储(缓存),但是实现起来要复杂一些;
  • Write Behind Caching:与Read/Write Through 类似,区别是Write Behind Caching的数据持久化操作是异步的,但是Read/Write Through 更新模式的数据持久化操作是同步的。优点是直接操作内存速度快,多次操作可以合并持久化到数据库。缺点是数据可能会丢失,例如系统断电等。

缓存本身就是通过牺牲强一致性来提高性能,因此使用缓存提升性能,就会有数据更新的延迟性。这就需要我们在评估需求和设计阶段根据实际场景去做权衡了。

7.缓存降级

7.1 概念

缓存降级是指当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,即使是有损部分其他服务,仍然需要保证主服务可用。可以将其他次要服务的数据进行缓存降级,从而提升主服务的稳定性。

降级的目的是保证核心服务可用,即使是有损的。如去年双十一的时候淘宝购物车无法修改地址只能使用默认地址,这个服务就是被降级了,这里阿里保证了订单可以正常提交和付款,但修改地址的服务可以在服务器压力降低,并发量相对减少的时候再恢复。

降级可以根据实时的监控数据进行自动降级也可以配置开关人工降级。是否需要降级,哪些服务需要降级,在什么情况下再降级,取决于大家对于系统功能的取舍。


http://chatgpt.dhexx.cn/article/8AUaAlXy.shtml

相关文章

动态修改android中的资源索引resId

目录 一、引言 1、为什么要动态修改资源索引 2、怎么修改资源索引 3、什么时候修改 二、处理Task及R文件 1、处理Task 2、修改R文件 三、处理编译后的二进制文件 1、编译后的文件在哪? 2、解压、压缩AP_文件 3、修改resources.arsc文件的pkgId 4、修改Xm…

Redis安装(Windows环境)

文章目录 一、Resid简介:二、下载Redis三、启动Redis服务四、设置Windows服务五、常用的Redis服务命令六、cmd启动服务:七、操作测试Redis 一、Resid简介: Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分…

Resid总结

Redis是什么? Redis:REmote DIctionary Server(远程字典服务器) 是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数…

Redis系列(一):各大厂都在用的Resid到底是什么?

一、redis是什么? 1.Redis的定义 先上一段官方定义:Redis 是开源免费(遵守BSD协议)、高性能的key-value数据库。 是不是觉得上面的一句话既熟悉又陌生,作者怎么想的为啥开源免费?BSD协议又是什么&#x…

opencv 实现图像高斯金字塔

函数: dst cv.pyrDown( src[, dst[, dstsize[, borderType]]] ) # 高斯金字塔下采样 参数: src 源图像. dst 输出图像;它有着指定的大小,和源图像有着相同的类型. dstsize 输出图像的大小. borderType 像素外延方法. 默认情况下&…

图像增强中的高斯金字塔/拉普拉斯金字塔 融合

1.高斯金字塔 注意区分:高斯金字塔层级越高,分辨率越低。但下层(第i层)得到上层(第i1层)的过程叫做下采样,有些地方用reduce描述这个过程。 图像的金字塔化过程实际上是先平滑、再下采样的过程…

python --opencv图像处理金字塔(高斯金字塔、拉普拉斯金字塔)

引言 前面的文章中,我们有用过图像方法或者缩小的函数 resize() ,这个函数既可以放大图像,也可以缩小图像,其中: 缩小图像:一版使用 CV_INETR_AREA (区域插值)来插值。放大图像&am…

高斯金字塔及拉普拉斯金字塔的Matlab实现

1、高斯金字塔计算步骤 (1)对第 i i i 层图像进行高斯内核卷积; (2)将所有偶数行和列去除(下采样),得到第 i 1 i1 i1 层图像; (3)对原始图像不…

【C++】高斯金字塔和拉普拉斯金字塔原理和实现

【C】高斯金字塔和拉普拉斯金字塔原理和实现 图像中各个像素与其相邻像素之间的有很强的相关性,包含的信息也十分丰富,目标的尺寸有大有小,对比度有强有弱,此时就需要一个“显微镜”或者“望远镜”-----多尺度图像技术。它可以在…

python 高斯金字塔_12、高斯金字塔、拉普拉斯金字塔与图片尺寸缩放(示例代码)...

一、引言 我们经常会将某种尺寸的图像转换为其他尺寸的图像,如果放大或者缩小图片的尺寸,笼统来说的话,可以使用OpenCV为我们提供的如下两种方式: (1)resize函数。这是最直接的方式, (2)pyrUp( )、pyrDown( )函数。即图…

高斯金字塔的构建步骤

转自:https://www.cnblogs.com/starfire86/p/5735061.html SIFT(Scale-Invariant Feature Transform,尺度不变特征转换)在目标识别、图像配准领域具有广泛的应用,下面按照SIFT特征的算法流程对其进行简要介绍对SIFT特征做简要介绍。 高斯金字…

图像处理(九)高斯金字塔及拉普拉斯金字塔

高斯滤波的核就是一个求平均值的卷积核 高斯金字塔也是一个高斯核,只是步长为2,卷积后图片缩小二倍。高斯金字塔的目的是在图像不同大小时可以获得不同的信息,比如说图像较小时可以获得轮廓,图像较大时可以获得细节 使用函数cv2.p…

OpenCV SIFT源码讲解——构建高斯金字塔

目录 一、构建方法 二、函数重要点注释 一、构建方法 高斯金字塔每层图像的尺度为:。理论上金字塔每层图像可以从原图做的高斯滤波得到。但是实际操作中,每组的第一张影像(除第一组)是上一组倒数第三张影像降采样得到&#xff0c…

OpenCV中的图像金字塔(高斯金字塔、拉普拉斯金字塔)

最近在看关于数字图像的知识点,目前在图像金字塔部分,实在是懒得用手作笔记了,就以其中比较出名的“高斯金字塔”和“拉普拉斯金字塔”为例,基于OpenCV的源代码作解析存个档;毕竟属于基础部分,以后有需要就…

python 高斯金字塔_Python OpenCV 之图像金字塔,高斯金字塔与拉普拉斯金字塔

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。 基础知识铺垫 学习图像金字塔,发现网上的资料比较多,检索起来比较轻松。 图像金字塔是一张图像多尺度的表达,或者可以理解成一张图像不同分辨率展示。 金字塔越底层的…

图像金字塔和高斯金字塔

一:图像金字塔 图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。图像金字塔实际上是一张图片在不同尺度下的集合,即原图的上采样和下采样集合。金字塔的底部是高分辨…

opencv学习-高斯金字塔和拉普拉斯金字塔

图像金字塔 一个图像金字塔是由一系列的图像组成,最底下一张是图像尺寸最大,最上方的图像尺寸最小,从空间上从上向下看就像一个古代的金字塔。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。我们将一层一层的…

高斯金字塔与拉普拉斯金字塔的原理与python构建

转载自:https://zhuanlan.zhihu.com/p/94014493 高斯金字塔和拉普拉斯金字塔【1】在图像相关领域应用广泛,尤其是图像融合和图像分割方面。本文从理论和opencv实现两个方面对两种金字塔进行了介绍,并给出了二者的视觉效果。 1、高斯金字塔 在计算机视觉…

图像金字塔、高斯金字塔、拉普拉斯金字塔是怎么回事?附利用拉普拉斯金字塔和高斯金字塔重构原图的Python-OpenCV代码

图像金字塔是对图像进行多分辨率表示的一种有效且简单的结构。 一个图像金字塔是一系列以金字塔形状排列的分辨率逐步降低的图像。图像金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率表示。 图像金字塔有什么作用? 图像金字塔常用于图像缩放…

高斯金字塔

1、为什么要构建高斯金字塔 高斯金字塔模仿的是图像的不同的尺度,尺度应该怎样理解?对于一副图像,你近距离观察图像,与你在一米之外观察,看到的图像效果是不同的,前者比较清晰,后者比较模糊&am…