Redis缓存详解:缓存穿透,缓存击穿,缓存雪崩 (面试&复习)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 参考了redis的相关学习课程,缓存穿透,缓存击穿,缓存雪崩,缓存预热,并总结了一些redis实战过程中的高频面试题,模拟了一些实际业务场景。

♨️本篇文章记录的为Redis知识中缓存穿透,缓存击穿,缓存雪崩,缓存预热中秒杀相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。
♨️如果文章有什么需要改进的地方还请大佬不吝赐教❤️🧡💛

👨‍🔧个人主页 : 阿千弟
💖点击这里👉👉👉: Redis专栏学习

前言:
参考了redis的相关学习课程,并总结了一些redis实战过程中的高频面试题,模拟了一些实际业务场景
在这里插入图片描述
@[TOC]

文章目录:

🎠 缓存更新策略

数据库和缓存不一致采用什么方案

综合考虑使用方案一,但是方案一调用者如何处理呢?这里有几个问题

操作缓存和数据库时有三个问题需要考虑:

如果采用第一个方案,那么假设我们每次操作数据库后,都操作缓存,但是中间如果没有人查询,那么这个更新动作实际上只有最后一次生效,中间的更新动作意义并不大,我们可以把缓存删除,等待再次查询时,将缓存中的数据加载出来

  • 删除缓存还是更新缓存?
    • 更新缓存:每次更新数据库都更新缓存,无效写操作较多
    • 删除缓存:更新数据库时让缓存失效,查询时再更新缓存
  • 如何保证缓存与数据库的操作的同时成功或失败?
    • 单体系统,将缓存与数据库操作放在一个事务
    • 分布式系统,利用 TCC 等分布式事务方案

应该具体操作缓存还是操作数据库,我们应当是先操作数据库,再删除缓存,原因在于,如果你选择第一种方案,在两个线程并发来访问时,假设线程 1 先来,他先把缓存删了,此时线程 2 过来,他查询缓存数据并不存在,此时他写入缓存,当他写入缓存后,线程 1 再执行更新动作时,实际上写入的就是旧的数据,新的数据被旧数据覆盖了。

  • 先操作缓存还是先操作数据库?
    • 先删除缓存,再操作数据库
    • 先操作数据库,再删除缓存
      在这里插入图片描述

🔥缓存预热

场景:“宕机” 服务器启动后迅速宕机

🔥问题排查:

1.请求数量较高,大量的请求过来之后都需要去从缓存中获取数据,
但是缓存中又没有,此时从数据库中查找数据然后将数据再存入缓存,
造成了短期内对redis的高强度操作从而导致问题

2.主从之间数据吞吐量较大,数据同步操作频度较高

🔥解决方案:

前置准备工作:
1.日常例行统计数据访问记录,统计访问频度较高的热点数据
2.利用LRU数据删除策略,构建数据留存队列例如:storm与kafka配合

准备工作:
1.将统计结果中的数据分类,根据级别,redis优先加载级别较高的热点数据
2.利用分布式多服务器同时进行数据读取,提速数据加载过程
3.热点数据主从同时预热

实施:
4.使用脚本程序固定触发数据预热过程
5.如果条件允许,使用了CDN(内容分发网络),效果会更好

🔥总的来说:

缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

🎠 缓存穿透

在这里插入图片描述

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,不断发起这样的请求,这些请求都会打到数据库,给数据库带来巨大压力。

🥝常见的解决方案有两种

  • ♨缓存空对象
    • 优点:
      • 实现简单,维护方便
    • 缺点:
       - 额外的内存消耗
      
      • 可能造成短期的不一致
  • ♨布隆过滤
    • 优点:
      • 内存占用较少,没有多余 key
    • 缺点:
      • 实现复杂
      • 存在误判可能

🥝面试场景hr:数据库服务器又崩溃了,跟之前的一样吗?

1.系统平稳运行过程中
2.应用服务器流量随时间增量较大
3.Redis服务器命中率随时间逐步降低
4.Redis内存平稳,内存无压力
5.Redis服务器CPU占用激增
6.数据库服务器压力激增
7.数据库崩溃

🥝问题排查:

1.Redis中大面积出现未命中
2.出现非正常URL访问

🥝问题分析:

1. 获取的数据在数据库中也不存在,数据库查询未得到对应数据
2.Redis获取到null数据未进行持久化,直接返回
3.下次此类数据到达重复上述过程
4.出现黑客攻击服务器

🥝解决方案:

1.缓存null值
2.布隆过滤
3.增强id的复杂度,避免被猜测id规律
4.做好数据的基础格式校验
5.加强用户权限校验
6.做好热点参数的限流

在这里插入图片描述

❄️缓存雪崩

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力

在这里插入图片描述

❄️场景:数据库服务器崩溃,一连串的场景会随之儿来

