首页 > 数据库 >06、Redis相关概念:缓存击穿、雪崩、穿透、预热、降级、一致性等

06、Redis相关概念:缓存击穿、雪崩、穿透、预热、降级、一致性等

时间:2025-01-22 13:56:47浏览次数:3  
标签:缓存 06 数据库 Redis 查询 线程 数据

Redis相关概念:缓存击穿、雪崩、穿透、预热、降级、一致性等

Redis缓存雪崩、缓存击穿、缓存预热热点key、缓存降级、短链接、分布式锁秒杀、预减库存、
堆外缓存+Redis架构设计、Redis动态刷新、Redis和DB双写一致性、过期删除策略、集群数据倾斜等

一、缓存雪崩

    缓存雪崩是指当缓存中的大量数据在同一时间失效,导致大量请求直接访问数据库,从而引起数据库的压力过大,
严重影响系统的性能。
   redis 主机挂了, Redis全盘崩溃,偏硬件运维
   redis 中有大量key 同时过期大面积失效,偏软件开发

1、缓存数据的随机过期时间

在缓存数据的过期时间上增加随机因素,从而避免大量数据在同一时间失效的情况
 //将数据缓存到Redis中,并增加随机的过期时间
 //int random = new Random().nextInt(600) + 600;

2、预热缓存

在系统启动时预热缓存,将系统中的热点数据提前加载到缓存中,从而避免了大量请求同时访问数据库的情况。
@Component
public class AdmdvsDimCacheManager implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        //预热处理
    }

}

3、分布式锁

