Redis过期策略与内存淘汰机制总结
redis常用于有时间限制的数据存储,可以在set key的时候给一个expire time(过期时间),通过设置过期时间可以指定这个key可以存活的时间,那么设定的过期时间到了后,redis是怎么对过期的key进行删除的呢?下面分别从redis过期策略和内存淘汰机制说起
redis过期策略
针对数据库key过期,通常有三种删除策略:
定时删除:在设置key的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作
惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期就删除该键,如果没有过期,就返回该键
定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键
redis服务实际使用了定期删除和惰性删除两种策略
定期删除
redis默认每隔100ms就会随机抽取一些设置了过期时间的key,检查是否过期,如果过期就删除该key,注意是随机抽取一些key,这是因为与CPU的负载有关,假设redis中的过期数据量十分庞大,每隔100ms就遍历所有的过期key的话,就会给CPU带来很大的负载。
定期删除策略可能会导致很多过期的key到了时间并没有被删除,这时就需要用到惰性删除策略了
惰性删除
假如key过期了,而定期删除策略没有将其删除掉,这个过期的key还停留在内存中,此时系统查询一下那个过期的key,redis就会将这个过期的key给删除掉。
经过以上两种过期策略的处理,还是会存在一些未删除的过期key,这是因为定期删除策略随机抽取过期key,就会漏掉很多没有被抽取到的key,而系统又没有及时去查询,也就没有触发惰性删除策略,那么这个过期的key就会一直留在数据库中,这些无用的垃圾数据就会占用大量的内存,而服务器又不会主动去释放它们,就会导致redis内存耗尽,redis为了解决这个问题引入了内存淘汰机制。
redis内存淘汰机制
redis内存淘汰机制有以下几种:
volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(常用)
allkeys-random:从数据集中任意选择数据淘汰
no-eviction:禁止驱逐数据,及当内存不足以容纳新写入数据时,新写入操作会报错
volatile-lfu:从已设置过期时间的数据集中挑选最不经常使用的数据淘汰
allkeys-lfu:当内存不足以容纳新写入的数据时,移除最不经常使用的key
通过配置redis.conf中的maxmemory参数值来开启淘汰功能,设置最大内存,通过maxmemory-policy参数值配置淘汰策略
LRU算法的实现:
通过双向链表来实现,新数据插入到链表头部,每当缓存数据被访问,则将数据移到链表头部,当链表满时,将链表尾部的数据丢弃。
new LinkedHashMap<K,V>(capacity, DEFAULT_LOAD_FACTORY, true);
第三个参数为true,代表按访问顺序排序,可作为LRU缓存;设为false,代表按插入顺序排序,可作为FIFO缓存
设置过期时间
redis中通过EXPIRE命令或PEXPIRE命令设置以秒或毫秒精度的生存时间(Time To Live,TTL),通过EXPIREAT命令或PEXPIREAT命令设置以秒或毫秒精度的过期时间(expire time)
EXPIRE <key> <ttl>:用于将key的生存时间设置为ttl秒
PEXPIRE <key> <ttl>:用于将key的生存时间设置为ttl毫秒
EXPIREAT <key> <timestamp>:用于将key的过期时间设置为timestamp所指定的秒数时间戳
PEXPIREAT <key> <timestamp>:用于将key的过期时间设置为timestamp所指定的毫秒数时间戳
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/76845.html