1.系统平稳运行过程中,忽然数据库连接量激增
2.应用服务器无法及时处理请求
3.大量408,500错误页面出现
4.客户反复刷新页面获取数据
5.数据库崩溃
6.应用服务器崩溃
7.重启应用服务器无效
8.Redis服务器崩溃
9.Redis集群崩溃
10.重启数据库后再次被瞬间流量放倒

❄️问题排查:

1.在一个较短的时间内,缓存中较多的key集中过期
2.此周期内请求访问过期的数据,redis未命中,redis向数据库获取数据
3.数据库同时接收到大量的请求无法及时处理
4.Redis大量请求被积压,开始出现超时现象
5.数据库流量激增,数据库崩溃
6.重启后仍然面对缓存中无数据可用
7.Redis服务器资源被严重占用,Redis服务器崩溃
8.Redis集群呈现崩塌,集群瓦解
9.应用服务器无法及时得到数据响应请求,来自客户端的请求数量越来越多,应用服务器崩溃
10.应用服务器,redis,数据库全部重启,效果不理想    

总而言之就两点:短时间范围内,大量key集中过期

❄️解决方案:

1.给不同的Key的TTL添加随机值

2.利用Redis集群提高服务的可用性

3.给缓存业务添加降级限流策略
(短时间范围内牺牲一些客户体验,限制一部分请求访问,
降低应用服务器压力,待业务低速运转后再逐步放开访问)

4.给业务添加多级缓存(Nginx缓存+redis缓存+ehcache缓存)

5.检测Mysql严重耗时业务进行优化
(对数据库的瓶颈排查:例如超时查询、耗时较高事务等)

❄️落地实践:

1.LRU与LFU切换

2.数据有效期策略调整:
根据业务数据有效期进行分类错峰,A类90分钟,B类80分钟,C类70分钟
过期时间使用固定时间+随机值的形式,稀释集中到期的key的数量

3.超热数据使用永久key

4.定期维护(自动+人工)
 对即将过期数据做访问量分析,确认是否延时,配合访问量统计,做热点数据的延时

5.加锁:慎用!

❄️总的来说:

缓存雪崩就是瞬间过期数据量太大,导致对数据库服务器造成压力。如能够有效避免过期时间集中,可以有效解决雪崩现象的出现(约40%),配合其他策略一起使用,并监控服务器的运行数据,根据运行记录做快速调整。

在这里插入图片描述

⚡缓存击穿

缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。

⚡场景:还是数据库服务器崩溃,但是跟之前的场景有点不太一样

1.系统平稳运行过程中
2.数据库连接量瞬间激增
3.Redis服务器无大量key过期
4.Redis内存平稳,无波动
5.Redis服务器CPU正常
6.数据库崩溃

⚡问题排查:

1.Redis中某个key过期,该key访问量巨大    
2.多个数据请求从服务器直接压到Redis后,均未命中
3.Redis在短时间内发起了大量对数据库中同一数据的访问

总而言之就两点:单个key高热数据,key过期

⚡解决方案:

1.预先设定    
​ 以电商为例,每个商家根据店铺等级,指定若干款主打商品,在购物节期间,
加大此类信息key的过期时长 注意:购物节不仅仅指当天,以及后续若干天,
访问峰值呈现逐渐降低的趋势

2.现场调整
​ 监控访问量,对自然流量激增的数据延长过期时间或设置为永久性key

3.后台刷新数据
​ 启动定时任务,高峰期来临之前,刷新数据有效期,确保不丢失

4.二级缓存
​ 设置不同的失效时间,保障不会被同时淘汰就行

5.加锁​&逻辑过期     (重点)
分布式锁,防止被击穿,但是要注意也是性能瓶颈,慎重!
  • ♟️互斥锁

    • 优点
      • 没有额外的内存消耗
      • 保证一致性
      • 实现简单
    • 缺点
      • 线程需要等待,性能受影响
      • 可能有死锁风险
        在这里插入图片描述
  • ♟️逻辑过期

    • 优点
      • 线程无需等待,性能较好
        • 缺点
      • 不保证一致性
      • 有额外内存消耗
      • 实现复杂
        在这里插入图片描述

⚡总的来说:

缓存击穿就是单个高热数据过期的瞬间,数据访问量较大,未命中redis后,发起了大量对同一数据的数据库访问,导致对数 据库服务器造成压力。应对策略应该在业务数据分析与预防方面进行,配合运行监控测试与即时调整策略,毕竟单个key的过期监控难度较高,配合雪崩处理策略即可。

在这里插入图片描述

