当前位置:网站首页>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
边栏推荐
- JSCORE day_ 03(7.4)
- [watevrCTF-2019]Cookie Store
- [HarekazeCTF2019]encode_and_encode
- [NPUCTF2020]ezinclude
- Canal 介绍
- Detailed explanation of CSRF forged user request attack
- Point to plane projection
- [qt] container class, iterator, foreach keyword
- Elaborate on the differences and usage of call, apply and bind 20211031
- Flink checkpoint源码理解
猜你喜欢

Operator overloading
![[HFCTF2020]EasyLogin](/img/23/91912865a01180ee191a513be22c03.png)
[HFCTF2020]EasyLogin

2022.7.14DAY604

Dynamic binding, static binding, and polymorphism

Use of postman

Flink 1.15实现 Sql 脚本从savepointh恢复数据

Medical data of more than 4000 people has been exposed for 16 years

Use csrftester to automatically detect CSRF vulnerabilities

JSCORE day_ 01(6.30) RegExp 、 Function

JSCORE day_ 03(7.4)
随机推荐
[ciscn2019 finals Day2 web1]easyweb
[WUSTCTF2020]CV Maker
Install redis-7.0.4 in Linux system
Medical data of more than 4000 people has been exposed for 16 years
细说 call、apply 以及 bind 的区别和用法 20211031
[CISCN2019 华北赛区 Day1 Web5]CyberPunk
Leetcode 301 week
DOM day_ 03 (7.11) event bubbling mechanism, event delegation, to-do items, block default events, mouse coordinates, page scrolling events, create DOM elements, DOM encapsulation operations
JSCORE day_01(6.30) RegExp 、 Function
[b01lers2020]Welcome to Earth
JSCORE day_ 04(7.5)
[Network Research Institute] attackers scan 1.6 million WordPress websites to find vulnerable plug-ins
MySql - 如何确定一个字段适合构建索引?
[hongminggu CTF 2021] write_ shell
JSCORE day_03(7.4)
2022.7.14DAY604
2020-12-20 99 multiplication table
ArcGIS and CASS realize elevation points of cross-section Exhibition
6_ Gradient descent method
Input a string of letters and output the vowels inside. I hope you guys can give guidance