前言
Redis是一个键值对(key-value pair)数据库服务器,服务器中的每个数据库都由一个redis.h/redisDb结构表示,redisDb结构中dict字典保存了数据库中的所有键值对,当我们给某个键值添加过期时间时(expire或pexpire),redisDb结构会开辟一个expires的字典用来保存dict字典中所有过期键的过期时间.
expires过期字典中的键值是一个指针,指向键空间中的某个键对象.值是一个long类型的时间戳,保存了键指针所指向的数据库键的过期时间——一个毫秒精度的UNIX时间戳.
过期键的判定
通过expires过期字典,Redis可以检查一个键是否过期:
- 检查dict字典中的键是否存在于expires过期字典中,如果存在,取得UNIX过期时间戳.
- 检查UNIX过期时间戳是否大于键的过期时间,如果大于,则键过期;否则键未过期.
我们可以用TTL命令或PTTL命令获取某个键的是否过期.
过期键删除策略
Redis有三种过期键的删除策略:
- 定时删除:设置键的过期时间的同时,创建一个timer定时器,该定时器在键过期时间来临时对键执行删除操作.
- 惰性删除:每次从dict键空间获取键值时,检查并判断该键是否存在过期时间,是否过期,如果过期就删除该键,如果没有,就返回该键.
- 定期删除:每隔一段时间对dict字典和expires字典做一次检查,删除过期键.
上诉三种策略中,1,3是主动删除策略,2是被动删除策略.它们各有利弊.
1.定时删除
定时删除对内存最友好,但对CPU最不友好.在过期键比较多的情况下,过多的timer定时器会占用比较多的CPU时间.影响服务器的响应时间和吞吐量.
2.惰性删除
惰性删除对CPU最友好,但对内存最不友好.当某些键不再被访问时,过期键将永远不会删除.浪费内存,有内存泄露的危险.
3.定期删除
定时删除和惰性删除的缺点都太明显,定期删除策略是前两种策略的整合折中的方式.
定期删除通过限制删除操作的执行时长和频率来减少对CPU的影响,通过定期删除过期键,有效减少因为过期键而造成的内存浪费.
目前Redis服务器使用的是惰性删除和定期删除的过期键删除策略. 通过这两种删除策略,服务器可以很好的在CPU和内存空间之间取得平衡.