redis持久化之rdb

标签: redis  rdb  redis  快照方式  redis持久化

一、简介

redis持久化的方式主要有两种方式:

  • 一种是以快照的方式进行持久化,这种方式也叫作rdb方式(redis database);
  • 另外一种方式是aof方式(append only file);

通过redis的持久化,我们可以将数据保存在磁盘上,以便于在redis出现故障或者重启时恢复上次的数据。两种方式各有各的优点和缺点,当然也可以两者一起使用,但是redis会有限加载aof文件,具体用哪一种看项目需求而定。

本文主要讲解其中一个方式 - 快照方式(rdb)

  • rdb快照:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot快照,它恢复时将快照文件.rdb直接读到内存里,rdb默认保存的文件是dump.rbd

二、配置文件

rdb方式的持久化在redis.conf中的配置如下:

#SNAPSHOTTING快照:主要配置redis持久化之rdb方式。  save <seconds> <changes>
################################ 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.

#在下面的例子中,行为将被保存:
#900秒后(15分钟),如果至少改变了一个键
#300秒后(5分钟),如果至少有10个键改变
#60秒后,如果至少改变10000个键
#   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 ""

# 900秒之内至少有一个key被改变
save 900 1
# 300秒之内至少有十个key被改变
save 300 10
# 一分钟之内有一万次key变更
save 60 10000

# By default Redis will stop accepting writes if RDB snapshots are enabled
# (at least one save point) and the latest background save failed.
# This will make the user aware (in a hard way) that data is not persisting
# on disk properly, otherwise chances are that no one will notice and some
# disaster will happen.
#
# If the background saving process will start working again Redis will
# automatically allow writes again.
#
# However if you have setup your proper monitoring of the Redis server
# and persistence, you may want to disable this feature so that Redis will
# continue to work as usual even if there are problems with disk,
# permissions, and so forth.

# bgsave出错的时候是否停止写入操作
stop-writes-on-bgsave-error yes

# Compress string objects using LZF when dump .rdb databases?
# For default that's set to 'yes' as it's almost always a win.
# If you want to save some CPU in the saving child set it to 'no' but
# the dataset will likely be bigger if you have compressible values or keys.

# 对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果不想消耗CPU来进行压缩的话,可以设置为no关闭此功能。
rdbcompression yes

# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
# This makes the format more resistant to corruption but there is a performance
# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
# for maximum performances.
#
# RDB files created with checksum disabled have a checksum of zero that will
# tell the loading code to skip the check.

# 在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增大大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
rdbchecksum yes

# The filename where to dump the DB
# rdb默认配置文件名称
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 ./

通过上面的配置可以看到:redis默认提供了三种会触发rdb持久化的条件:

# 900秒之内至少有一个key被改变
save 900 1
# 300秒之内至少有十个key被改变
save 300 10
# 一分钟之内有一万次key变更
save 60 10000

小伙伴们可以根据需求适当更改持久化触发时机。

三、原理

【a】save:save时只管保存,其他不管,save是一个阻塞式命令,即当服务器接收了一条save命令之后就会开始拍摄快照,在此期间不会再去处理其他的请求,其他请求会被挂起直到备份结束,应该避免使用。

【b】bgsave:redis会在后台异步进行快照操作,快照操作同时还可以响应客户端请求,与save命令区别就在于bgsave不会阻塞主进程处理的操作。Redis会单独创建(Fork)一个子进程来进行持久化,先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。

四、示例

【a】首先我们先修改一下redis.conf配置文件中触发rdb持久化的条件,这里只是为了方便测试,所以调整成:120秒之内至少有十个key被改变就触发rdb持久化,生成dump.rdb。

vim redis.conf
# 900秒之内至少有一个key被改变
save 900 1
# 120秒之内至少有十个key被改变
save 120 10
# 一分钟之内有一万次key变更
save 60 10000

【b】我们先删除原来存留的dump.rbd文件,防止造成影响

【c】在两分钟时间内操作10以上的key,去触发持久化条件:

【d】查看bin目录下是否生成了dump.rbd文件

可见,成功生成了dump.rdb,下面就需要模拟一下突发情况了:比如断电等;

注意:执行了 flushall 命令,马上生成了dump.rdb文件,但是是空的,无任何意义。

 

接着我们重启完redis,进入客户端查看数据是否恢复成功。

 

结果发现,并没有恢复之前的数据,原因就是因为上面退出redis时不小心执行了 flushall 命令,该命令会生成空的dump.rdp覆盖掉之前的rdp文件,所有恢复数据都为空的。

下面,我们重新重新来一遍:

首先备份没有执行 flushall 命令后的rdb文件:dump_bak.rdb,然后再把这个文件复制一份成dump.rdb,这样就可以成功恢复数据。

然后我们重启redis之后查看数据:

可见,数据成功恢复了。

那么,如果想禁用掉rdb持久化该怎么弄呢?

方法很简单,首先将前面讲解的关于SNAPSHOTTING快照部分的配置全部注释掉,然后只保留下面一句即可。

save ""

五、优缺点

  • 优点:
  • 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效;
  • 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些;
  • RDB很适合用于灾备,单文件很方便就能传输到远程的服务器上;
  • 可以定期备份rdb文件,直接写个脚本就好了,很方便;
  •  
  • 缺点:
  • 最后一次持久化后的数据可能丢失;
  • rdb需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能导致redis在一些毫秒级不能响应客户端请求;

六、总结

以上就是关于redis持久化方式之rdb快照的原理以及使用说明,在实际项目中,如果对丢失部分数据不敏感的话可以选择使用rdb方式进行持久化,毕竟比aof快,而且我们可以写个脚本定期备份dump.rdb文件,这样我们以后如果系统出问题就可以随时恢复到以前某个时间备份的数据了。

原文链接:加载失败,请重新获取