使用分布式锁,从而避免大量请求同时访问数据库的情况。
public List<User> getUserList() {
    List<User> userList = redisTemplate.opsForValue().get("userList");
    if (userList == null) {
        // 如果Redis中不存在,则尝试获取分布式锁
        RLock lock = redissonClient.getLock("userListLock");
        try {
            // 尝试加锁,并设置锁的过期时间为5秒
            boolean success = lock.tryLock(5, TimeUnit.SECONDS);
            if (success) {
                // 如果获取到了锁,则查询数据库并将数据缓存到Redis中
                userList = userDao.getUserList();
                if (userList != null && userList.size() > 0) {
                    redisTemplate.opsForValue().set("userList", userList, 1, TimeUnit.HOURS);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            lock.unlock
        }
    } return userList;
}

二、缓存击穿

    缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无 数的请求访问会在瞬间给数据库带来巨大的冲击。
    描述:假设线程1在查询缓存之后,本来应该去查询数据库,然后把这个数据重新加载到缓存的, 此时只要线程1走完这个逻辑,其他线程就都能从缓存中加载这些数据了,但
是假设在线程1没有走完的 时候,后续的线程2,线程3,线程4同时过来访问当前这个方法, 那么这些线程都不能从缓存中查询到 数据,那么他们就会同一时刻来访问查询缓存,
都没查到,接着同一时间去访问数据库,同时的去执行 数据库代码,对数据库访问压力过大.

1、互斥锁

   如果未命中缓存,先获取互斥锁,获取锁之后要再次检查缓存,如果还是未命中进行缓存重建,这样当其他线程来的时候就会获取锁失败,这时我们让这个线程休眠一会,重新
查询缓存,如果命中就返回嘛,如果没命中再次尝试获取锁,假设这次获取锁成功了,还是再次检查缓存,如果未命中重建缓存。
  
   描述:假设现在线程1过来访问,他查询缓存没有命中,但是此时他获得到了锁的资源,那么线程1就会一个人 去执行逻辑,假设现在线程2过来,线程2在执行过程中,并没有
获得到锁,那么线程2就可以进行到休 眠,直到线程1把锁释放后,线程2获得到锁,然后再来执行逻辑,此时就能够从缓存中拿到数据了。

  优点:可保证数据高一致性

  缺点:性能低,可能发生死锁

在这里插入图片描述

2、逻辑过期

 我们把过期时间设置在 redis的value中,注意:这个过期时间并不会直接作用于redis,而是我们后续 通过逻辑去处理。假设线程1去查询缓存,然后从value中判断出来当
前的数据已经过期了,此时线程1 去获得互斥锁,那么其他线程会进行阻塞,获得了锁的线程他会开启一个 线程去进行 以前的重构数据 的逻辑,直到新开的线程完成这个逻辑
后,才释放锁, 而线程1直接进行返回,假设现在线程3过来访 问,由于线程线程2持有着锁,所以线程3无法获得锁,线程3也直接返回数据,只有等到新开的线程2把 重建数据构
建完后,其他线程才能走返回正确的数据。

  优点:性能高

  缺点:数据可能不一致,实现复杂

在这里插入图片描述

三、缓存穿透

   缓存穿透是指查询一个不存在的数据,由于缓存中没有数据,请求会直接穿透到数据库中,从而引起数据库的压力过大,严重影响系统的性能。

1、布隆过滤器

   布隆过滤器是一种高效的数据结构,可以判断一个元素是否存在于一个集合中,同时也可以减轻数据库的压力。在使用布隆过滤器的时候,首先将所有的数据hash到一个位图
中,如果查询的数据在位图中不存在,那么直接返回不存在,从而避免了对数据库的查询操作。

  优点:内存占用较少,没有多余key

  缺点:实现复杂,存在误判可能

在这里插入图片描述

2、空对象存储

    采用空对象缓存的方式,即当查询的数据不存在时,将一个空对象缓存到Redis中。这样下次查询同样不存在的数据时,就可以直接从Redis中获取到一个空对象,从而避免了
对数据库的查询操作。

优点:实现简单,方便维护

缺点:占内存,可能造成短期数据不一致

在这里插入图片描述

四、缓存预热热点KEY

    缓存预热是指在系统启动或者高峰期之前,提前将数据加载到缓存中,避免在用户请求的时候,先查询数据库(这样第一个查询的人就会比较慢),再把查询结果回写到redis
当中去。
   通过LRU数据删除策略,可以得到高频数据队列。
   通过脚本的方式将热点数据提前加入。
处理方案:

1、配置一个job定时刷新数据缓存。

2、直接写个缓存刷新页面,上线后手动刷新。

3、项目启动的时候直接将热点KEY缓存到redis

五、缓存降级

    当站点的访问量剧增、服务出现卡顿问题或非关键服务影响到关键流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,
放弃一些不重要的加载项,也可以配置开关实现人工降级。

降级的最终目的是保证关键核心服务的正常运行,比如涉及财务的网站购物的购物车,结算等重要模块,是不能降级的。

六、缓存一致性

缓存一致性指的是缓存与DB之间的数据一致性,我们需要通过各种手段来防止缓存与DB不一致,我们要保证缓存与DB的数据一致或者数据最终一致。
处理方案:

1.数据库层:

在数据库层面,可以使用事务来确保数据的一致性。通过将读写操作放在同一个事务中,可以保证数据的更新和查询是一致的。
使用数据库的触发器或者存储过程,在数据更新的同时,主动触发缓存的更新操作,确保缓存与数据库的数据保持一致。

2.缓存层:

在缓存层面,可以使用缓存更新策略,通过定时任务、异步消息队列等方式,定期或者在数据更新时异步地更新缓存,保持缓存与数据库的数据一致性。
使用互斥锁或者分布式锁来保证对缓存的读写操作的原子性,避免数据冲突。
设置合适的缓存过期时间,避免缓存数据长时间过期而导致数据不一致的问题。

3.应用层:

在应用层面,可以采用读写分离策略,将读请求和写请求分发到不同的节点,读请求直接从缓存中获取数据,写请求则更新数据库并更新缓存,保持数据的一致性。
使用缓存中间件或者缓存组件,提供自动更新缓存的功能,减少手动维护缓存的复杂性。

4.监控和报警:

建立监控和报警机制,通过监控缓存层和数据库层的状态、数据一致性等指标,及时发现异常情况,并触发报警,以便及时处理问题。

标签:缓存,06,数据库,Redis,查询,线程,数据
From: https://blog.csdn.net/pilot_speed/article/details/145299996

相关文章

  • 详解Redis的Zset类型及相关命令
    目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZPOPMAXBZPOPMAXZPOPMINBZPOPMINZRANKZREVRANKZSCOREZREMZREMRANGEBYRANKZREMRANGEBYSCOREZINCRBYZINTERSTORE内部编码应用场景Zset简介有序集合相对于字符串、列表、哈希、集合来说会有......
  • Redis内存淘汰策略
    Redis是一个高性能的键值存储系统,它支持多种数据结构,如字符串、列表、集合、有序集合等。由于Redis是基于内存的存储系统,因此它的速度非常快。然而,内存资源是有限的,当Redis的内存使用量达到一定阈值时,就需要采取一些策略来管理内存,以确保系统的稳定性和性能。这就是Redis......
  • 关于此题CF2061E_Kevin and And的一些总结
    传送门题目大意:给定\(n\)个数\(a[1...n]\)和\(m\)个数\(b[1...m]\),并且给定整数k,求让任意\(i,j\)使\(a[i]&b[j]\)来替代\(a[i]\)后这\(n\)个数总和最小。首先我们看到题目给的m范围非常小,最大只有10,然后又问我们k次操作之后总和的最小值,第一反应是不是可以直接先求出每个\(a[i]......
  • 带 `$` 符号的 Redis 密码在 Flink 调度脚本中被截断的解决方案 WRONGPASS invalid us
    在实际生产使用中,如果你的Redis密码中包含$符号,而你又通过调度脚本(如DolphinScheduler)或Shell参数方式传递给Flink,就可能造成密码被部分截断,进而导致:WRONGPASSinvalidusername-passwordpairoruserisdisabled这是因为Shell解释$为变量展开符,后续字符被当作环......
  • 【教学类-13-06】20240119数字色块图的代码优化-简化代码路径+班级位置空缺
    背景需求:第一笔有客户购买“9图的数字像素图”,我都没有在百度网盘里备份。  ​​​​​​​打开代码文件夹,发现生成的PDF很多,不知道是哪一个?找到是这份,可是里面有大1班了,客户不一定是大1班。所以word模版的班级要空着,就需要修改模版删除中3的文字,按四个空格(2个汉......
  • 随身 WiFi 的 R106 卡槽焊接与开孔:网络连接的新起点
    随身WiFi相关(程序+源码+工具+调试部署+开发环境)总共500多GB以上,文章末尾可获取,在最后面了。随身WiFi的R106已焊接卡槽并开好卡槽孔,说明该设备已经具备了使用特定SIM卡进行网络连接的基础条件。以下是关于此情况的一些分析和建议:优势方面使用便利性提升:开好卡槽孔后......
  • Redis数据库笔记——ZSet的底层实现(跳表)
    大家好,这里是GoodNote,关注公主号:Goodnote,专栏文章私信限时Free。本文详细介绍ZSet数据类型中跳表的底层实现,包括基本特点和常用操作。文章目录ZSet(有序集合)概述基本特点底层实现Skiplist跳表概述结构跳表的基本操作1.查找操作:`Search`2.插入操作:`Insert`3.删......
  • 关于Redisson分布式锁的用法
    一、前言在分布式系统中,多个节点可能会同时访问共享资源,导致数据不一致的问题。分布式锁是解决这些问题的一种有效机制。Redisson是一个基于Redis的Java客户端,不仅提供了丰富的分布式数据结构,还实现了分布式锁功能。本文将详细介绍Redisson分布式锁的用法,包括其配置、基本用法和......
  • Redis Stream:实时数据流的处理与存储
    RedisStream是Redis5.0引入的一个强大的数据结构,专门用于处理实时数据流。它类似于ApacheKafka和RabbitMQ等消息队列系统,但集成在Redis这个内存数据库中,使得Redis不仅能处理缓存和存储,还能高效地处理实时数据流。本文将深入探讨RedisStream的特性、使用方法以及......
  • 怎样实现每次页面打开时都清除本页缓存?
    在前端开发中,有多种方法可以在每次页面打开时清除页面缓存。以下是一些建议的方法:使用Meta标签:在HTML的<head>部分,你可以使用<meta>标签来控制缓存行为。通过设置Cache-Control和Pragma为no-cache,以及Expires为0,你可以告诉浏览器不要缓存页面内容。<metahttp-equiv="Cache-C......