首页 > 其他分享 >缓存穿透、击穿和雪崩的认识

缓存穿透、击穿和雪崩的认识

时间:2024-09-24 10:53:19浏览次数:10  
标签:缓存 击穿 Redis 数据库 redis 写入 雪崩 数据

一、前言

在redis的使用中会遇到缓存失效、缓存穿透、缓存雪崩等问题。分布式缓存服务,主要是为了解决集群环境下,内存数据不共享的问题,比如 session 会话,以及一些字典缓存等等,在当前服务器的内存中存储,在另一台服务器中难以获取查询的问题,通过引入缓存服务,将缓存数据统一归一到一个服务器里面,以解决系统中内存数据不共享的问题,同时缓存性能也不会受到很大影响。

二、常见问题

1.为什么存入 redis 的数据,查询失效

Redis 的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上;也可以把每一次数据变化都写入到一个aof日志文件里面,当 redis 的服务器重启的时候,自动从日志文件里面恢复数据到内存中。

有哪些场景会发生缓存失效呢?总结起来有以下两种场景:

  • 1.当 redis 服务器重启的时候,可能会发生缓存失效,此时可以将 redis 的持久化方式改成AOF模式,也就是全持久化模式,但是性能会消耗很大
  • 2.存入redis 的数据,设置了自动过期时间,这种情况可以重新调整过期时间

2.缓存与数据库的数据不一致

通常情况下我们使用缓存,其中有一个很重要的目的就是降低数据库的访问压力,比如商品的信息查询,优先是从缓存中查询,如果没有,再从数据库里面查询。

对于既有数据库写入又有缓存操作的接口,一般分为两种情况执行。

  • 1.先写入数据库,再操作缓存。这种情况下如果数据库操作成功,缓存操作失败就会导致缓存和数据库不一致
  • 2.先操作缓存,再写入数据库。这种情况下如果缓存操作成功,数据库操作失败也会导致数据库和缓存不一致

大部分情况下,缓存理论上都是需要可以从数据库恢复出来的,所以基本上采取第一种顺序都是不会有问题的,但是无法保证数据库和缓存完全一致。

也就是说,使用缓存,就可能会出现缓存与数据库不一致的情况,只是说这种几几率的情况有多大。

针对那些必须保证数据库和缓存一致的情况,通常是不建议使用缓存的,直接从数据库查询。

3.什么是缓存穿透

缓存穿透,表示恶意用户频繁的模拟请求缓存中不存在的数据,此时如果有大量的接口请求,短时间内会直接落在了数据库上,缓存被击穿,导致数据库性能急剧下降,最终影响服务整体的性能。

这个在实际项目中很容易遇到,如抢购活动、秒杀活动、抢优惠券等接口 API 被大量的恶意用户刷,导致短时间内数据库宕机。对于缓存击穿的问题,有以下几种解决方案。

  • 1.使用分布式锁排队。当从缓存中获取数据失败时,给当前接口加上锁,从数据库中加载完数据并写入后再释放锁。若其它线程获取锁失败,则等待一段时间后再重试。
  • 2.使用布隆过滤器。将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力
  • 3.对空结果进行缓存。如果一个查询返回的数据为空,我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟,这样第二次到缓存中获取就有值了,而不会继续访问数据库,简单粗暴好使。

4.什么是缓存雪崩

缓存雪崩,简单的说就是在短时间内有大量缓存失效,如果这期间有大量的请求发生,同样也有可能会导致数据库发生宕机。在 Redis 机群的数据分布算法上如果使用的是传统的 hash 取模算法,在增加或者移除 Redis 节点的时候就会出现大量的缓存临时失效的情形。

对于缓存雪崩的问题,有以下几种解决方案。

  • 1.像解决缓存穿透一样加锁排队
  • 2.建立备份缓存。比如缓存 A 和缓存 B,A 设置超时时间,B 不设值超时时间,先从 A 读缓存,A 没有读 B,当缓存 A 发生变化的时候,同时更新缓存 B
  • 3.计算数据缓存节点的时候采用一致性 hash 算法,这样在节点数量发生改变时不会存在大量的缓存数据需要迁移的情况发生

5.redis 缓存会不会出现并发问题

首先 Redis 是单线程执行命令的,在出现多个 Redis Client 并发操作数据时,秉承先发起先执行的原则,其它的处于阻塞状态。

redis 缓存并发问题,其实主要指的还是读取数据库数据的并发操作问题。

当缓存过期后会从数据库查询数据然后再存入Redis缓存,但是在高并发情况下,可能还没来得及将数据库中查出来的数据存入Redis时,其它Client又从数据库里查询数据再存入Redis了。

这样一来会造成多个请求并发的从数据库获取数据,然后存入Redis,可能在读取的时候,出现脏数据。

