一、 AOF 持久化
1.1 实现机制
AOF(Append Only File) 是 redis 持久化方式的一种,它通过把所有 redis 执行过的命令都写入到文件来维持持久化。一旦服务崩溃,则可以重放这些命令来恢复服务数据。
例如,在 redis 上执行下面 2 条语句:
1 2 3 4 |
127.0.0.1:6379> set data "helloworld" OK 127.0.0.1:6379> sadd zdata hello world (integer) 2 |
那么 AOF 文件中的内容就类似是:
1 2 |
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 文件数据。
所做的优化就是整合指令,例如:
1 2 3 4 |
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 文件并不需要上面两行,只需要一行就可以完成:
1 |
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 相关的操作,主要有以下几个配置:
1 2 3 |
save <seconds> <changes> dbfilename dump.rdb dir ./ |
第一个配置是执行 BGSAVE
的策略,当在 secnods 秒之内执行了 changes 次操作时,会自动把改动写入到 RDB 文件。可以同时有多个 save 配置段存在,例如官方默认的配置中就有三个 save 配置:
1 2 3 |
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 对比整理得来。
评论