1、键过期相关命令

expire key seconds #单位为秒,对已经有过期时间的key执行expire操作,将会更新它的过期时间,有很多应用有这种业务场景,例如记录会话的session

pexpire key milliseconds #单位为毫秒

persist key #清除超时,使其变成一个永久的key

expireat key timestamp 

pexpireat key milliseconds-timestamp #以毫秒为单位设置 key 的过期 unix 时间戳

pttl key #以毫秒为单位范围key的剩余生存时间

ttl key #以秒为单位范围key的剩余生存时间

如果key被rename命令修改,相关的超时时间会转移到新key上面(不管原来的key是永久的还是有过期时间的)
 

 

2、过期键删除策略

redis使用一个过期字典来保存数据库所有键的过期时间,过期字典的key是一个指针,指向redis的键,value则存储一个毫秒精度的UNIX时间戳。

现有以下三种可能的过期键删除策略:

  • 定时删除:在设置键过期时间的同时,创建一个定时器,让定时器在键过期时,立即删除键;对内存友好而对CPU不友好;
  • 惰性删除:只有用到的时候才会判断是否删除;对CPU友好但对内存不友好,如果一个过期键永远不被访问,那该键占用的内存也就永远得不到释放;
  • 定期删除:每隔一段时间,就检查一次;折中方案,需要合理设置删除操作的执行时间和执行频率;

 

redis实际使用的是惰性删除和定期删除两种。

redis对于惰性删除的做法是:

  • 每次访问键之前需要判断键是否过期;

redis对于定期删除的做法是:

  • 默认每隔100ms检查是否有过期的key,有则删除。需要说明的是,redis不是每隔100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms检查全部key,redis岂不是卡死);

 

3、内存淘汰机制

如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效,这样,redis的内存会越来越高。此时就会采用内存淘汰机制。

可以通过如下配置来限制redis的最大内存。

maxmemory 100mb

当maxmemory限制达到时,Redis会使用maxmemory-policy配置的策略来回收内存,有如下策略:

  • volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰;
  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰;
  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰;
  • allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰;
  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰;
  • noenviction(驱逐):禁止驱逐数据,新写入操作会报错;

如果没有设置 expire 的key, 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致

redis使用的是近似LRU算法,通过对少量keys进行取样,然后回收其中一个最好的key(被访问时间较早的)。真实LRU算法太耗内存。可通过如下配置使采样数量提升到10来让LRU算法更真实,但会消耗更多的CPU时间。

maxmemory-samples  10