Redis系列(五):Redis的过时键删除策略

本篇博客是Redis系列的第5篇,主要讲解下Redis的过时键删除策略。面试

本系列的前4篇能够点击如下连接查看:算法

Redis系列(一):Redis简介及环境安装数据库

Redis系列(二):Redis的5种数据结构及其经常使用命令服务器

Redis系列(三):Redis的持久化机制(RDB、AOF)数据结构

Redis系列(四):Redis的复制机制(主从复制)函数

划重点:Redis的过时键删除策略也是面试中常常会被问的,我最近面试,被问到了好几回。post

对于Redis服务器来讲,内存资源很是宝贵,若是一些过时键一直不被删除,就会形成资源浪费,性能

所以咱们须要考虑一个问题:若是一个键过时了,它何时会被删除呢?设计

1. 常见的删除策略

常见的删除策略有如下3种:3d

  1. 定时删除

    在设置键的过时时间的同时,建立一个定时器,让定时器在键的过时时间来临时,当即执行对键的删除操做。

  2. 惰性删除

    听任过时键无论,每次从键空间中获取键时,检查该键是否过时,若是过时,就删除该键,若是没有过时,就返回该键。

  3. 按期删除

    每隔一段时间,程序对数据库进行一次检查,删除里面的过时键,至于要删除哪些数据库的哪些过时键,则由算法决定。

其中定时删除和按期删除为主动删除策略,惰性删除为被动删除策略。

接下来咱们一一讲解。

1.1 定时删除策略

定时删除策略经过使用定时器,定时删除策略能够保证过时键尽量快地被删除,并释放过时键占用的内存。

所以,定时删除策略的优缺点以下所示:

  1. 优势:对内存很是友好
  2. 缺点:对CPU时间很是不友好

举个例子,若是有大量的命令请求等待服务器处理,而且服务器当前不缺乏内存,若是服务器将大量的CPU时间用来删除过时键,那么服务器的响应时间和吞吐量就会受到影响。

也就是说,若是服务器建立大量的定时器,服务器处理命令请求的性能就会下降,

所以Redis目前并无使用定时删除策略。

1.2 惰性删除策略

惰性删除策略只会在获取键时才对键进行过时检查,不会在删除其它无关的过时键花费过多的CPU时间。

所以,惰性删除策略的优缺点以下所示:

  1. 优势:对CPU时间很是友好
  2. 缺点:对内存很是不友好

举个例子,若是数据库有不少的过时键,而这些过时键又刚好一直没有被访问到,那这些过时键就会一直占用着宝贵的内存资源,形成资源浪费。

1.3 按期删除策略

按期删除策略是定时删除策略和惰性删除策略的一种整合折中方案。

按期删除策略每隔一段时间执行一次删除过时键操做,并经过限制删除操做执行的时长和频率来减小删除操做对CPU时间的影响,同时,经过按期删除过时键,也有效地减小了由于过时键而带来的内存浪费。

2. Redis使用的过时键删除策略

Redis服务器使用的是惰性删除策略和按期删除策略。

2.1 惰性删除策略的实现

过时键的惰性删除策略由expireIfNeeded函数实现,全部读写数据库的Redis命令在执行以前都会调用expireIfNeeded函数对输入键进行检查:

  • 若是输入键已通过期,那么将输入键从数据库中删除
  • 若是输入键未过时,那么不作任何处理

以上描述可使用以下流程图表示:

2.2 按期删除策略的实现

过时键的按期删除策略由activeExpireCycle函数实现,每当Redis服务器的周期性操做serverCron函数执行时,activeExpireCycle函数就会被调用,它在规定的时间内,分屡次遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过时时间,并删除其中的过时键。

activeExpireCycle函数的大致流程为:

函数每次运行时,都从必定数量的数据库中随机取出必定数量的键进行检查,并删除其中的过时键,好比先从0号数据库开始检查,下次函数运行时,可能就是从1号数据库开始检查,直到15号数据库检查完毕,又从新从0号数据库开始检查,这样能够保证每一个数据库都被检查到。

划重点:

  1. 关于按期删除的大致流程,最近面试时有被问道,我就是按上述描述回答的。
  2. 可能有的面试官还会问,每次随机删除哪些key呢?能够提下LRU算法(Least Recently Used 最近最少使用),通常不会再细问,不过有兴趣的同窗能够深刻研究下。

3. RDB对过时键的处理

3.1 生成RDB文件

在执行SAVE命令或者BGSAVE命令建立一个新的RDB文件时,程序会对数据库中的键进行检查,已过时的键不会被保存到新建立的RDB文件中

举个例子,若是数据库中包含3个键k一、k二、k3,而且k2已通过期,那么建立新的RDB文件时,程序只会将k1和k3保存到RDB文件中,k2则会被忽略。

3.2 载入RDB文件

在启动Redis服务器时,若是服务器只开启了RDB持久化,那么服务器将会载入RDB文件:

  • 若是服务器以主服务器模式运行,在载入RDB文件时,程序会对文件中保存的键进行检查,未过时的键会被载入到数据库中,过时键会被忽略。

  • 若是服务器以从服务器模式运行,在载入RDB文件时,文件中保存的全部键,不管是否过时,都会被载入到数据库中。

    由于主从服务器在进行数据同步(完整重同步)的时候,从服务器的数据库会被清空,因此通常状况下,过时键对载入RDB文件的从服务器不会形成影响。

4. AOF对过时键的处理

4.1 AOF文件写入

若是数据库中的某个键已通过期,而且服务器开启了AOF持久化功能,当过时键被惰性删除或者按期删除后,程序会向AOF文件追加一条DEL命令,显式记录该键已被删除。

举个例子,若是客户端执行命令GET message访问已通过期的message键,那么服务器将执行如下3个动做:

  1. 从数据库中删除message键
  2. 追加一条DEL message命令到AOF文件
  3. 向执行GET message命令的客户端返回空回复

4.2 AOF文件重写

在执行AOF文件重写时,程序会对数据库中的键进行检查,已过时的键不会被保存到重写后的AOF文件中

5. 复制功能对过时键的处理

在主从复制模式下,从服务器的过时键删除动做由主服务器控制

  • 主服务器在删除一个过时键后,会显式地向全部从服务器发送一个DEL命令,告知从服务器删除这个过时键。
  • 从服务器在执行客户端发送的读命令时,即便发现该键已过时也不会删除该键,照常返回该键的值。
  • 从服务器只有接收到主服务器发送的DEL命令后,才会删除过时键。

6. 源码及参考

黄健宏 《Redis设计与实现》

相关文章
相关标签/搜索