Redis key的淘汰策略
过期策略
定时删除
在设置某个key 的过期时间的同时,创建一个定时器,让定时器在该过期时间到来时,立即执行对其进行删除的操作。
定期删除
每隔一段时间,我们就对一些key进行检查,删除里面过期的key。
惰性删除
在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会返回东西。会导致很多过期的key仍然存在内存中。
Redis就是使用惰性删除和定期删除两种策略配合使用。
实现方式
惰性删除:Redis的惰性删除策略由 db.c/expireIfNeeded 函数实现.
定期删除:由redis.c/activeExpireCycle 函数实现,函数以一定的频率运行,每次运行时,都从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键(默认没100ms一次)。
内存的淘汰策略
默认无限制,通常设置为物理内存的3/4。
当现有内存大于maxmemory时,便会触发redis主动淘汰内存方式,通过设置maxmemory-policy,有如下几种淘汰方式。
- volatile-lru:利用LRU算法移除设置过过期时间的key
- allkeys-lru: 利用LRU算法移除任何key。通常使用该方式。
- volatile-random : 移除设置过过期时间的随机key。
- allkeys-random: 无差别的随机移除。
- volatile-ttl:移除即将过期的key
- noeviction: 不移除任何key,只是返回一个写错误,默认选项,一般不会选用。
Redis持久化
为了避免内存中的数据丢失,Redis提供了对持久化的支持,可以选择不同的方式保存到磁盘中。
RDB(Redis Database)
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot快照,恢复时将快照文件直接读入内存。
Snapshot的两种模式
1.SAVE: save只管保存,其他的不管,全部阻塞。
2.BGSAVE: Redis会在异步后台(fork子进程)进行快照操作,主进程仍然可以响应客户端的请求,保存完成后通知主进程,可以通过lastsave命令获取最后一次成功执行快照的时间。
优势
- 适合大规模的数据恢复
- 对数据完整性和一致性要求不高
- 与AOF模式相比,通过RDB文件恢复数据比较快
- 通过fork进程的方式备份,对Redis服务器的性能影响较小。
劣势
- 每隔一段时间备份,会丢失最后一次快照后的数据
- Fork的时候,内存消耗大,会占用2倍的内存
- 使用save时会造成Redis服务器阻塞,导致不可用。
- 使用bgsave fork子进程时,如果数据量太大,forks的过程也会发生阻塞另外比较费内存。
AOF(Append-Only-File)
以日志的形式来记录每个写操作,将Redis执行过的所有写指令。只许追加但不可以改写文件。redis载入AOF文件的时候,会创建一个虚拟的client,把AOF中每一条命令都执行一遍。在RDB和AOF备份文件都有的情况下,redis会优先执行AOF中的文件。
AOF备份的三种策略
- always:将缓存区的内容总是及时写到AOF文件中。
- everysec: 将缓存区的内容每隔一秒写入AOF文件中(默认策略)。
- no: 写入AOF文件中的操作由操作系统决定,一般系统会等到缓存区被填满,才会同步数据到磁盘。
AOF重写
为了解决AOF文件膨胀的问题,Redis提供AOF重写功能:Redis服务器可以创建一个新的AOF文件来替换旧文件,Redis保证新旧两个文件所保存的数据库状态一样。
AOF_REWRITE这个函数会保证服务器的高性能,会Fork子进程进而执行AOF重写程序,同时,为了保障主进程和AOF文件数据不一致的问题。Redis增加了 一个AOF缓存区,等子进程完成后 ,会将AOF缓存区中的内容写入到新的AOF文件中。
默认重写出发机制时上次rewrite后大小的一倍并且文件大于64MB。
优点
1.AOF只是追加文件,对服务器的影响小。
2.可以采用不同的策略,在数据的完整性和性能之间做出平衡性。
缺点
1.一般AOF文件要大于RDB文件恢复数据的速度比RDB慢
2.aof运行效率慢于rdb,同步策略效率较好,不同步效率与rdb相同。