redis过期策略以及内存淘汰机制
一、redis的过期策略
定期删除+惰性删除
redis在存储数据时,可能会设置过期时间,而所谓的定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key进行检查,如果过期了就会删除。
至于为啥是每隔100ms随机抽取一些数据进行检查而不是全部检查,这就与cpu负载有关了,如redis中的数据十分庞大,并且全部都设置了过期时间,依次全部检查并且进行删除的话负载太高,影响性能。
但是,由于是随机抽取的key进行检查进行删除,那么很多的key可能会到了过期时间了还没进行删除,那么怎么办呢?这时候,惰性删除就会发挥作用了,所谓的惰性删除,就是在读取某个key的时候,redis会先检查一个该key是否过期,如果过期了,就会在此时删除,然后不会给你返回任何东西。
但是此时就会产生另外一个问题,假如一些key设置了过期时间,而定期删除的随机抽取没有选中这些key,而恰好也没有人去获取这些key,惰性删除也发挥不了作用了,那么这些数据就会越积累越多,redis一般作为缓存的,是基于内存的,这些数据越来越多的时候回导致内存耗尽,影响性能,这时候应该怎么办呢?这时候,另一个重量型的武器就要发挥作用了,那就是:内存淘汰机制。
AOF、RDB和复制功能对过期key的处理
在执行save或bgsave命令创建一个新的RDB文件时,redis会对键进行检查,已过期的键不会保存到RDB文件中。当启用了rdb持久化策略,在启用redis时,服务器会对rdb文件进行载入。
如果是主库,载入rdb文件时,会对键进行检查,已过期的键不会载入到redis中。如果是从库载入rdb文件时,不论key是否过期,都会被载入到redis中,但这不会对redis造成影响。因为主从服务器进行数据同步时,从数据库的数据会被清空。
当redis使用aof持久化策略,当redis删除一条过期key时,会同时向aof文件中追加一条del命令。在执行aof重写的过程中,程序会对数据库中的键进行检查,已过期的建不会被保存到重写的aof文件中。
当服务器运行在复制模式下时,从服务器的过期键删除动作有主服务器控制,所以读写分离模式下,会出现key过期但仍有效的问题。(reidis3.2已修复)
二、内存淘汰机制 (maxmemory-policy)
- noeviction: (默认策略) 当内存不足以容纳新写入数据时,新写入操作会报错。
- allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key。
- allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。
- volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key。
- volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。
- volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。