Redis的持久化方案

97 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

持久化

redis的数据都是存放在内存中的,所以当出现断电、系统崩溃等异常时,这些数据就丢失了,为此,我们需要利用永久性的存储介质将这些数据保存起来,这样就可以在出现问题的时候再将数据从存储介质上恢复回来。

redis提供了两种数据持久化的方式,RDB和AOF,其中RDB是以快照的方式进行保存,而AOF则以日志的方式进行保存,下面分别介绍。

RDB

在前面我们已经设置了 dir 的配置值为 /opt/redis-4.0.0/logs ,所以redis生成的rdb文件也会在该目录出现,我们使用客户端连接上一个redis服务:

redis-cli -p 6380

然后设置几个数据:

set name zhangsan
set age 20

执行 save 指令即可进行持久化,此时在logs目录下即可看到持久化文件:

[root@centos-7 logs]# ls
6379.log  6380.log  dump.rdb

该文件的相关信息可以在配置文件中进行设置,比如:

dbfilename dump.rdb		# 持久化文件名,默认为dump.rdb
dir ./								# 文件存放位置,默认为当前目录
rdbcompression yes		# 设置存储至本地时是否压缩数据,默认为yes,采用LZF压缩
rdbchecksum yes				# 设置是否进行RDB文件格式校验,默认为yes

修改一下6380端口的配置文件:

dbfilename dump-6380.rdb

通过该文件即可恢复数据。

\

需要注意,save指令的执行会阻塞当前redis服务,直到RDB过程完成为止,有可能会造成长时间的阻塞,线上环境不建议使用save指令。

\

redis提供了第二种RDB指令, bgsave ,该指令的执行将会在后台进行,当我们执行该指令后,redis会调用fork函数生成一个子进程,然后在子进程中创建RDB文件。

\

bgsave指令也有一个可配置项:

stop-writes-on-bgsave-error yes	

默认为yes,表示后台存储过程中如果发生了错误,是否停止保存操作。

\

我们已经知道通过 bgsave 指令能够备份数据,然而手动执行备份指令并不好,为此,可以让redis自动为我们进行备份,还可以设置备份的频率和触发条件。

需要在配置文件中进行配置:

save 10 2

它表示在10秒的时间内若是有2个key及以上的数据发生了变化,无论是添加、修改还是删除,只要发生了变化,那么就会触发自动备份。

AOF

RDB的方式有着一定的缺陷,因为每次是基于所有数据的备份,所以文件存储大、导致IO性能下降,而且是基于子进程实现的,会额外消耗内存资源。

而AOF以独立日志的方式记录每次的写指令,重启时再重新执行AOF文件中记录的指令,以达到恢复数据的目的,与RDB的区别在于:RDB记录的是数据;而AOF记录的是操作数据的指令。

AOF方式共有三种写策略,分别是:

  • always:每次写入操作均同步到AOF文件中,数据零误差,性能较低
  • everysec:每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高,但在系统突然宕机的情况下会丢失1秒的数据
  • no:由操作系统控制每次同步到AOF文件的周期,整体过程不可控

\

redis默认是关闭了AOF功能的,所以我们需要在配置文件中开启它:

appendonly yes			# 开启AOF
appendfsync always	# 指定策略为每次都同步

AOF的写策略默认为每秒同步一次,我们可以将其修改为每次都同步,配置完毕后启动redis服务,查看 logs 目录:

[root@centos-7 logs]# ll
总用量 28
-rw-r--r--. 1 root root  4650 3月  15 03:35 6379.log
-rw-r--r--. 1 root root 14704 3月  15 19:41 6380.log
-rw-r--r--. 1 root root     0 3月  15 19:41 appendonly.aof
-rw-r--r--. 1 root root   184 3月  15 19:31 dump-6380.rdb

会发现出现了 appendonly.aof 文件,这就是AOF的持久化文件,接下来我们连接客户端,并写入一个数据后,再观察该文件:

[root@centos-7 logs]# ll
总用量 32
-rw-r--r--. 1 root root  4650 3月  15 03:35 6379.log
-rw-r--r--. 1 root root 14704 3月  15 19:41 6380.log
-rw-r--r--. 1 root root    60 3月  15 19:42 appendonly.aof
-rw-r--r--. 1 root root   184 3月  15 19:31 dump-6380.rdb

会发现文件大小由原来的0变为了60,这说明我们的配置生效了,该文件只会记录写指令,即添加、修改、删除数据的指令,诸如get指令是不会被它记录的。

\

AOF的持久化文件名也可以通过配置来修改:

appendfilename appendonly-6380.aof

随着指令不断写入AOF,文件也会越来越大,但有时候会出现这样一种情况:

set name zs
set name ls
set name ww

这里虽然执行了三条 set 指令,但事实上,它的效果等价于一条指令: set name ww ,因为后面的数据覆盖了前面的数据,那么如果AOF记录了这三条指令,很显然就造成了资源的浪费。为此,redis提供了AOF重写机制,它能够将对同一个数据的若干条指令转换为最终结果数据对应的指令记录,这样便极大地压缩了AOF文件的体积。

\

只需执行指令即可实现AOF重写:

bgrewriteaof