针对这种场景,有以下几种解决方案。

  • 1.同步加锁处理。在写入数据库的时候,再操作缓存这个阶段,进行加锁处理,保证服务串行,可能会牺牲一点时间
  • 2.异步队列串行执行。把写入数据库和操作缓存的操作,放在队列中使其串行化,让他们一个一个的执行,比如通过消息中间件异步执行。
  • 3.使用类似SQL的乐观锁机制:在并发写入Redis缓存时,把要写入数据的版本号和时间戳与Redis中的数据进行对比,如果写入的数据时间戳或者版本号 比Redis高,则写入;否则就不写入


标签:缓存,击穿,Redis,数据库,redis,写入,雪崩,数据
From: https://blog.51cto.com/u_13312531/12097718

相关文章

  • 浏览器缓存
    使用场景-强缓存适用于不经常变动的静态资源,图片、css、js等文件。这些资源变更频率低,可以设置较长的缓存时间,以提高加载速度减少服务器压力。-协商缓存适用于可能被频繁更新的资源,主要通过if-none-match也就是etag或者if-modified-since来判断是否需要修改强缓存......
  • 【解决方案】Java 互联网项目中常见的 Redis 缓存应用场景
    一、常见key-value首先介绍的是项目开发中常见的一些String类型的key-value结构场景,如:使用jsonStr结构存储的用户登录信息,包括:手机号、token、唯一uuid、昵称等;jsonStr结构某个热门商品的信息,包括:商品名称、商品唯一id、所属商家、价格等;String类型的、......
  • 缓存写入失败的解决方案
    缓存写入失败通常是因为磁盘空间不足或目录权限设置不当。以下是一些具体的解决方案:1.检查磁盘空间1.1检查磁盘空间是否已满使用命令行检查:使用命令行工具检查磁盘空间是否已满。sh df-h输出示例:  FilesystemSizeUsedAvailUse%Mountedon/d......
  • 【解决方案】Java 互联网项目中常见的 Redis 缓存应用场景
    目录前言一、常见key-value二、时效性强三、计数器相关四、高实时性五、排行榜系列六、文章小结前言在笔者3年的Java一线开发经历中,尤其是一些移动端、用户量大的互联网项目,经常会使用到Redis作为缓存中间件的基本工具来解决一些特定的问题。下面是笔者总结梳理的一些常......
  • Python中的同一运算符与整数缓存问题
    在Python中,is运算符与==运算符的使用常常引发混淆。特别是在处理小整数时,Python会进行整数缓存,以提高性能。本文将深入探讨同一运算符(is)与相等运算符(==)的区别,并详细阐述整数缓存的问题,通过具体的代码示例和运行结果来帮助理解。1.同一运算符与相等运算符is运算符:判断两个对象是否......
  • MySQL—缓存_mysql 页缓存
    bufferpool缓存什么InnoDB会把存储的数据划分为若干个页,以页作为磁盘和内存交互的基本单位,一个页默认大小为16KB,MySQL启动时,InnoDB会为bufferpool申请一篇连续的内存空间,然后按照默认的16KB的大小划分出一个个的页,bufferpool中的页就叫做缓存页。BufferPool除了缓存「索引页......
  • 【编程底层原理】彻底搞懂Spring是如何利用三级缓存来解决循环依赖问题的(一级缓存为
    一、整体推导思路为了彻底搞懂Spring是如何利用三级缓存来解决循环依赖问题的,要么去找三级缓存的设计者了解其设计的初衷,要么利用反推法来进行倒推(即一级缓存为啥不行,二级缓存为啥也不合适)。为了让大家能有一个更清晰的理解脉路,下面将先从反推法来介绍下一级缓存为啥不......
  • 商城项目改进分布式缓存下的登录逻辑和页面展示-----商城项目
    packagecom.alatus.mall.auth.app;importcom.alatus.common.constant.AuthServerConstant;importcom.alatus.common.exception.BizCodeEnum;importcom.alatus.common.utils.R;importcom.alatus.common.vo.MemberRespVo;importcom.alatus.mall.auth.feign.MemberFe......
  • 项目实战:一步步实现高效缓存与数据库的数据一致性方案
    Hello,大家好!我是积极活泼、爱分享技术的小米!今天我们来聊一聊在做个人项目时,如何保证数据一致性。数据一致性问题,尤其是涉及缓存与数据库的场景,可以说是我们日常开发中经常遇到的挑战之一。今天我将以一个简单的场景为例,带大家一步步了解如何解决这个问题——既能高效利用缓存,又能......
  • 【信号传输】DMA传输只能收到一半数据,发送123456 只能收到 123, 发送abcd只能收到ab,缓
    系列文章目录1.元件基础2.电路设计3.PCB设计4.元件焊接5.板子调试6.程序设计7.算法学习8.编写exe9.检测标准10.项目举例11.职业规划文章目录方案一、改DMA中断方案二、改数据类型方案三、改数据长度后记方案一、改DMA中断每个DMA通道都可以在DMA传......