Redis持久化的两种方式

引言

Redis是内存数据库,如果不将内存中的数据保存到硬盘,那么一旦服务器断电,内存中的数据也会消失,所以必须做持久化。
Redis有两种持久化的方式,快照(RDB持久化)和追加式文件(AOF持久化)。

RDB

RDB持久化是通过快照的方式,即在指定的时间间隔内将内存中的数据集快照写入磁盘。在创建快照之后,用户可以备份该快照,可以将快照复制到其他服务器以创建相同数据的服务器副本,或者在重启服务器后恢复数据。RDB是redis默认的持久化的方式。
RDB持久化会生成RDB文件,该文件是一个压缩过的二进制文件,可以通过该文件还原快照时的数据库状态,即生成该RDB文件时的服务器数据,RDB文件默认为当前工作目录下的dump.rdb,可以根据配置文件中的dbfilenamedir设置RDB的文件名和文件位置。

# The filename where to dump the DB
dbfilename dump.rdb

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis

触发快照的时机

  • 执行savebgsave命令
  • 配置文件设置save [seconds] [changes]规则,自动间隔性执行bgsave命令
  • 主从复制时,从库全量复制同步主库数据,主库会执行bgsave
  • 执行flushall命令清空服务器数据
  • 执行shutdown命令关闭redis时,会执行save命令

save和bgsave的区别

执行savebgsave命令,可以手动触发快照,生成RDB文件,两者的区别如下:
使用save命令会阻塞redis服务器进程,服务器进程在RDB文件创建完成之前是不能处理任何的命令请求。
而使用bgsave命令不同的是,bgsave命令会fork一个子进程,然后该子进程会负责创建RDB文件,而服务器进程会继续处理命令请求。
fork()是由操作系统提供的函数,作用是创建当前进程的一个副本作为子进程。
fork一个子进程,子进程会把数据集先写入临时文件,写入成功之后,再替换之间的RDB文件,用二进制压缩存储,这样可以保证RDB文件始终存储的是完整的持久化内容。

自动间隔触发

在配置文件中设置save [seconds] [changes]规则,可以自动间隔性执行bgsave命令。

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000

save [seconds] [changes]表示在seconds秒内,如果有changes次key的变化,就会触发bgsave命令。

AOF持久化

AOF(Append Only File)持久化功能会把被执行的写命令写到AOF文件的末尾,记录数据的变化。默认情况下,redis不开启AOF持久化。在配置文件中可以更改开启,开启后,没执行一条更改redis数据的命令,都会把该命令追加到AOF文件中,这会降低redis的性能,但大部分情况下这个影响是能够接受的。使用较快的硬盘可以提高AOF的性能。

AOF的实现

AOF需要记录redis的每个写命令,步骤为:命令追加(append)、文件写入(write)和文件同步(sync)。

  • 命令追加(append)
    开启AOF持久化功能后,服务器每执行一个写命令,都会把该命令以协议格式先追加到aof_buf缓存区的末尾,而不是直接写入文件,避免每次有命令都直接写入硬盘,减少磁盘IO次数。
  • 文件写入(write)和文件同步(sync)
    至于何时把aof_buf缓冲区的内容写入保存在AOF文件中,redis提供了多种策略。
    • appendfsync always:将aof_buf缓冲区的所有内容写入并同步到AOF文件,每个写命令同步写入磁盘。此时数据安全性是最高的,但是会对磁盘进行大量的写入,redis处理命令的速度会受到磁盘性能的限制。
    • appendfsync everysec:将aof_buf缓冲区的内容写入AOF文件,每秒同步一次,该操作由一个线程专门负责。该选项兼顾了数据安全和写入性能,以每秒一次的频率同步AOF文件,即使出现系统崩溃,最多只会丢失一秒内产生的数据。
    • appendfsync no:将aof_buf缓冲区的内容写入AOF文件,什么时候同步由操作系统来决定。该策略不会对redis的性能带来影响,但假如系统崩溃,可能会丢失不定数量的数据。
      默认为每秒同步一次。

