当前位置:网站首页>redis——缓存雪崩、缓存穿透、缓存击穿
redis——缓存雪崩、缓存穿透、缓存击穿
2022-07-26 22:40:00 【hayhead】
通常我们为了保证缓存中的数据与数据库中的数据一致性,会给 Redis 里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库,并将数据更新到 Redis 里,这样后续请求都可以直接命中缓存。
缓存雪崩
如果同一时间大量的缓存数据同时过期(失效)或redis服务宕机,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机。
发生缓存雪崩有两个原因
- 大量的缓存数据同时过期(失效)
- redis服务宕机
大量的缓存数据同时过期(失效)的解决方案
1、随机设置过期时间 (TTL)
2、互斥锁
当业务线程在处理用户请求时,如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存(从数据库读取数据,再将数据更新到 Redis 里),当缓存构建完成后,再释放锁。未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
实现互斥锁的时候,最好设置超时时间,不然第一个请求拿到了锁,然后这个请求发生了某种意外而一直阻塞,一直不释放锁,这时其他请求也一直拿不到锁,整个系统就会出现无响应的现象。
3、双 key 策略
我们对缓存数据可以使用两个 key,一个是主 key,会设置过期时间,一个是备 key,不会设置过期,它们只是 key 不一样,但是 value 值是一样的,相当于给缓存数据做了个副本。
当业务线程访问不到「主 key 」的缓存数据时,就直接返回「备 key 」的缓存数据,然后在更新缓存的时候,同时更新「主 key 」和「备 key 」的数据。
4、多级缓存
jvm本地缓存,nginx缓存等
Redis 故障宕机引发的缓存雪崩的解决方案
服务熔断或请求限流机制 (sentinel);
构建 Redis 缓存高可用集群 (主从集群);
缓存击穿
缓存击穿也称(热点key问题),一个被高并发访问且缓存业务重建困难的key突然过期(失效)了,于是全部请求都直接访问数据库,从而导致数据库的压力骤增甚至宕机。
如:tb秒杀活动,wb热榜等

解决方案
1、互斥锁

互斥锁保证同一时间只有一个业务线程更新缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。最后给锁也添加过期时间
redis命令
SETNX KEY_NAME VALUE
使用setIfAbsent,boot2.1版本以上才支持
stringRedisTemplate.opsForValue().setIfAbsent(key, "1",10, TimeUnit.SECONDS);
使用lua脚本
private Boolean tryGetLock1(String key){
/** redisUtil.setIfAbsent 新加的带有超时的setIfAbsent 脚本*/
//KEYS[1] 用来表示在redis 中用作键值的参数占位,
// 主要用來传递在redis 中用作keys值的参数
// ARGV[1] 用来表示在redis 中用作参数的占位,
// 主要用来传递在redis中用做 value值的参数。
String newSetIfAbsentScriptStr = " if 1 == redis.call('setnx',KEYS[1],ARGV[1]) then" +
" return 1;" +
" else" +
" return 0;" +
" end;";
//创建 redis脚本对象
RedisScript<Boolean> newSetIfAbsentScript = new DefaultRedisScript<>(newSetIfAbsentScriptStr,Boolean.class);
List<String> keys = new ArrayList<>();
keys.add(key); // key
Object[] values = {
"1"}; // value
// 执行脚本
Boolean res = stringRedisTemplate.execute(newSetIfAbsentScript, keys, values);
System.out.println("result:"+res);
return res;
}
2、逻辑过期

逻辑过期是指不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间
互斥锁和逻辑过期对比
缓存穿透
缓存穿透是指客户端请求的数据在缓存和数据库中都不存在,于是全部请求都直接访问数据库,从而导致数据库的压力骤增甚至宕机。
存在原因:恶意攻击,故意大量访问某些读取不存在数据的业务
解决方案
1、请求校验
2、缓存空对象
3、布隆过滤器
布隆过滤器校验的结果特点是:
- 若过滤器判断某个元素存在,那么这个元素不一定存在
- 若过滤器判断某个元素不存在,那么这个元素一定不存在
布隆过滤器讲解:https://blog.csdn.net/cssweb_sh/article/details/124284785
边栏推荐
猜你喜欢
随机推荐
关于Redis问题的二三事
The detailed process of reinstalling AutoCAD after uninstallation and deleting the registry
[HarekazeCTF2019]encode_ and_ encode
[ciscn2019 North China Day1 web5] cyberpunk
Two or three things about redis
JSCORE day_01(6.30) RegExp 、 Function
Only hard work, hard work and hard work are the only way out C - patient entity class
JSCORE day_ 01(6.30) RegExp 、 Function
Canal 介绍
MySQL common functions (summary)
[RootersCTF2019]I_< 3_ Flask
[qt] container class, iterator, foreach keyword
Search engine realizes keyword highlighting
logback自定义MessageConverter
2022.7.16DAY606
DOM day_04(7.12)BOM、打开新页面(延迟打开)、地址栏操作、浏览器信息读取、历史操作
[4.1 prime number and linear sieve]
flinksql 窗口提前触发
[HITCON 2017]SSRFme
关于Thymeleaf的表达式

![[HarekazeCTF2019]encode_ and_ encode](/img/f5/c06523a1764717bdf2d91f069c9d77.png)

![[ciscn2019 North China Day1 web5] cyberpunk](/img/84/b186adc8becfc9b3def7dfd8e4cd41.png)
![[CTF攻防世界] WEB区 关于备份的题目](/img/af/b78eb3522160896d77d9e82f7e7810.png)
![[SQL注入] 联合查询](/img/82/37008a1ecb4bb37bea42443dbb9be6.png)
![[hongminggu CTF 2021] write_ shell](/img/f5/c3a771ab7b40311e37a056defcbd78.png)
