[redis] 删除策略以及持久化

484 阅读5分钟

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

过期删除策略

过期数据的清理可以有三种删除策略:

  • 定时删除:对设置了过期时间的键,设计一个到期执行的执行器,在key过期的时候立即将键值删除。
  • 惰性删除:获取键时才进行判断,如果过期再删除,不过期就返回该键。
  • 定期删除:设置一个定时执行的定时器,每隔一段时间,检查并删除过期的值。

定时删除

  • 内存友好,但对CPU不友好,而且可能导致缓存雪崩的情形。

惰性删除

  • CPU友好,但内存不友好。

定期删除

上述两种的折衷考虑。

redis实际使用的是惰性删除和定期删除的策略。

redis - 惰性删除

所有读写数据库的redis命令,都会先通过特定函数(db.c/expireIfNeeded)的检查:

  • 如果过期,删除
  • 不过期则进入读写操作指令。

redis - 定期删除

redis服务器会周期性地执行某个函数(redis.c/activeExpireCycle),随机从数据库中抽取部分记录,做过期判断与过期删除。

复制模式

复制模式下,从服务器是不会主动删除过期键的。只有当:

  • 主服务器删除了一个过期键后,会向所有从服务器发送del命令,来告知从服务器删除该过期键。

  • 从服务器仅当受到主服务器的命令,才删除过期键。

    • 否则,读命令再从服务器上对过期键的查询,和未过期键的拆线呢相同。

持久化

  • 两种方式:快照、AOF

    • 快照:一次全量备份
    • AOF:连续增量备份

快照 - RDB

快照备份的是内存的二进制序列化形式,存储紧凑。

  • 是一个经过压缩的二进制文件

使用SAVE,或者BGSAVE,或者根据服务器选项定期执行,来创建一个新的RDB文件。

  • 不会保存过期的键。

由于RDB的全量性质,因此AOF的更新频率通常高于RDB,数据也较新,因此:

  • 如果开启了AOF持久化,那么服务器会优先使用AOF来进行启动时数据载入。
  • 仅当关闭了AOF且开启了RDB,服务器才会使用RDB来还原。

RDB载入

启动服务器时,如果开启了RDB功能,那么服务器会载入RDB文件

  • 服务器为主服务器模式:检查RDB中的键,如果过期了就不载入
  • 服务器为从服务器模式:载入RDB中所有的键。

不过,因为主从服务器在进行数据同步的时候,从服务器的数据库就会被清空,所以一般来讲,过期键对载入RDB文件的从服务器也不会造成影响。

RDB文件载入时,直到载入完成,服务器都会一直处于阻塞状态。

RDB写入状态

手动写入

RDB通过两个命令进行手动写入。

  • 当执行save时:

    redis服务器会阻塞,拒绝所有客户端发送的命令。

  • 当执行BGSave时:

    BGSave时通过子进程执行的,因此该场景下Redis服务器仍可以继续处理客户端命令请求,但对于如下三个命令会执行不同的处理:

    • SAVE:当执行BGSAVE时,SAVE命令会被拒绝。

      服务器禁止SAVE命令和BGSAVE命令同时执行是为了避免父进程(服务器进程)和子进程同时执行两个rdbSave调用,防止产生竞争条件。

    • BGSAVE:和上面相同的道理,BGSAVE也会被拒绝。

    • BGRewriteAOF:和BGSave不会同时执行。

      • BGSAVE先执行,那么BGRewriteAof命令会被推迟到BgSave命令执行完毕后执行。
      • BgRewrite先执行,那么BGSAVE会被拒绝。

      此处考虑的不是冲突,而是性能考虑(两个子线程并发且都执行了大量的磁盘写入操作)

自动写入

BGSave不阻塞服务器主进程,因此Redis可以通过服务器设置,让服务器间隔时间一段时间自动执行一次BGSAVE指令。

指令为:

save 900 1
save 300 10
save 60 10000

save的指令是互相兼容的关系,上面三个指令(这个是save选项的默认条件)指的是:

只要满足以下三个条件中的任意一个,BGSAVE命令就会被执行:

❑服务器在900秒之内,对数据库进行了至少1次修改。

❑服务器在300秒之内,对数据库进行了至少10次修改。

❑服务器在60秒之内,对数据库进行了至少10000次修改。

定期执行的逻辑是:

  • 必须先满足时间上的间隔到了
  • 随后再考虑数据的修改次数

AOF日志

aof日志是内存数据修改的指令记录文本,存储没有那么紧凑,长时间运行会很大,因此需要定期重写以及瘦身。

AOF载入

如果键过期但没来得及删除,那么AOF文件不会有对应记录。

如果被删除了,那么AOF文件末尾会追加一条del命令,来记录该键已被删除。

AOF重写

AOF重写时,不会写入过期的键。