1、key的生存时间到了,Redis会立即删除吗?
不会立即删除
- 定期删除:Redis每隔一段时间就会去查看Redis设置了过期时间的key,会在100ms的间隔中默认查看3个key
- 惰性删除:如果当你查询一个已经过了生存时间的key时,Redis会先查看当前key的生存时间,是否已经到了,直接删除当前key,并且返回用户一个空值
2、Redis的淘汰机制
在Redis内存已经满的时候,添加了一个新的数据,执行淘汰机制
- volatile-lru:在内存不足时,Redis会在设置过生存时间的key中干掉一个最少使用的key
- allkeys-lru:在内存不足时,Redis会在全部的key中干掉一个最近最少使用的key
- volatile-lfu:在内存不足时,Redis会在设置过生存时间的key中干掉一个最少频次使用的key
- allkeys-lfu:在内存不足时,Redis会在全部的key中干掉一个最近频次使用的key
- volatile-random:在内存不足时,Redis会在设置过生存时间的key中随机干掉一个
- allkeys-random:在内存不足时,Redis会在全部的key中随机干掉一个
- volatil-ttl:在内存不足时,Redis会在设置了生存时间的key中干掉一个剩余时间最少的key
- noeviction:在内存不足时,直接报错,默认值
指定淘汰机制的方式:maxmemory-policy 具体策略
设置Redis的最大内存:maxmemory 字节大小
3、Redis缓存问题
Redis
的缓存穿透、缓存击穿和缓存雪崩定义、原因及其解决⽅案。
3-1、缓存穿透
缓存穿透定义
缓存穿透是指查询⼀个⼀定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写⼊缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决⽅案
1.缓存空对象
当存储层未命中后,即使数据库返回的空对象也对其进⾏缓存,同时设置⼀个过期时间,之后再访问这个数据将会 从缓存中获取,保护了后端数据源。
2.
布隆过滤器
布隆过滤器是⼀种数据结构,对所有可能查询的参数以
hash
形式存储,在控制层进⾏校验,不符合则丢弃,从⽽避 免了对底层存储系统的查询压⼒。
优点:空间效率和查询时间都远远超过⼀般的算法,缺点是有⼀定的误识别率和删除困难。
3.
设置可访问的⽩名单
使⽤
bitmaps
类型定义⼀个可以访问的名单,名单
id
作为
bitmaps
的偏移量,每次访问和
bitmap
⾥⾯的
id
进⾏⽐ 较,如果访问id
不在
bitmaps
⾥⾯,进⾏拦截,不允许访问。
4.
进⾏实时监控
当发现
Redis
的命中率开始急速降低,需要排查访问对象和访问的数据,和运维⼈员配合,可以设置⿊名单限制服
务。
3-2、缓存击穿
缓存击穿定义
key
对应的数据存在,但在
Redis
中过期,此时若有⼤量并发请求过来,这些请求发现缓存过期⼀般都会从后端
DB
加载数据并回设到缓存,但是缓存回设期,这个时候⼤并发的请求可能会瞬间把后端
DB压垮。例
解决⽅案
1.
预先设置热⻔数据
在
Redis
⾼峰访问之前,把⼀些热⻔数据提前存⼊到
Redis
⾥⾯,加⼤这些热⻔数据
key
的时⻓。
2.
设置热点数据永不过期
若缓存的数据是基本不会发⽣更新的,则可尝试将该热点数据设置为永不过期。
3.
实时调整
现场监控哪些数据热⻔,实时调整key
的过期时⻓。
4.
使⽤分布式锁
使⽤分布式锁,保证对于每个
key
同时只有⼀个线程去查询后端服务,其他线程在没有获取分布式锁的权限时,需 要等待。这种⽅式将⾼并发的压⼒转移到了分布式锁,因此对于分布式锁的考验很⼤。
5.
定时线程
若缓存的数据更新频繁或者在缓存刷新的流程耗时较⻓的情况下,可以利⽤定时线程在缓存过期前主动地重新构建
缓存或者延后缓存的过期时间,以保证所有的请求能⼀直访问到对应的缓存。
3-3、缓存雪崩
缓存雪崩定义
缓存雪崩,是指在某个时间段,缓存集中过期失效,导致数据库异常的状况。
key
对应的数据存在,但在
Redis
中过期或者是缓存服务直接宕机,此时若有⼤量并发请求过来,这些请求发现缓存过期⼀般都会从后端DB
加载数据并回设到缓存,这个时候⼤并发的请求可能会瞬间把后端
DB
压垮
解决⽅案
1.
构建集群
通过搭建
Redis
集群,保障
Redis
的⾼可⽤,避免全盘崩溃。
2.
搭建多级缓存架构
Nginx
缓存
+ Redis
缓存
+
其他缓存(
Ehcache
等)。
3.
限流降级
在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量,从⽽避免失效时⼤量的并发请求落到底层存储系统上。⽐如对某个key
只允许⼀个线程查询数据和写缓存,其他线程等待。不适⽤⾼并发情况。
4.
数据预热
在正式部署之前,先把可能的数据先预先访问⼀遍,这样部分可能⼤量访问的数据就会加载到缓存中,在即将发⽣⼤并发访问前⼿动触发加载缓存不同的key
,设置不同的过期时间,让缓存失效的时间点尽量均匀。
5.
设置过期标志更新缓存
记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际
key
的缓存。
6.
将缓存失效时间分散开
⽐如我们可以在原有的失效时间基础上增加⼀个随机值,⽐如
1-5
分钟随机,这样每⼀个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。