> 文档中心 > Redis持久化 - RDB和AOF

Redis持久化 - RDB和AOF


作者简介:
🌹 作者:暗夜91
🤟 个人主页:暗夜91的主页
📝 微信公众号: 程序员的知识站 ,关注本人公众号,学习更多前沿知识。


1、简介

Redis支持RDB和AOF两种持久化机制,持久化是为了避免因进程退出导致的数据丢失的问题。当下次重启时,利用之前持久化的文件,就可以实现数据的恢复工作。

2、RDB

RDB持久化就是把当前进程的数据生成快照保存到硬盘中。

RDB持久化触发方式分为手动触发和自动触发两种。

2.1 触发机制

手动触发有两种方式,分别是save命令和bgsave命令。

  • save

    执行save命令进行持久化时,会阻塞当前Redis服务,直到RDB持久化过程结束,对内存比较大的实例会造成长时间的阻塞,不建议使用

  • bgsvae

    执行bgsave命令,会在当前进程中执行fork操作,创建子进程,RDB持久化在子进程中完成,完成后进程自动结束,阻塞只发生在fork操作时,时间会很短。

显然,bgsave命令优化了save命令,解决了save命令带来的阻塞风险,因此Redis底层所有涉及到RDB的操作,都使用bgsave命令完成,而save命令已经废弃。

2.2 流程说明

在这里插入图片描述

1)执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如果存在,bgsave命令直接返回。

2)父进程执行fork操作,创建子进程,fork过程中父进程会阻塞,通过info stats命令可以查看latest_fork_usec选项,获取最近一个fork操作的耗时,单位是微秒

3)fork完成后,bgsave命令返回"Background saving started"信息,并释放父进程,这时Redis可以继续执行其他命令。

4)子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有的RDB文件进行替换。执行lastsave命令,可以得到最后一次生成RDB文件的时间。

5)子进程发送完成通知给父进程,父进程更新统计信息。

2.3 RDB文件处理

  • 保存

    RDB文件保存到dir配置的指定目录中,文件名通过dbfilename配置指定,可以通过config set dir {new Dir} 和config set dbfilename {new Filename}命令动态修改配置,当下次运行时,RDB文件自动保存到新的目录中。

  • 压缩

    Redis默认采用LZF算法对生成的RDB文件进行压缩,压缩后的文件远远小于内存大小,默认开启,可以通过参数config set rdbcompression {yes|no}动态修改。

  • 校验

    如果Redis加载损坏的RDB文件时,会拒绝启动,并打印如下日志:

    # Short read or OOM loading DB, Unrecoverable error,aborting now

2.4 RDB的优缺点

优点:

  • RDB是一个紧凑压缩的二进制文件,是Redis在某个时间点上的数据快照,非常适用于备份,全量复制等场景。比如定期使用bgsave备份,并把RDB文件复制到远程机器中,用于灾难恢复
  • Redis加载RDB恢复数据远远快于AOF方式。

缺点:

  • RDB无法做到实时持久化/秒级持久化,因为bgsave每次运行都要执行fork操作创建子线程,属于重量级操作,频繁操作成本太高
  • RDB文件使用特定二进制格式保存,不同版本的Redis,RDB文件格式不尽相同,存在老版本无法兼容新版本的RDB文件的问题。

3、AOF

AOP(append only file)持久化:以独立日志的方式记录每次命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的。

AOF的主要作用是解决数据持久化的实时性,目前已经是Redis持久化的主流方式。

3.1 使用AOF

Redis默认不开启AOF,开启功能需要添加配置:appendonly yes .AOF文件名通过appendfilename配置设置,默认文件名为appendonly.aof。保存路径和RDB持久化方式一致,通过dir配置指定。

AOF的工作流程操作为:命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load)。

具体流程如下:

1)所有的写入命令都会追加到aof_buf(缓冲区)中

2)AOF缓冲区根据对应的策略向硬盘做同步操作

3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。

4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

3.2写入命令

AOF命令写入的内容直接是文本协议格式。

3.3文件同步

Redis提供了多种AOF缓冲区同步文件的策略,由参数appendfsync控制,具体策略如下:

  • always:命令写入aof_buf后,调用系统fsync操作,同步到AOF文件,fsync完成后线程返回。
  • everysec:命令写入aof_buf后,调用系统write操作,write完成后线程返回。fsync同步文件操作由专门的线程负责,每秒调用一次。
  • no:命令写入aof_buf后,调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30秒

3.4 重写机制

随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件的体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

重写后AOF文件变小的原因:

1)进程内已经超时的数据不再写入文件

2)旧的AOF中含有的无效命令,如:del key,hkey key等,重写使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令。

3)多条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c可以转化为 lpush list a b c,为了防止单条命令过大造成客户端缓冲区溢出,对于list、set、hash、zset等类型的操作,以64个元素为界,拆分为多条。

AOF重写降低了文件的占用空间,此外,另一个目的是因为更小的AOF文件能够更快的被redis加载。

AOF重写过程可以手动触发和自动触发两种方式。

  • 手动触发:直接调用bgrewriteraof命令
  • 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。
    • auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认64M
    • auto-aof-rewrite-percentage:表示当前AOF文件空间(aof_current_size)和上一次重写AOF文件空间(aof_base_size)的比值。

3.5重启加载

AOF和RDB文件都可以用于服务器重启时的数据恢复,Redis持久化文件加载流程如下:

在这里插入图片描述

流程说明:

1)AOF持久化开启并且存在AOF文件时,优先加载AOF文件

2)AOF关闭或者AOF文件不存在时,加载RDB文件。

3)加载AOF/RDB文件成功后,Redis启动成功

4)AOF/RDB文件存在错误时,redis启动失败并打印错误日志。

3.6文件校验

加载损坏的AOF文件时,Redis会拒绝启动。对于损坏的文件,应先进行备份,然后使用redis-check-aof --fix命令进行修复,修复后使用diff -u对比数据差异,找出丢失数据。

AOF文件可能存在结尾不完整的情况,比如机器突然断电。为了解决这种情况,Redis提供了aof-load-truncated配置来兼容这种情况,默认是开启的,当遇到这种问题时,Redis会忽略并继续启动,同时打印警告日志。