Redis——缓存雪崩

embedded/2024/12/25 11:42:57/

文章目录

  • 1. 问题介绍
  • 2. 解决方案
    • 2.1 方案一:随机过期时间
    • 2.2 方案二:增强 Redis 集群的可用性
    • 2.3 方案三:多级缓存
      • 2.3.1 做法
      • 2.3.2 流程
      • 2.3.3 示例代码
      • 2.3.4 评价
    • 2.4 方案四:限流
  • 3. 总结


1. 问题介绍

缓存雪崩:大量缓存同时过期,或 Redis 宕机,导致大量请求访问 MySQL 数据库,导致其承受不住压力而宕机。

2. 解决方案

从问题介绍中可以发现,对于大量缓存同时过期的情况,只要让缓存的过期时间不同即可;对于 Redis 宕机的情况,则可以通过 增强 Redis (集群) 的可用性、多级缓存、限流 等方案解决。

2.1 方案一:随机过期时间

缓存数据时,给固定的过期时间加上一个随机值,例如对于原本 10min 过期的数据:

java">redisTemplate.opsForValue().set("key", "value", 10, TimeUnit.MINUTES);

通过 new Random().nextInt(10) (获取随机值还可以使用别的方法,并不局限于此) 给它加上一个 60s 以内随机值,从而避免大量数据同时在 10min 这一时刻过期,而是将其分散到 10min 后的 1min 时间段内过期。

java">redisTemplate.opsForValue().set("key", "value", 600 + new Random().nextInt(60), TimeUnit.SECONDS);

2.2 方案二:增强 Redis 集群的可用性

可以通过 Redis 的集群模式或哨兵模式来达到 Redis 的高可用 (之后会讲)。

2.3 方案三:多级缓存

2.3.1 做法

除了使用 Redis 这样的分布式缓存中间件之外,还可以使用 Caffeine、Guava 这样的框架实现应用内部的本地缓存,这样可以减轻 MySQL 的访问压力。

2.3.2 流程

Created with Raphaël 2.3.0 开始 从本地缓存中获取 本地缓存是否为 null? 从 Redis 中获取 Redis 缓存是否为 null? 从数据库中获取 数据库中有没有这个数据? 将数据缓存到 Redis 将数据缓存到本地 返回数据 结束 yes no yes no yes no

2.3.3 示例代码

java">public Order get(long orderId) {// 先从 Caffeine 缓存中获取Order order = caffeineCache.getIfPresent(orderId);if (order == null) {String key = "order:" + orderId;// 如果 Caffeine 缓存未命中,再从 Redis 缓存中获取order = (Order) redisTemplate.opsForValue().get(key);if (order == null) {// 如果 Redis 缓存未命中,从 MySQL 中获取order = orderMapper.getById(orderId);if (order != null) {// 将数据放入 Redis 缓存redisTemplate.opsForValue().set(key, order, 3, TimeUnit.MINUTES);}}if (order != null) {// 将数据放入 Caffeine 缓存caffeineCache.put(orderId, order);}}return order;
}

2.3.4 评价

一般情况下,使用本地缓存的响应时间会少一点,因为避免了分布式缓存的网络 IO 时间。但这种方案实现起来比较复杂 (查询时需要查询两级缓存,更新时也一样),而且由于缓存在本地,还对服务器的内存有一定的要求。

2.4 方案四:限流

限流也可以避免缓存雪崩的问题,通过限制一个接口的访问量,从而防止大量请求通过,压垮 MySQL。

3. 总结

缓存雪崩指的是由于大量缓存同时过期或 Redis 宕机,导致大量请求直接访问 MySQL,以致其宕机的问题。

缓存雪崩还是很好理解的,不同问题的应对方案如下:

  • 对于大量缓存同时过期的问题,可以采取设置随机的过期时间来解决。
  • 对于预防 Redis 宕机,可以通过 Redis 的集群模式或哨兵模式来保证其高可用性。
  • 对于 Redis 宕机后的处理,可以使用多级缓存,在本地也缓存一份数据。
  • 无论应对缓存雪崩的哪种问题,都可以通过限流来解决,防止大量请求访问 MySQL。

http://www.ppmy.cn/embedded/148604.html

相关文章

UE5 物体自动跟随主角镜头转向

A、思路 Tick,设置物体世界旋转 旋转数值源于物体自身位置与玩家摄像机位置的差值 效果是物体自动转向,玩家镜头动,则物体也随之调整角度。 适合一些提示文字,如按键提示、帮助之类。 B、参考图

PHP医院安全(不良)事件管理系统源码,通过运用RCA分析工具,借助柏拉图、鱼骨图等分析工具,分析问题产生的根本原因

医院安全(不良)事件管理系统采用无责的、自愿的填报不良事件方式,有效地减轻医护人员的思想压力,实现以事件为主要对象,可以自动、及时、实际地反应医院的安全、不良、近失事件的情况,更好地掌握不良事件的…

Java 深拷贝全面解析

1. 引言 在 Java 编程中,对象之间的复制是一个常见的需求。根据复制的深度不同,我们可以将复制分为浅拷贝和深拷贝。本文将深入探讨 深拷贝(Deep Copy) 的概念、应用场景、具体实现方法及其优缺点,并提供一些实用的建…

项目开源能够带来什么?从中得到了什么?

开源软件项目的发展趋势和参与经验是一个多维度的话题,涉及技术进步、经济影响、社区动态以及个人成长等多个层面。以下是针对当前开源项目发展趋势的分析,以及参与开源项目时可能获得的经验和收获。 当前开源项目的发展趋势 技术领域的渗透加深&#x…

专业的内外网数据交换方案 可解决安全、效率、便捷3大问题

内外网数据交换是很多企业和行业都会面临的场景,既然隔离了内外网,重中之重就是要确保数据的安全性,其次在数据流转交换过程中,不能太繁琐复杂,需要让用户快速、便捷的进行数据交换。首先我们来看看,在进行…

太速科技-428-基于XC7Z100+ADRV9009的双收双发无线电射频板卡

基于XC7Z100ADRV9009的双收双发无线电射频板卡 一、板卡概述 基于XC7Z100ADRV9009的双收双发无线电射频板卡是基于Xilinx ZYNQ FPGA和ADI的无线收发芯片ADRV9009开发的专用功能板卡,用于5G小基站,无线图传,数据收发等领域。 二…

八股(One Day one)

最近老是看到一些面试的视频,对于视频内部面试所提到的八股文,感觉是知道是什么,但是要说的话,却又不知道该怎么说(要不咋称之为八股文呢),所以就想到写一篇八股文总结的博客,以便进…

2024年华为OD机试真题-字符串变换最小字符串-C++-OD统一考试(E卷)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,持续跟新。 题目描述࿱