Redis持久化 aof和rdb的原理

2022-11-22 14:56:03 浏览数 (1)

一.介绍

由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。

redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时 dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)

本篇为综合整理的文档,若要深入了解可查阅Redis官网文档

二.RDB持久化(全量写入)

rdb原理

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发

过程:

  • 1)执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。
  • 2)父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒。
  • 3)父进程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。
  • 4)子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换 执行lastsave命令可以获取最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项。
  • 5)进程发送信号给父进程表示完成,父进程更新统计信息,具体见info Persistence下的rdb_*相关选项。

rdb模式

SAVE 阻塞式的RDB持久化,当执行这个命令时间时rdis的主进程把内存里的数据库状态写入到rdb文件中,直到该文件创建完毕的这段时间内redis讲不能处理任何命令请求

BGSAVE 非阻塞式的持久化,它会创建一个子进程,专门去把内存中的数据库状态写入RDB文件,同时主进程还可以处理来自客户端的请求命令,但子进程基本是复制父进程,这等于两个相同大小的redis进程在系统上运行,会造成内存使用率的大幅增加。

rdb触发情况

1.手动执行bgsave或save命令 2.根据配置文件的save选项自动触发 3.主从结构时,从节点执行全量复制操作,主节点自动执行,将生成的RDB文件发送给从 4.执行debug reload命令重新加载Redis时 5.默认情况下执行shutdown命令关闭redis时,如果没有开启AOF持久化功能则自动执行

rdb优势和劣势

优势:

  • 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对可以定时每天可以备份出一个整个的数据文件。
  • 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
  • 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

劣势:

  • 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。

rdb文件配置

redis.conf文件

代码语言:javascript复制
#注释所有save行则停止rdb持久化

#900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)

save 900 1

#300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)

save 300 10
#60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)

save 60 10000
#当RDB持久化出现错误后,再写入数据会报错,用于提示用户出问题了。

#yes是开启,no是关闭,默认开启

stop-writes-on-bgsave-error yes
#是否压缩rdb文件,rdb文件压缩使用LZF压缩算法,压缩会消耗一些cpu,不压缩文件会很大

#yes开启,no关闭,默认开启

rdbcompression yes
#使用CRC64算法来进行数据校验,防止RDB是错误的,但是这样做会增加大约10%的性能消耗

#yes开启,no关闭,默认开启

rdbchecksum yes

rdb命令配置

阻塞当前Redis服务器 直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。 save

Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。 bgsave

查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒。 info stats

rdb数据恢复

1.将RDB备份放到配置文件指定的数据目录下,启动redis将会自动恢复。加载期间将会阻塞,无法进行其它操作。

2.上述方法不行,或者恢复的集群,可以使用redis-migrate-tool工具进行恢复。

三.AOF持久化(增量写入)

aof原理

以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

写入的数据具有可读性,同步时先写入缓冲区,再放入硬盘。如果直接写入硬盘,性能将取决于磁盘负载,并且放到缓冲区,可以提供各种同步策略。

过程:

  • 1)所有的写入命令会追加到aof_buf(缓冲区)中。
  • 2)AOF缓冲区根据对应的策略向硬盘做同步操作。
  • 3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
  • 4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

aof触发情况

1.根据配置文件自动触发

aof优势和劣势

优势:

  • 该机制可以带来更高的数据安全性,即数据持久性。根据策略不同,从而对数据安全性不同,可以在性能和安全区选择一个。
  • 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。
  • 如果日志过大,将自动启用rewrite机制。以append模式不断的将修改数据写入到老的磁盘文件中,同时还会创建一个新的文件用于记录此期间有哪些修改命令被执行,保证安全性。
  • AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。

劣势:

  • 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
  • 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

aof文件配置

在Redis的配置文件中存在三种同步方式,它们分别是:

代码语言:javascript复制
#是否开启aof持久化。默认no,要打开

appendonly yes

#位置

appendfilename "appendonly.aof"

#每次有数据修改发生时都会写入AOF文件

#命令写入aof_buf后调用系统fsync操作同步AOF文件,fsync完成后线程返回

appendfsync always

#每秒钟同步一次,该策略为AOF的缺省策略

#命令写入aof_buf后调用系统write操作,write完成后线程返回。fsync同步文件操作由专门线程每秒调用一次

#这个模式兼顾了效率的同时也保证了数据的完整性,即使在服务器宕机也只会丢失一秒内对redis数据库做的修改

appendfsync everysec

#不加入缓冲区,直接写到硬盘,速度最快,不安全

#命令写入aof_buf后调用系统write操作,不对aof文件做fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30秒

#这种模式下效率是最快的,但对数据来说也是最不安全的,如果redis里的数据都是从后台数据库如mysql中取出来的,属于随时可以找回或者不重要的数据,那么可以考虑设置成这种模式。

appendfsync no

aof命令配置

aof文件重写手动触发 bgrewriteaof

aof文件重写自动触发,配置文件

代码语言:javascript复制
#新的aof文件大小是上次的aof文件的大小2倍(100)时,进行重写

auto-aof-rewrite-percentage 100

#表示运行AOF重写时文件最小体积, 默认为64MB

auto-aof-rewrite-min-size 64mb

aof数据恢复

  • 将AOF备份放到配置文件指定的数据目录下,启动redis将会自动恢复。加载期间将会阻塞,无法进行其它操作。
  • 上述方法不行,或者恢复的集群,可以使用redis-migrate-tool工具进行恢复。
  • 可以使用pipline方式批量硬写入,但效率会低

四.总结

二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。

启动加载流程:

  • AOF持久化开启且存在AOF文件时, 优先加载AOF文件
  • AOF关闭或者AOF文件不存在时, 加载RDB文件
  • 加载AOF/RDB文件成功后, Redis启动成功
  • AOF/RDB文件存在错误时, Redis启动失败并打印错误信息

0 人点赞