Redis过期策略以及淘汰机制

    科技2026-08-05  3

    微信公众号:Java患者专注Java领域技术分享

    redis 过期策略

    前言

    Redis中可以通过expire设置键的过期,那么Redis又是什么时候删除键的呢?

    Redis有三种删除策略:

    定时删除:在设置键的过期时间同时,会创建一个定时器,通过设置的时间来执行键的删除操作。

    惰性删除:不管设置键的过期时间,只有当每次获取键的同时,检查获取到的键是否已经过期,如果过期就删除该键。

    定期删除:每隔一段时间,就对Redis数据库进行一次检查,删除里面过期的键。每次要检查多少个数据库,以及要删除多少个过期的键,由Redis的算法决定。

    定时删除

    定时删除对内存是比较友好的,毕竟通过定时器删除,可以保证过期就删除不占用多的内存,但是每一个键设置了过期时间就给予一个定时器,这种情况下如果过期键比较多的情况下就很占用CPU。

    如果有大量的命令请求到redis服务器,而且服务器当前不缺少内存,那么服务器本应该优先将CPU时间用在处理客户端的七年跪求,但是由于此时有定时器在跑,就会占用CPU在删除过期键上面。

    惰性删除

    惰性删除策略相对定时删除来看是相反的,程序只会在取出键的时候才会对键进行过期检查,这就可以保证删除过期键的操作只会在获取的时候才会执行,这个策略相对来说不会花费额外的CPU资源,但是如果有一个过期键一直保存在数据库中,而没有获取这个键,这个时候就会对内存造成浪费,没有获取就不会进行资源释放。

    定期删除

    键的定时删除会在Redis的周期性执行任务(serverCron)中执行,默认 每100ms执行一次。

    首先会依次遍历每个db,然后针对每个db,每次循环随机选择20个key来判断是否过期,如果一轮所选择的key少于25%过期,则终止迭次。此外在迭代过程中如果超过了一定的时间限制则终止过期删除的任务。

    淘汰机制

    Redis中不同位数操作系统中最大占用内存不同,在64位的操作系统中,Redis不限制占用内存,在32位系统中最大占用内存为3GB。也可以通过配置文件修改。

    # maxmemory <bytes>

    当Redis的内存快耗尽的时候,Redis会启动内存淘汰机制,将部分key清理以腾出内存。

    redis中提供了8种淘汰策略,也可以在配置中配置。

    # volatile-lru -> Evict using approximated LRU among the keys with an expire set. # allkeys-lru -> Evict any key using approximated LRU. # volatile-lfu -> Evict using approximated LFU among the keys with an expire set. # allkeys-lfu -> Evict any key using approximated LFU. # volatile-random -> Remove a random key among the ones with an expire set. # allkeys-random -> Remove a random key, any key. # volatile-ttl -> Remove the key with the nearest expire time (minor TTL) # noeviction -> Don't evict anything, just return an error on write operations. # # LRU means Least Recently Used # LFU means Least Frequently Used # # Both LRU, LFU and volatile-ttl are implemented using approximated # randomized algorithms. # # Note: with any of the above policies, Redis will return an error on write #       operations, when there are no suitable keys for eviction. # #       At the date of writing these commands are: set setnx setex append #       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd #       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby #       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby #       getset mset msetnx exec sort # # The default is: # # maxmemory-policy noeviction
    lru:算法 Least Recently Used 最近最少使用

    volatile-lru:表示从已经设置过期时间的数据中挑选出最近使用次数最少的数据进行淘汰;

    allkeys-lru:表示从所有键数据中挑选出最近最少使用的数据进行淘汰

    lfu: 算法 Least Frequently Used 最少频率使用

    volatile-lfu:在设置了过期时间的key中使用LFU算法淘汰

    allkeys-lfu:在所有键中使用LFU算法淘汰数据

    volatile-random: 从已设置了过期时间的数据中选择任意数据进行淘汰

    allkeys-random:在所有键中随机选择任意数据进行淘汰

    volatile-ttl:从已设置了过期时间的数据中挑选即将要过期的数据淘汰

    noeviction:默认配置是这个,当内存使用达到阈值的时候,只读不可写。

    可以通过配置maxmemory-policy修改淘汰机制。

    资料 · 福利

    回复 【加群】即可加入Java技术交流修仙群

    回复 【Java】即可获取最新零基础Java视频资料

    回复 【激活】即可获取IDEA、datagrip等系统激活方式

    回复 【面试题】即可获取Java技术相关面试题

    往期 · 精彩

    盘点那些互联网APP出现的奇葩bugRedis中String数据类型原理实现

    十月一号之后,github新建的默认分支不叫master了

    Java面试锦囊(十二)-- Eureka与Zookeeper区别你连volatile都不在意,你在意什么,在意大利吗

    专注分享Java技术,跟我一起学习吧

    长按识别二维码关注

    Processed: 0.013, SQL: 9