redis缓存雪崩,缓存穿透,缓存击穿的解决方法
一、缓存雪崩
缓存雪崩表示在某一时间段,缓存集中失效,导致请求全部走数据库,有可能搞垮数据库,使整个服务瘫痪。
使缓存集中失效的原因:
1、redis服务器挂掉了。
2、对缓存数据设置了相同的过期时间,导致某时间段内缓存集中失效。
如何解决缓存集中失效:
1、针对原因1,可以实现redis的高可用,Redis Cluster 或者 Redis Sentinel(哨兵) 等方案。
2、针对原因2,设置缓存过期时间时加上一个随机值,避免缓存在同一时间过期。
<?php $redis = new Redis();
$redis->connect('127.0.0.1', 6379, 60);
$redis->auth(''); //设置过期时间加上一个随机值
$redis->set('article_content_1', '文章内容', 60 + mt_rand(1, 60));
$redis->set('article_content_2', '文章内容', 60 + mt_rand(1, 60));
3、使用双缓存策略,设置两个缓存,原始缓存和备用缓存,原始缓存失效时,访问备用缓存,备用缓存失效时间设置长点。
//原始缓存
$redis->set('article_content_2', '文章内容', 60);
//设置备用缓存,失效时间设置长点
$redis->set('article_content_backup_2', '文章内容', 1800);
二、缓存穿透
缓存穿透表示查询一个一定不存在的数据,由于没有获取到缓存,所以没写入缓存,导致这个不存在的数据每次都需要去数据库查询,失去了缓存的意义。
请求的数据大量的没有获取到缓存,导致走数据库,有可能搞垮数据库,使整个服务瘫痪。
比如文章表,一般我们的主键ID都是无符号的自增类型,有些人想要搞垮你的数据库,每次请求都用负数ID,而ID为负数的记录在数据库根本就没有。
解决方案:
1、对于像ID为负数的非法请求直接过滤掉,采用布隆过滤器(Bloom Filter)。
2、针对在数据库中找不到记录的,我们仍然将该空数据存入缓存中,当然一般会设置一个较短的过期时间。
//设置文章ID为-10000的缓存为空
$id = -10000;
$redis->set('article_content_' . $id, '', 60); var_dump($redis->get('article_content_' . $id));
三、缓存击穿
缓存击穿表示某个key的缓存非常热门,有很高的并发一直在访问,如果该缓存失效,那同时会走数据库,压垮数据库。
缓存击穿与缓存雪崩的区别是这里针对的是某一热门key缓存,而雪崩针对的是大量缓存的集中失效。
解决方案:
1、让该热门key的缓存永不过期。
2、使用互斥锁,通过redis的setnx实现互斥锁。
<?php function getRedis()
{
$redis = new Redis();
$redis->connect('127.0.0.1', 6379, 60);
return $redis;
} //加锁
function lock($key, $random)
{
$redis = getRedis();
//设置锁的超时时间,避免释放锁失败,del()操作失败,产生死锁。
$ret = $redis->set($key, $random, ['nx', 'ex' => 3 * 60]);
return $ret;
} //解锁
function unLock($key, $random)
{
$redis = getRedis();
//这里的随机数作用是,防止更新缓存操作时间过长,超过了锁的有效时间,导致其他请求拿到了锁。
//但上一个请求更新缓存完毕后,如果不加判断直接删除锁,就会误删其他请求创建的锁。
if ($redis->get($key) == $random) {
$redis->del($key);
}
} //从缓存中获取文章数据
function getArticleInCache($id)
{
$redis = getRedis();
$key = 'article_content_' . $id;
$ret = $redis->get($key);
if ($ret === false) {
//生成锁的key
$lockKey = $key . '_lock';
//生成随机数,用于设置锁的值,后面释放锁时会用到
$random = mt_rand();
//拿到互斥锁
if (lock($lockKey, $random)) {
//这里是伪代码,表示从数据库中获取文章数据
$value = $db->getArticle($id);
//更新缓存,过期时间可以根据情况自已调整
$redis->set($key, $value, 2 * 60);
//释放锁
unLock($lockKey, $random);
} else {
//等待200毫秒,然后重新获取缓存值,让其他获取到锁的进程取得数据并设置缓存
usleep(200);
getArticleInCache($id);
}
} else {
return $ret;
}
}
redis缓存雪崩,缓存穿透,缓存击穿的解决方法的更多相关文章
- 8.了解什么是 redis 的雪崩、穿透和击穿?redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 redis 的穿透?
作者:中华石杉 面试题 了解什么是 redis 的雪崩.穿透和击穿?redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 redis 的穿透? 面试官心理分析 其实这是问到缓存必问的,因为缓 ...
- redis缓存雪崩、穿透、击穿概念及解决办法
缓存雪崩 对于系统 A,假设每天高峰期每秒 5000 个请求,本来缓存在高峰期可以扛住每秒 4000 个请求,但是缓存机器意外发生了全盘宕机.缓存挂了,此时 1 秒 5000 个请求全部落数据库,数据 ...
- Redis 缓存雪崩、穿透、击穿
缓存雪崩 定义: 同一时间所有 key 大面积失效,比如网站首页的数据基本上都是同一批次去缓存的. 解决方法: ① 存的时候设定随机的失效时间. ② 服务做熔断处理(异常或着慢查询 Hystrix 限 ...
- 什么是 redis 的雪崩、穿透和击穿?
缓存雪崩 对于系统 A,假设每天高峰期每秒 5000 个请求,本来缓存在高峰期可以扛住每秒 4000 个请求,但是缓存机器意外发生了全盘宕机.缓存挂了,此时 1 秒 5000 个请求全部落数据库,数据 ...
- Redis 雪崩、穿透和击穿
https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/redis-caching-avalanche-and ...
- 什么是redis的雪崩和穿透
缓存雪崩 如何应对缓存雪崩 首先要保证redis的高可用,可以使用redis cluster,开启redis持久化,redis之前要使用本地缓存,请求先走本地缓存,没找到再走redis 如果还是出现了 ...
- SRX550路由器缓存满了无法在web页面操作解决方法
SRX550路由器缓存满了无法在web页面操作解决方法 首页出现下图为满的标志,我这个文档就是解决这中情况,让web页面可以操作的 1. 打开命令行,输入用户密码,进入路由器 注意:这里使用te ...
- Redis 雪崩、穿透、击穿、并发、缓存讲解以及解决方案
1.缓存雪崩 数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机. 比如一个雪崩的简单过程 1.redis集群大面积故障 2.缓存 ...
- Redsi缓存问题(穿透,击穿,雪崩)以及解决办法(分布式锁)【高并发问题】
Redsi常见问题 缓存在高平发和安全压力下的一些问题 缓存击穿 是某一个热点key在高并发访问的情况下,突然失效,导致大量的并发大金mysql数据库的情况 缓存穿透 是利用redis和mysql的机 ...
随机推荐
- Layout-3相关代码:3列布局代码演化三]
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- C#实现json压缩和格式化
json作为常用数据文件,为了传输的效率,在传输前要进行压缩,而在传输后要进行格式化,以便阅读.下面是使用C#完成的格式化和压缩代码. public static string Compress(st ...
- 【HDFS API编程】从本地拷贝文件,从本地拷贝大文件,拷贝HDFS文件到本地
接着之前继续API操作的学习 CopyFromLocalFile: 顾名思义,从本地文件拷贝 /** * 使用Java API操作HDFS文件系统 * 关键点: * 1)create Configur ...
- Flask对数据库的操作-----
首先得做好做基本的框架 # -*- encoding: utf-8 -*- from flask import Flask,render_template #导入第三方连接库sql点金术 from f ...
- JavaScript字符串操作方法大全,包含ES6方法
一.charAt() 返回在指定位置的字符. var str="abc" console.log(str.charAt(0))//a 二.charCodeAt() 返回在指定的位置 ...
- word文档转pdf,支持.doc和.docx,另附抽取pdf指定页数的方法
公司有个需求,需要将word转成pdf并且抽取首页用以展示,word文档有需要兼容.doc和.docx两种文档格式.其中.docx通过poi直接就可以将word转成pdf,.doc则无法这样实现,上网 ...
- FireDac 同时连接SQLserver2000时出现 Connection is busy with results for another command
First chance exception at $763FC632. Exception class EMSSQLNativeException with message '[FireDAC][P ...
- Linux命令:source
语法 source filename 说明 . 的同义词
- 排序大集合java
今日面试被问到排序问题,发现自己的不足,特来查漏补缺: 首先是各大排序算法的总结表 排序算法大合集 排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 稳定性 冒泡排序 Ο(n2) Ο(n) ...
- ArcPy开发教程2-管理地图文档1
联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com ArcPy开发教程2-管理地图文档1 第二次课:2019年2月26日上午第二节 讲解: 地图文档:Map docume ...