Redis中有一些Key到期了,需要一些策略来处理这些过期的key, 设置到期时间的key会放入一个单独的字典中,以后会定时遍历这个这个字典来删除到期的key,除了定时遍历以外,还会使用惰性策略来删除过期的key,当客户端访问这个的key时候会检查到期时间,到期了就立即删除。而定时删除是集中式处理。
Redis是单线程,如果某一段时间过期的key很多,删除的时候会不会出现卡顿情况。Redis有一个定时扫描策略:
#1 Redis默认1秒扫描10次有到期时间的字典,即差不多100ms扫描一次
#2从过期字典中随机选择20个key进行扫描,将已经过期的key删除掉
#3 统计这一批20个key中的删除比例,如果有25%的key需要删除,则再进行一轮,即重复步骤2
#4 同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,默认扫描不会超过 25ms。
所以当客户端请求到来的时候,如果服务器正好在进行过期扫描,客户端的请求将会等待至少25毫秒才会处理,如果客户端连接设置的比较短有可能因为超时而关闭。所以如果有大批量的key需要过期,一定要设置随机到期时间,不适合在同一时间全部过期,分散处理过期范围。
从库不会主动过期,既不会主动扫描过期。当主库的key到期的时候,会在AOF文件中增加一条del指令来删除过期的key。因为del指令是异步执行的,所以主库过期的key的del指令没有及时同步到从库的话,会出现从库数据不一致的情况。
第一:如果业务允许段时间内主从不一致,则可以使用这样的方式
第二:如果确实不允许主从数据不一致,则该请求强行读主库
当Redis内存超过物理内存限制的时候,内存的数据开始和磁盘产生频繁的交换,这会使得Redis的性能急剧下降,生产环境一般是不允许这样的情况存在。为了限制最大使用内存,Redis提供了配置参数maxmemory来限制内存超出期望的大小。当实际使用内存超出maxmemory的时候,Redis提供了几种可以选择的策略,让用户自己来选择如何腾出新的空间以继续提供服务。
不会继续服务写请求(del请求除外),读请求可以继续执行
当内存不够的时候,对于最近很少使用的设置了过期时间的key进行淘汰
当内存不足的时候,对于设置了过期时间的key,剩余存活时间越短的key越先被淘汰
当内存不足的时候,从设置了到期时间的key中随机选择一部分key进行淘汰
当内存不足的时候,从所有的key中选择最近很少使用的进行淘汰
当内存不足的时候,从所有的key中随机选择进行淘汰
我们知道key过期处理方式有2种: 集中删除和惰性删除。LRU淘汰不一样吗,只有惰性删除,当Redis执行写操作的时候,发现内存不够,超过了maxmemory,就会执行一次LRU淘汰算法,随机采样出5个(maxmemory_samples配置)个key,如果淘汰后内存还是超出maxmemory,则继续淘汰5个,直到低于maxmemory为止。