AOF重写(AOF)

随着时间的推移,redis执行的命令会越来越多,AOF文件也会越来越大,过大的AOF文件可能会对redis服务器造成影响,如果使用AOF文件来进行数据还原所需时间也会越长。
很大的一个问题是,AOF文件中会有一些冗余命令,比如:过期数据的命令、无效的命令(重复设置、删除)、多个命令可以合并为一个命令(批处理命令)。所以AOF文件是有精简压缩的空间的。
AOF重写的目的就是减小AOF文件的体积,不过值得注意的是:AOF文件重写并不需要对现有的AOF文件进行任何读取、分享和写入操作,而是通过读取服务器当前的数据库状态来实现的。
文件重写可分为手动触发和自动触发,手动触发执行bgrewriteaof命令,该命令的执行跟bgsave触发快照时类似,都是先fork一个子进程做具体的工作。
自动触发会根据auto-aof-rewrite-percentageauto-aof-rewrite-min-size配置来自动执行bgrewriteaof命令。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

上述配置表示当AOF文件体积大于64MB,并且AOF文件的体积比上一次重写后的体积大了一倍(100%),会执行bgrewriteaof命令。

  • 重写会有大量的写入操作,所以服务器进程会fork一个子进程来创建一个新的AOF文件
  • 在重写期间,服务器进程继续处理命令请求,如果有写入的命令,追加到aof_buf的同时,还会追加到aof_rewrite_buf
  • 当子进程完成重写之后,会给父进程一个信号,然后父进程把AOF重写缓冲区的内容写进新的AOF临时文件中,再对新的AOF文件改名完成替换,这样可以保证新的AOF文件与当前数据库数据的一致性。

数据恢复

redis 4.0开始支持RDB和AOF的混合持久化,可以通过配置项aof-use-rdb-preamble开启。

  • 如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据
  • 如果是redis进程所在机器挂掉,俺么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复,如果AOF文件破坏,那么用redis-check-aof fix命令修复
  • 如果没有AOF文件,会去加载RDB文件
  • 如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复。

RDB与AOF的比较

RDB优缺点

  • 优点
  1. RDB快照是一个压缩过的非常紧凑的文件,保存着某个时间点的数据集,适合做数据的备份,灾难恢复。
  2. 可以最大化redis的性能,保存RDB文件,服务器只需fork一个子进程来完成RDB文件的创建,父进程不需要IO操作。
  3. 与AOF相比,恢复大数据集的时候会更快。
  • 缺点
  1. RDB的数据安全性不如AOF,保存整个数据集的过程是很繁重的,根据配置可能要几分钟才快照一次,如果服务器宕机,那么可能丢失几分钟的数据。
  2. redis数据集较大时,fork的子进程要完成快照会比较耗CPU、耗时间。

AOF优缺点

  • 优点
  1. 数据更完整,安全性更高,秒级数据丢失
  2. AOF文件是一个只追加的日志文件,且写入操作是以redis协议的格式保存的,内容是可读的,适合误删紧急恢复
  • 缺点
  1. 对于相同的数据集,AOF文件的体积要大于RDB文件,数据恢复也会比较慢
  2. 根据所使用的fsync策略,AOF的速度可能会慢于RDB。不过在一般情况下,每秒fsync的性能依然非常高。

如何选择RDB和AOF

  • 如果是数据不那么敏感,且可以从其他地方重新生成补回的,那么可以关闭持久化
  • 如果是数据比较重要,不想再从其他地方获取,且可以承认数分钟的数据丢失,比如缓存等,那么可以只使用RDB
  • 如果是用做内存数据库,要使用redis的持久化,建议是RDB和AOF都开启,或者定期执行bgsave做快照备份,RDB的方式更适合做数据的备份,AOF可以保证数据的不丢失。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值