目前,Redis采用的是惰性删除+定期删除的方案
在设置键过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作;
当key被操作时(如get,set)时,Redis 会被动检查该key是否过期, 如果key过期, 会触发惰性删除策略,直接删除掉这个过期key。
由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定期主动淘汰一批已过期的key,Redis中通过Max Memory参数来设定内存的使用上限,当前已用内存超过Max Memory限定时,会触发主动删除策略。 目前Redis提供了8种的淘汰策略(默认的是noeviction),配置文件中的策略主要包含以下几种:
volatile-lru(least recently used):最近最少使用算法,从设置了过期时间的键中选择空转时间最长的键值对清除掉;volatile-lfu(least frequently used):最近最不经常使用算法,从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉;volatile-ttl:从设置了过期时间的键中,选择过期时间最早的键值对清除;volatile-random:从设置了过期时间的键中,随机选择键进行清除;allkeys-lru:最近最少使用算法,从所有的键中选择空转时间最长的键值对清除;allkeys-lfu:最近最不经常使用算法,从所有的键中选择某段时间之内使用频次最少的键值对清除;allkeys-random:所有的键中,随机选择键进行删除;noeviction:不做任何的清理工作,在redis的内存超过限制之后,所有的写入操作都会返回错误;但是读操作都能正常的进行;前缀为volatile-和allkeys-的区别在于二者选择要清除的键时的字典不同,volatile-前缀的策略代表从RedisDb中的expire字典中选择键进行清除;allkeys-开头的策略代表从dict字典中选择键进行清除。
目前Redis提供了两种持久化方式,分别是RDB和AOF;
RDB是通过创建快照获取内存中的数据在某一个时间点上的数据的副本;有两个命令可以创建RDB文件,分别是SAVE和BGSAVE,两者的区别在于是否阻塞进程去创建RDB文件,这两个命令都不会将数据空间中的过期键给保存到RDB文件中;
在启动Redis服务器时,如果服务器开启了RDB文件,那么服务器就会对RDB文件进行载入,需要注意的是:
如果当前服务器是Master,那么过期键将会被忽略,不会载入到主服务器中;
如果当前服务器是Slave,文件中所有键(不管是否过期)都会被载入到从服务器中;
数据库中的过期键没有被删除时,其不会对AOF文件有任何的影响;当过期键被删除以后,程序会向AOF文件追加一条DEL命令,标记该键已经被删除;
AOF是通过将执行的写命令添加到AOF文件的末尾,来记录数据的变化;为了避免文件被添加得越来越大,甚至有可能用完硬盘的所有空间,因此Redis提供了Rewrite的优化策略,分别是REWRITEAOF和BGREWRITEAOF,两个命令的区别也是在于是否阻塞主进程,这两个命令都不会将数据空间中的过期键给保存到AOF文件中;
通常在主从模式下,主服务器来读取写命令,从服务器用来读取读命令,分担主服务器的压力,需要注意的是:
如果当前服务器是Master的话,当服务器通过策略得知某个键过期,则将该过期键给删除,并且同步给其他从服务器让它们删除掉该键;如果当前服务器是Slave的话,如果有命令读取当前过期键的话,不会惰性删除,因为这会影响读取的性能,因此不会删除,并且返回过期键对应的值;除非是Master服务器同步告知Slave服务器,需要删除过期键才会删除。