本文首发于 Redis 持久化(persistence)技术口袋书,转载请注明出处。
本文讲解 Redis 数据库的数据持久化解决方案。
测试环境:
Redis 提供两种持久化解决方案:RDB 持久化和 AOF 持久化。
要点:
RDB 持久化:可以在指定时间间隔内,生成数据集在这个时间点的快照。 AOF 持久化:通过记录服务器执行的所有写操作命令,在服务器重启时,通过重新执行这些命令来还原数据。
采用 RDB 持久化方案时,Redis 会每隔一段时间对数据集进行快照备份,换句话说这种方案在服务器发生故障时可能造成数据的丢失。所以,如果对数据的完整性有比较强烈的要求,可能不太适用这种备份方案,即它适用于做数据的备份。
我们已经知道,采用 RDB 持久化方案会每隔一段时间对数据进行备份,那么这个时间段如何确定呢?
我们可以到 redis.windows.conf 配置文件的 SNAPSHOTTING 配置节点获取答案,默认情况下 Redis 采用三种持久化策略:
save 900 1
save 300 10
save 60 10000
这里的 save 指令表示「在 x 秒内有 n 个及以上键被改动」则会自动保存一次数据集,比如配置中的 save 60 10000 表示如果在 60 秒内有 10000 个及以上的键被改动时则执行保存数据集操作。
我们在启动 Redis 服务时,服务器会读取配置文件中的配置,所以 RDB 持久化策略会自动启动,当满足条件时会执行持久化处理。
不过,有时我们可能需要手动的执行 RDB 持久化处理,那么 Redis 有没有提供类似的方法呢?
答案是有的,我们可以使用 SAVE](http://redisdoc.com/server/save.html)(这里不是配置文件中的 save 指令) 或 BGSAVE 命令,来手动执行 RDB 持久化处理。
虽然,save 和 bgsave 都可以手动的执行 RDB 持久化处理。但是它们的工作模式完全不同。
注意:虽然通过 SAVE 命令可以执行 RDB 持久化处理,但是它的运行原理同自动持久化中的 save 指令是完全不同的,save 指令的工作原理同 BGSAVE 指令。
在 RDB 持久化策略中,我们引入了「快照」的概念,即「在 x 秒内有 n 个及以上键被改动」则执行持久化处理。
摘自 Redis 持久化。
通过 RDB 持久化方案的学习,我们知道它可能导致数据丢失,如果你的项目忍不了数据丢失的问题,那么可能就需要使用 AOF 持久化方案。
AOF(append only file):只进行追加操作的文件。默认情况下,Redis 会禁用 AOF 重写,无需开启我们需要到配置文件中将 appendonly 指令配置为 yes(默认:no 不启用)。
启用 AOF 持久化方案后,当我们执行类似 SET 设置(或修改)命令时,Redis 会将命令以 Redis 通信协议 文本保存到 appendonly.aof 文件中。
AOF 持久化方案提供 3 种不同时间策略将数据同步到磁盘中,同步策略通过 appendfsync 指令完成:
使用是推荐采用默认的 everysec 每秒同步策略,兼顾安全与效率。
摘自 Redis 持久化。
我们知道 AOF 的运行原理是不断的将写入的命令以 Redis 通信协议的数据格式追加到 .aof 文件末尾,这就会导致文件的体积不断增大。
如果所有的命令完全不同到没有关系。
但是,如果命令处理类似计数器的功能,比如执行 100 次 INCR(incr counter) 处理,AOF 文件会保存全部的 INCR 命令的执行记录,但实际上我们知道这些处理的结果同 set counter 100 并无二致。这就导致我们的 .aof 多存储了 99 条命令记录。
这时,我们就可以使用 Redis 提供的 BGREWRITEAOF 重写命令,将 AOF 文件进行重写优化。
举例:
SET name 'liugongzi'
SET age 18
SET name 'liugongzi handsome'
AOF 文件将这些写入命令保存到(appendonly.aof)文件中,内容如下:
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$9
liugongzi
*3
$3
set
$3
age
$2
18
*3
$3
set
$4
name
$18
liugongzi handsome
写入的内容完全遵循 Redis 通信协议。通过示例,我们知道虽然我们执行了两次 set name 操作,但最终 Redis 保存的 name 值是 liugongzi handsome。也就是说第一次 set name 其实并无必要。
现在我们通过 BGREWRITEAOF 命令对文件进行重写处理:
127.0.0.1:6380> BGREWRITEAOF
Background append only file rewriting started
重写完成后的 AOF 文件内容如下:
*2
$6
SELECT
$1
0
*3
$3
SET
$3
age
$2
18
*3
$3
SET
$4
name
$18
liugongzi handsome
通过对比重写前后的文件内容,可以发现 Redis 将第一次的 set name 'liugongzi' 操作给删出掉了。这样就达到优化 AOF 文件的目的。
补充一句 AOF 重写,并不是对 AOF 文件进行重写,而是依据 Redis 在内存中当前的键值进行重写的。
摘自 Redis 持久化。
通过前面的学习我们了解到 Redis 是如何执行 RDB 和 AOF 持久化处理的,现在我们简单了解下 Redis 是如何恢复 RDB 或 AOF 备份中的数据。
我们知道 Redis 是一种内存型的 NoSQL 数据库(或者说数据结构),当服务重启或宕机都会导致内存中的数据丢失。
所以,当 Redis 服务器重启或恢复时,它会进行读取 RDB 或 AOF 文件(如果存在的话)处理,将文件中的数据重新载入内存实现数据恢复操作。
Redis 数据恢复采用两套恢复方案:
这个很好理解,因为 AOF 持久化方案的数据保存是秒级的,所以相对于 RDB 持久化数据更完整,所以在启动 Redis 服务器是,会在 AOF 启用时有限载入 AOF 文件进行数据还原。
到这里,相信你对 Redis 持久化已经有了相当大了解了,这节开始我们将学习 Redis 配置文件,看看如何使用 RDB 和 AOF 持久化功能。
Redis 服务器配置文件默认是 redis.windows.conf:
RDB 配置位于 SNAPSHOTTING 配置节点。
#save 900 1
#save 300 10
#save 60 10000
通过 rdbcompression 指令完成,默认 yes 进行压缩。
使用 dbfilename 指令,默认值 dump.rdb。
使用 dir 指令,默认值 your_redis_path。另外 AOF 备份数据同样会保存到该目录下。
AOF 配置位于 APPEND ONLY MODE 配置节点。
开启 AOF 持久化功能,通过 appendonly 指令完成,取值范围 yes / no,默认:no 不开启 AOF 重写。
由 appendfilename 指令完成,默认值 appendonly.aof。
请参考前文 appendfsync 指令说明。
之前我们通过使用命令 BGREWRITEAOF 对 AOF 执行重写,但是当我们启用 AOF 持久化功能后,Redis 默认会启用 AOF 重写优化,这个工作有两条指令完成:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 指令表示,本次执行 AOF 重写时,当 AOF 文件的大小是上次执行重写时文件的百分之多少才可以自动重写。默认: 100 表示本次重写时的 AOF 文件是上次 2 倍可以自动重写。
auto-aof-rewrite-min-size 这个指令用于设置进行 AOF 文件自动重写的最小文件大小。
换言之,这两条配置表示:当 AOF 文件大小达到 64mb 时,才开始自动进行重写。下一次只有当文件大小需达到 128 mb 才能再次重写,以此类推。
当我们的 Redis 服务器宕机时,可能导致 AOF 文件的尾部数据不完整,在重启 Redis 服务器可能导致数据不一致。此时可以通过:
aof-load-truncated 指令在启动 Redis 自动修复文件。它的取值范围是 yes / no,默认为 yes 重启时自动修复。
同样的我们也可以通过 redis-check-aof --fix 修复工具手动进行修复。
Redis 持久化解密(https://blog.csdn.net/hanhuili/article/details/12873011) part 2 原文
NoSQL 之【Redis】学习(三):Redis 持久化 Snapshot 和 AOF 说明