本文首发于 Redis 持久化(persistence)技术口袋书,转载请注明出处。
本文讲解 Redis 数据库的数据持久化解决方案。php
测试环境:html
Redis 提供两种持久化解决方案:RDB 持久化和 AOF 持久化。git
要点:github
RDB 持久化:能够在指定时间间隔内,生成数据集在这个时间点的快照。
AOF 持久化:经过记录服务器执行的全部写操做命令,在服务器重启时,经过从新执行这些命令来还原数据。redis
采用 RDB 持久化方案时,Redis 会每隔一段时间对数据集进行快照备份,换句话说这种方案在服务器发生故障时可能形成数据的丢失。因此,若是对数据的完整性有比较强烈的要求,可能不太适用这种备份方案,即它适用于作数据的备份。shell
咱们已经知道,采用 RDB 持久化方案会每隔一段时间对数据进行备份,那么这个时间段如何肯定呢?数据库
咱们能够到 redis.windows.conf 配置文件的 SNAPSHOTTING 配置节点获取答案,默认状况下 Redis 采用三种持久化策略:windows
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/sa...(这里不是配置文件中的 save 指令) 或 BGSAVE 命令,来手动执行 RDB 持久化处理。
虽然,save 和 bgsave 均可以手动的执行 RDB 持久化处理。可是它们的工做模式彻底不一样。
注意:虽然经过 SAVE 命令能够执行 RDB 持久化处理,可是它的运行原理同自动持久化中的 save 指令是彻底不一样的, save 指令的工做原理同 BGSAVE 指令。
在 RDB 持久化策略中,咱们引入了「快照」的概念,即「在 x 秒内有 n 个及以上键被改动」则执行持久化处理。
- Redis 调用 fork() ,同时拥有父进程和子进程。
- 子进程将数据集写入到一个临时 RDB 文件中。
- 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
摘自 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 修复工具手动进行修复。