redis是目前很流行的key-value形式的、基于内存的NoSQL数据库,相比于memocache有更加丰富的数据类型,能适应更多的业务场景,因此得到了广泛的应用。本文主要关注的是redis缓存键的过期策略,更多关于redis的介绍详见redis官网。
redis有四个不同的命令用于设置键的过期时间:
命令名 | 功能 |
---|---|
EXPIRE <key> <ttl> | 将键的生存时间设置为ttl秒 |
PEXPIRE <key> <ttl> | 将键的生存时间设置为ttl毫秒 |
EXPIREAT <key> <timestamp> | 将键的生存时间设置为timestamp指定的秒数时间戳 |
PEXPIREAT <key> <ttl> | 将键的生存时间设置为timestamp指定的毫秒数时间戳 |
前三个命令最终都会转换成PEXPIREAT命令来实现,然后将键的过期时间以毫秒精度的UNIX时间戳保存到expires字典中。
那么过期的键何时会被删除呢?
redis中有三种策略:
1、定时删除,设置键的过期时间的同时设置一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作。
2、惰性删除,放任键测过期不管,但每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键,如果没有过期就返回该键。
3、定期删除,每隔一段时间,程序对数据进行一次检查,删除里面的过期键,至于要删除多少过期键,以及检查多少个数据库,则由算法决定。
定时删除对内存是友好的,在特定的时间会将键删除,但对cpu并不友好,因为定时任务要花费大量时间去查找事件表。与之相反,惰性删除对cpu是友好的,但对内存并不友好,因为如果这个键没有被访问到的话,它将永远不会被删除。以上两种删除策略单独使用时都有明显缺陷,因此有了整合两种策略的第三种策略:定期删除。定期删除策略会在规定的时间内,分多次遍历服务器中的数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。