程序员面试题之Redis缓存穿透,缓存击穿,缓存雪崩,解决这些问题的关键在于合理设置缓存的过期时间、使用锁机制来保护缓存的加载过程、 使用多级缓存架构和预加载机制来提高系统的容错性和性能。

本文主要是介绍程序员面试题之Redis缓存穿透,缓存击穿,缓存雪崩,解决这些问题的关键在于合理设置缓存的过期时间、使用锁机制来保护缓存的加载过程、 使用多级缓存架构和预加载机制来提高系统的容错性和性能。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AI:please wait...
Redis缓存穿透是指恶意请求绕过缓存直接访问数据库,导致缓存无效,请求大量落到数据库上,造成数据库压力过大。缓存击穿是指缓存中的一个热点数据失效,导致大量请求同时访问数据库,造成数据库压力过大。缓存雪崩是指缓存中的大量数据同时失效,导致大量请求同时访问数据库,造成数据库压力过大。以下是解决这些问题的方法:1. 对于缓存穿透问题,可以使用布隆过滤器(Bloom Filter)来过滤掉无效的请求,
2. 将查询结果为空的请求放入布隆过滤器中,下次请求时先检查布隆过滤器,如果命中则直接返回,避免访问数据库。3. 对于缓存击穿问题,可以在缓存失效的瞬间,通过互斥锁(Mutex Lock)或分布式锁来避免多个请求同时访问数据库,
4. 只允许一个请求重新加载缓存,并在加载完成后释放锁,其他请求再次访问缓存。5. 对于缓存雪崩问题,可以设置缓存的过期时间随机,避免同时失效,或者使用热点数据的时候,
6. 将其缓存时间设置长一些,避免同时失效。另外,可以使用多级缓存架构,将热点数据缓存在多个缓存服务器上,避免单点故障。7. 另外,可以使用预加载机制,在缓存过期前主动去刷新缓存,避免缓存过期期间的请求落到数据库上。总结起来,解决这些问题的关键在于合理设置缓存的过期时间、使用锁机制来保护缓存的加载过程、
使用多级缓存架构和预加载机制来提高系统的容错性和性能。

在这里插入图片描述

在这里插入图片描述

缓存穿透:

Key中对应的缓存数据不存在,导致去请求数据库,造成数据库的压力倍增的情况。

缓存穿透的解决方案

/** 常用的方法可以采用布隆过滤器方法进行数据拦截,其次还有一种解决思路,就是如果请求的数据为空* ,将空值进行缓存,就不会发生穿透的情况*/$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis_key = '';
$result = $redis->get($redis_key);
if(!isset($result)) {//此处应该进行数据库查询...//如果查询结果不存在,给其默认空数组进行缓存$result = [];$redis->set($redis_key, $result, 10000);
}

缓存击穿:

redis过期后的一瞬间,有大量用户请求同一个缓存数据,导致这些请求都去请求数据库,造成数据库压力倍增的情况,针对一个Key而言

缓存击穿的解决方案

/**使用互斥锁(mutex key),就是一个key过期时,多个请求过来允许其中一个请求去操作数据库,* 其他请求等待第一个请求成功返回结果后再请求。*/public function fetch(){$redis = new Redis();$redis->connect('127.0.0.1', 6379);$redis_key = '';$result = $redis->get($redis_key);$redis_key = '|prize_list';$setnx_key = '|prize_list_setnx';$expire = 30;if(!isset($result)) {if($redis->setnx($setnx_key, 1, $expire)) {//此处应该进行数据库查询...//$result = 数据库查询结果;$this->redis->set($redis_key, $result, $expire);$this->redis->del($setnx_key); //删除互斥锁} else {//其他请求每等待10毫秒重新请求一次sleep(10);self::fetch();}}
}

缓存雪崩:

缓存服务器宕机了或者大量缓存集中某个时间段失效,导致请求全部去到数据库,造成数据库压力倍增的情况,这个是针对多个Key而言

缓存雪崩的解决方案

/** 这种情况是因为多个key同时过期导致的数据库压力,一种方法可以在key过期时间基础上增加时间随机数,* 让过期时间分散开,减少缓存时间过期的重复率* 另一种方法是加锁排队,这种有点像上面缓存击穿的解决方式,但是这种请求量太大,* 比如5000个请求过来,4999个都需要等待,这必然是指标不治本,* 不仅用户体验性差,分布式环境下就更加复杂,因此在高并发场景下很少使用** 最好的解决方法,是使用缓存标记,判断该标记是否过期,过期则去请求数据库,* 而缓存数据的过期时间要设置的比缓存标记的长,* 这样当一个请求去操作数据库的时候,其他请求拿的是上一次缓存数据*/public function fetch(){$redis = new Redis();$redis->connect('127.0.0.1', 6379);$redis_key = '';$result = $redis->get($redis_key);$redis_key = '|prize_list';//缓存标记key$cash_key = '|prize_list_cash';$expire = 30;if(!isset($result)) {$cash_result = $redis->get($cash_key);$result = $redis->get($redis_key);if(!$cash_result) {$redis->set($cash_key, 1, $expire);//此处应该进行数据库查询...//$result = 数据库查询结果, 并且设置的时间要比cash_key长,这里设置为2倍;$redis->set($redis_key, $result, $expire * 2);}}
}

这篇关于程序员面试题之Redis缓存穿透,缓存击穿,缓存雪崩,解决这些问题的关键在于合理设置缓存的过期时间、使用锁机制来保护缓存的加载过程、 使用多级缓存架构和预加载机制来提高系统的容错性和性能。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116364

相关文章

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi