一、AOF持久化
1.1 实现机制
AOF(Append Only File)是redis持久化方式的一种,它通过把所有redis执行过的命令都写入到文件来维持持久化。一旦服务崩溃,则可以重放这些命令来恢复服务数据。
例如,在redis上执行下面2条语句:
127.0.0.1:6379> set data "helloworld"
OK
127.0.0.1:6379> sadd zdata hello world
(integer) 2
那么AOF文件中的内容就类似是:
set data "helloworld"
sadd zdata hello world
当然,文件中保存不是直接的命令语句。而是按照redis命令请求协议保存的,除了执行的命令以外还有一些其他的内容也会保存到文件。redis协议是redis执行命令专用的一种协议,当客户端向服务端发送请求也是使用的redis协议,AOF也使用redis协议的好处是可以直接使用redis协议解析库,不用再单独实现一套。
AOF数据并不是实时写入到文件中的,而是优先保存在缓冲区。redisServer对象中保存了一个aof_buf字段,它就是aof命令的保存缓冲区。当执行完命令后,会先把指令保存到这里,然后根据策略把缓冲区中的内容写入到磁盘。一个要注意的是,文件写入磁盘并不会立马刷新到文件系统,因为操作系统对系统IO有缓存,缓存到达一定条件后才会同步缓存到文件系统。
为了避免数据没有及时写入到文件系统(还在缓存中),AOF提供了三种策略来同步缓存:
策略 | 描述 |
---|---|
always | 每处理一次事件循环,就把aof文件写入到文件。这种办法最稳妥,数据丢失后的恢复效果最好。 |
Everysec | 每秒同步一次AOF文件缓存到文件系统。 |
no | 不主动同步缓存,由操作系统决定什么时候写入到文件系统。 |
1.2 AOF重写
当服务运行久了之后,AOF文件会变得很大,redis提供了AOF重写功能来优化AOF文件数据。
所做的优化就是整合指令,例如:
127.0.0.1:6379> zadd age 14 hello 15 world 16 nginx
(integer) 3
127.0.0.1:6379> zrem age hello
(integer) 1
执行完这两个命令后,数据库保存了一个有序集合age,里面包含了两个元素world和nginx。其中hello在第一个命令中加进来了,但是第二个指令又删除了,所以实际上写入AOF文件并不需要上面两行,只需要一行就可以完成:
zdd age 15 world 16 nginx
AOF重写就是基于这种策略来重写的,但是有一个要注意的地方是:在执行AOF写入的时候,会导致redis阻塞。所以一般建议是使用后台重写来完成整个AOF文件的重写,后台重写会新建一个子进程,避免在父进程中操作阻塞正常业务。执行后台重写的指令是BGREWRITEAOF
。
二、RDB持久化
RDB持久化是redis的第二种持久化方式,它持久化的原理是把数据库中所有键值对的二进制数据直接写入到文件。RDB持久化的优先级一般低于AOF持久化,因为AOF持久化的实时性高于RDB,所以在系统启动的时候如果存在AOF持久化,redis会优先通过AOF持久化恢复数据。
执行持久化的操作指令是SAVE
和BGSAVE
,一个是前台执行,一个是后台执行。和AOF持久化一样,前台执行会阻塞当前redis进程,所有客户断请求都会被阻塞,因此一般建议是用BGSAVE
,它也会新创建一个子进程来做持久化操作。RDB备份是全量备份。
可以在redis.conf中配置RDB相关的操作,主要有以下几个配置:
save <seconds> <changes>
dbfilename dump.rdb
dir ./
第一个配置是执行BGSAVE
的策略,当在secnods秒之内执行了changes次操作时,会自动把改动写入到RDB文件。可以同时有多个save配置段存在,例如官方默认的配置中就有三个save配置:
save 900 1
save 300 10
save 60 10000
这三个配置,只要在任意时间段内满足了任意一条就会执行(三者互不影响,互相独立,各自备份各自的):
- 900秒内执行了一次更新,BGSAVE就会执行。
- 300秒内执行了10次更新,BGSAVE就会执行。
- 60秒呢执行了10000次更新,BGSAVE就会执行。
dbfilename
和dir
指定了备份文件名和路径,执行后就会把RDB文件写入到这个文件中。例如,设置保存的路径为/appdata/redis/dump.rdb
,执行save命令后,就会生成这个文件:
RDB持久化文件可以使用官方的redis-check-rdb
程序(低版本叫redis-check-dump
)来检测相关数据:
当然,这个文件只提供了基本检测功能(即验证rdb文件是否合法),并不包含导出所有数据的功能。
如果需要处理实际的数据可以通过其他工具来实现,google一下redis rdb parser就能看到了。
github上也有很多,例如https://github.com/sripathikrishnan/redis-rdb-tools。
三、AOF和RDB对比
RDB持久化 | AOF持久化 |
---|---|
全量备份,一次保存整个数据库 | 增量备份,只保存新修改的数据 |
保存的间隔较长 | 保存的间隔默认一秒 |
更适合数据备份,默认开启 | 更适合用来保存数据,和一般SQL持久化方式一样,默认关闭 |
save会阻塞,但bgsave或者自动不会阻塞 | 无论是平时还是AOF重写,都不会阻塞 |
轻重 : 重 | 轻重: 轻 |
启动优先级 : 低 | 启动优先级 : 高 |
体积 : 小 | 体积 : 大 |
恢复速度 : 快 | 恢复速度 : 慢 |
数据安全性 : 丢数据 | 数据安全性 : 根据策略决定 |
表格从Redis持久化AOF和RDB对比整理得来。
此处评论已关闭