Redis 之数据过期策略
文章目录
- 定时删除
- 惰性删除
Redis 中有惰性删除与定时删除两种数据删除策略。Redis 将这两种策略结合使用,是为了在性能和内存管理之间取得平衡。惰性删除策略减少了 CPU 开销,而定时删除策略则能及时清理部分过期键,避免大量过期键长时间占用内存。这样既保证了 Redis 的高性能,又能有效地管理内存资源。
TTL 指令说明
Redis 是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过 TTL 指令获取其状态。通过 TTL 指令获取数据状态可能返回如下结果:
- 返回正整数:表示距离数据被删除的剩余时间;
- 返回
-1
:表示该数据永久有效; - 返回
-2
:表示已经过期的数据
或被删除的数据
或未定义的数据
。
过期键存储结构
在 Redis 中,当你为一个键值对设置过期时间时,Redis 会在内部维护一个额外的数据结构来管理这些过期键。具体来说,Redis 数据库结构中除了有一个用于存储普通键值对的字典(dict
)之外,还会有一个专门用于存储过期键信息的字典(expires
)。
- 普通键值对字典:用于存储正常的
key - value
数据,即你通过SET
等命令设置的键值对。 - 过期键字典(
expires
):是一个哈希表,其中的key
是那些设置了过期时间的键,而value
是该键的过期时间戳(以毫秒为单位),表示该键在这个时间点之后就会过期。
定时删除
定时删除策略也被称为定期删除策略,Redis 会按照一定的时间周期,周期性地在数据库中随机抽取一部分键进行检查,判断这些键是否过期,如果过期则将其删除。
定时删除策略执行流程如下:
- 周期性执行:Redis 服务器在启动时会初始化一个定时任务,默认情况下,Redis 每秒会执行 10 次过期键检查操作(这个频率可以通过配置参数
hz
进行调整,hz
越大,检查频率越高,但也会对性能产生一定影响)。 - 随机抽样检查:每次执行过期键检查时,Redis 并不会遍历数据库中的所有键,因为这样会带来巨大的性能开销。而是随机从数据库中选取一部分键(具体数量由 Redis 内部算法决定),对这些键进行过期检查。
- 删除过期键:对于抽样检查中发现的过期键,Redis 会将其从数据库中删除,释放相应的内存空间。
- 循环检查:如果在一次检查中,发现过期键的比例超过了一定阈值(默认是 25%),Redis 会继续进行下一轮的过期键检查操作,直到过期键的比例低于阈值或者达到了执行时间上限,以保证过期键能被及时清理。
调整 Redis 执行过期键检查的频率可以通过修改 Redis 配置文件 redis.conf
中的 hz
参数来实现。例如,将检查频率提高到每秒 20 次:
# 修改前
# hz 10# 修改后
hz 20
修改完成后,重启 Redis 服务器使配置生效。
定时删除策略本质上是一种用 CPU 性能换取存储空间的策略(时间换空间),其优缺点如下:
- 优点:节约内存,时效到时立刻删除内存占用;
- 缺点:CPU 压力很大,无论 CPU 此时负载多高,都会占用 CPU,会影响 Redis 服务器响应时间和指令吞吐量。
惰性删除
惰性删除策略并不会主动去检查和删除过期键,而是在客户端尝试访问某个键时,Redis 会先检查该键是否已经过期。如果过期,Redis 会立即删除这个键,并返回给客户端一个空结果(例如,对于 GET 操作返回 nil);如果未过期,则正常处理客户端的请求。
例如:
set name zhangsan 10
get name
对于以上案例中,在惰性删除策略下,get name
时发现 name
过期,name
才会被删除。
惰性删除策略本质上是一种拿存储空间换 CPU 性能(即空间换时间)的策略,优缺点如下:
- 优点:节约 CPU 性能。不需要定期扫描所有的键来检查是否过期,避免了在大规模数据场景下对 CPU 资源的过度消耗。
- 缺点:内存压力问题。如果过期键一直没有被访问,它们会一直占用内存,可能导致内存泄漏。为了弥补这一缺点,Redis 还采用了定期删除策略。