从零 Redis 系列 -- 持久化数据


Redis 持久化

redis 提供了2种方式来做持久化,分别是 RDB方式 和 AOF方式

RDB

RDB 持久化是指 redis 会生成一个默认为 dump.rdb 的文件来保存数据,在 redis 宕机或者启动的时候,可以从 rdb 文件来恢复数据,达到持久化的目的。 不过 rdb 文件并不是实时生成的,它是由 Redis 在 fork 出一个子进程之后,子进程先将数据写入到一个临时的 rdb 文件里面;然后替换旧的 rdb 文件。因此 这种持久化方式还是有一定的几率丢失数据的。但是 rdb 的持久化比 aof 的持久化更适合做备份,因为 rdb 文件可以看作是某个时间点的备份,通过一个 rdb 文件 可以直接恢复到指定的时间点。并且 rdb 恢复数据比 aof 恢复数据更快捷安全。

redis 什么时候会 fork 子进程来做数据的持久化呢?

redis.conf 里面的 save 配置项决定了 redis 什么时候会 fork 子进程做数据持久化

save 1 1save 300 10save 60 10000
1 秒之内有 1 个 key 做了修改会持久化300 秒之内有 10 个 key 做了修改会持久化60 秒之内有 10000 个 key 做了修改会持久化

AOF

AOF(append only file) 持久化是通过将 redis 的操作指令记录到 aof 文件中,来达到持久化数据的效果。在 redis 启动的时候,会解析 aof 文件,然后”逆向”的根据 aof 里面的指令来生成持久化的数据。 但是 aof 的文件体积比 rdb 文件大,因为 aof 里面存储的是可识别的 redis 指令,而 rdb 文件是一个数据文件。针对 aof 文件体积过大的问题,redis 也提供了 aof 文件重写功能,来压缩 aof 文件。可以修改 redis.conf 里面的 auto-aof-rewrite-percentageauto-aof-rewrite-min-size 来重写 aof 文件,减少 aof 的体积。redis 也提供了 appendfsync 来控制 aof 指令写入的策略。

fsync() 是 redis 写入数据的一个方法,可以看作 redis 调用一次 fsync(),内存里面的数据就会被真正的持久化到文件中,否则 redis 的数据一直是在内存中存储。

noalwayseverysec
从不调用fsync(),由 os 自己决定,持久性较差每写一次就调用一次 fsync(),对性能比较由影响默认的配置,每秒调用一次 fsync(),兼顾了性能和持久性

混合模式

在 redis4.0 版本的时候,出现了一个配置项 aof-use-rdb-preamble=yes ,默认为 no,当设置为 yes 之后,在 redis 进行 rewrite aof 文件的时候,会把 aof 文件的内容由操作指令 变更为 rdb 内容和 aof 操作指令。如果在重写了 aof 文件之后,又没有达到重写条件之前,aof 文件存储的内容还是 redis 的操作命令。

只有当 aof 文件达到重写条件的时候,aof 的内容才会变成 rdb 和 aof 的混合模式,否则 aof 追加的内容一直是操作指令

# 增长百分比为100的时候,会重写 aof 文件,可以理解为就是压缩一些不必要的命令
auto-aof-rewrite-percentage 100
# 64mb 的时候就可以重写 aof 文件
auto-aof-rewrite-min-size 1kb
aof-use-rdb-preamble=yes

生产环境配置

在生产环境中,对于数据的持久化要求比较高,也对于数据的完整性也比较高。可以同时开启 aof 和 rdb 的持久化方式。这两种方式并不冲突,而且两者搭配基本上可以做到很高的持久化。

假设在 redis 宕机之后,数据里面既有 aof 文件也有 rdb 文件,那么数据会从哪个文件里面恢复呢?

redis 会从 aof 文件中恢复数据,因为 aof 文件里面的内容是 redis 操作指令,记录的数据比较完整。

  #redis 

« 从零 Redis 系列 -- 常用命令 从零 Redis 系列 -- 使用 Docker Compose 创建集群 »
blog comments powered by Disqus