如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对Java后端或者对redis感兴趣的朋友,请多多关注💖💖💖
👨‍🔧个人主页:阿千弟
如果大家对redis相关知识感兴趣请点击这里👉👉👉redis专栏学习

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1天前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文介绍了缓存穿透问题在分布式系统和缓存应用中的严重性,当请求的数据在缓存和数据库都不存在时,可能导致数据库崩溃。为解决此问题,提出了五种策略:接口层增加校验、缓存空值、使用布隆过滤器、数据库查询优化和加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统稳定性的影响。
47 3
|
1天前
|
缓存 NoSQL 中间件
中间件缓存击穿和缓存雪崩
中间件缓存击穿和缓存雪崩
10 3
|
2天前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中可能出现的问题及其解决方案。首先,缓存穿透是指查询数据库中不存在的数据,导致请求频繁到达数据库。解决方法包括数据校验、缓存空值和使用BloomFilter。其次,缓存击穿是大量请求同一失效缓存项,可采取监控、限流或加锁策略。再者,缓存雪崩是大量缓存同时失效,引发数据库压力。应对措施是避免同一失效时间,分散缓存过期。接着,文章介绍了Spring Boot中Redis缓存的配置,包括缓存null值以防止穿透,并展示了自定义缓存过期时间的实现,以避免雪崩效应。最后,提供了在`application.yml`中配置不同缓存项的个性化过期时间的方法。
|
6天前
|
缓存 监控 数据库
分布式系统中缓存穿透问题与解决方案
在分布式系统中,缓存技术被广泛应用以提高系统性能和响应速度。然而,缓存穿透是一个常见而严重的问题,特别是在面对大规模请求时。本文将深入探讨缓存穿透的原因、影响以及一些有效的解决方案,以确保系统在面对这一问题时能够保持稳定和高效。
30 13
|
10天前
|
缓存 NoSQL Java
springboot业务开发--springboot集成redis解决缓存雪崩穿透问题
该文介绍了缓存使用中可能出现的三个问题及解决方案:缓存穿透、缓存击穿和缓存雪崩。为防止缓存穿透,可校验请求数据并缓存空值;缓存击穿可采用限流、热点数据预加载或加锁策略;缓存雪崩则需避免同一时间大量缓存失效,可设置随机过期时间。文章还提及了Spring Boot中Redis缓存的配置,包括缓存null值、使用前缀和自定义过期时间,并提供了改造代码以实现缓存到期时间的个性化设置。
|
10天前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中的三个问题:缓存穿透、缓存击穿和缓存雪崩。为解决这些问题,提出了相应策略。对于缓存穿透,建议数据校验和缓存空值;缓存击穿可采用监控扩容、服务限流或加锁机制;缓存雪崩则需避免大量缓存同时过期,可设置随机过期时间。此外,文章还介绍了Spring Boot中Redis缓存配置,包括全局设置及自定义缓存过期时间的方法。
|
16天前
|
缓存 NoSQL 算法
Redis入门到通过之解决Redis缓存击穿、缓存穿透、缓存雪崩
Redis入门到通过之解决Redis缓存击穿、缓存穿透、缓存雪崩
20 0
|
5天前
|
存储 消息中间件 缓存
Redis缓存技术详解
【5月更文挑战第6天】Redis是一款高性能内存数据结构存储系统,常用于缓存、消息队列、分布式锁等场景。其特点包括速度快(全内存存储)、丰富数据类型、持久化、发布/订阅、主从复制和分布式锁。优化策略包括选择合适数据类型、设置过期时间、使用Pipeline、开启持久化、监控调优及使用集群。通过这些手段,Redis能为系统提供高效稳定的服务。
|
11天前
|
存储 缓存 NoSQL
【Go语言专栏】Go语言中的Redis操作与缓存应用
【4月更文挑战第30天】本文探讨了在Go语言中使用Redis进行操作和缓存应用的方法。文章介绍了Redis作为高性能键值存储系统,用于提升应用性能。推荐使用`go-redis/redis`库,示例代码展示了连接、设置、获取和删除键值对的基本操作。文章还详细阐述了缓存应用的步骤及常见缓存策略,包括缓存穿透、缓存击穿和缓存雪崩的解决方案。利用Redis和合适策略可有效优化应用性能。
|
14天前
|
存储 缓存 NoSQL
Redis多级缓存指南:从前端到后端全方位优化!
本文探讨了现代互联网应用中,多级缓存的重要性,特别是Redis在缓存中间件的角色。多级缓存能提升数据访问速度、系统稳定性和可扩展性,减少数据库压力,并允许灵活的缓存策略。浏览器本地内存缓存和磁盘缓存分别优化了短期数据和静态资源的存储,而服务端本地内存缓存和网络内存缓存(如Redis)则提供了高速访问和分布式系统的解决方案。服务器本地磁盘缓存因I/O性能瓶颈和复杂管理而不推荐用于缓存,强调了内存和网络缓存的优越性。
40 1