Redis过期删除策略和内存淘汰机制
1. 过期删除策略
1.1 定时删除策略
在设置key的过期时间的时候,并且为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除
优点:保证内存被尽快释放
缺点:若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器(将会有大量的定时器产生),性能影响严重。(用时间换内存空间)
1.2 惰性删除
key过期的时候不删除,每次通过key获取值的时候去检查是否过期,若过期,则删除key,返回null。
优点:删除操作只发生在通过key取值的时候发生,而且只删除当前key,所以对CPU时间的占用是比较少
缺点:过期key很多,会占用大量内存空间,可能导致内存溢出(用内存空间换时间)
1.3 定期删除
每隔一段时间执行一次删除过期key操作
优点:通过限制删除操作执行的时长和频率,来减少删除操作对cpu的影响。另一方面定时删除也有效的减少了因惰性删除带来的内存浪费
Redis配置项hz定义了serverCron任务的执行周期,默认为10,即CPU空闲时每秒执行10次;
每次过期key清理的时间不超过CPU时间的25%,即若hz=1,则一次清理时间最大为250ms,若hz=10,则一次清理时间最大为25ms;
清理时依次遍历所有的db; 从db中随机取W个key,判断是否过期;
若过期,则删除key;
如果一轮中删除的key的数量>W*25%,重复操作步骤
否则遍历下一个db;
在清理过程中,若达到了25%CPU时间,用current_db记录当前步骤,退出清理过程;下一次继续从current_db处执行。
W取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PRE_LOOP
1.4 Redis采用的过期删除策略
redis 过期策略是:定期删除+惰性删除。
2. 内存淘汰机制
当redis内存超出物理内存限制时,会和磁盘产生swap,这种情况性能极差,一般是不允许的。通过设置 maxmemory 限制最大使用内存。超出限制时,根据redis提供的几种内存淘汰机制让用户自己决定如何腾出新空间以提供正常的读写服务。
在redis中,允许用户设置最大使用内存大小maxmemory,设置为0表示不限制(默认配置)。
生产环境中需要设置此值,最好不超过内存60%-70%。
当redis内存数据集快到达maxmemory时,redis会实行数据淘汰策略,设置maxmemory-policy值。
-
检查易失数据(设置了过期时间的数据)
- volatile-lru:在设置了过期时间的键空间中,删除最近最少使用的 key。
- volatile-ttl:在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。
- volatile-random:在设置了过期时间的键空间中,随机删除某个 key。
-
检查全库数据
- allkeys-lru:在所有键空间中,移除最近最少使用的 key
- allkeys-random:在所有键空间中,随机移除某个 key
-
放弃数据驱逐
- no-enviction : 禁止驱逐数据,新写入操作会报错 (默认值)。
为了键设置过期时间也是需要消耗内存的,所以使用allkeys-lru这种策略更加高效,因为没有必要为键取设置过期时间当内存有压力时。