Redis 数据持久化

依然范特西╮ 提交于 2020-02-28 11:12:34

大纲

  1. 为什么要做数据持久化
  2. 数据持久化方式(RDB 和 AOF 介绍)
  3. RDB 的优缺点
  4. AOF 的优缺点

开篇

本文着重讲得是 redis 数据持久化,不会去介绍 redis 是什么,它的特性是什么,以及安装方式,使用场景等等。

正文

一. 为什么要做数据持久化

或者我们还可以这样问,什么情况下需要做数据持久化?

这需要结合你的业务场景去选择,当然大部分情况下,还是建议大家去做 redis 的数据持久化。

回到原题,我们做数据持久化的目的是用于故障恢复。

举个例子:

我最近接手到的 xx 系统,它的数据就直接存在 redis 中,或者说我们就是把 redis 当作一个持久化数据库在用,这样做的原因就先不说了。根据这样一个应用场景,假设我们不做数据持久化,万一 redis 挂掉,我们的数据就全没了,如何跟客户去交代??? ~~~~~ 只能跑路~~~

那么问题又来了,

  1. redis 是怎么做数据持久化的?

  2. 如果我们做了数据持久化,就能保证一条数据都不会丢了吗?

请接着往下看 ⬇️️️

二. redis 数据持久化方式

redis 提供了两种不同的持久化方式: RDB 和 AOF。

  1. RDB : 定期保存一份 redis 快照数据到 rdb 文件当中

  2. AOF : 把每一个写操作都记录在一个日志文件里

说的通俗一点就是:

RDB 就是将 redis 的数据保存到一份 rdb 文件中,当我们启动 redis 时,redis 会把这个文件的数据 load 到内存中。(这里先不要管 redis 如何 load 的)

AOF 就是记录每一个 redis 写指令, 比如 set key value。当需要恢复数据时,redis 会把这个文件的这些写指令,全都执行一遍。

也许到这里你还是会有很多疑问,比如:

  1. 写文件写到一半,redis 挂掉怎么办? 因为文件不完整了
  2. 生成数据快照的时候,如果 redis 挂掉,不也是会丢数据吗?

这些下面会提到,另外只凭上面讲得那些设计,你也应该要想到会出现这样那样的问题。

三. RDB 数据持久化的优缺点

优点
  1. RDB 非常适合做冷备,它会把每个时间点的完整数据保存到一份 rbd 文件中。比如把过去 24 小时的数据按每 1 小时保存一次,或者过去 30 天的数据,每隔一天保存一次
  2. RDB对于灾难恢复非常有用,它是一个紧凑的文件,可以传输到远程的安全存储上
  3. RDB对 redis 对外提供的读写服务影响非常小,可以让 redis 保持高性能,因为 redis 主进程只需要 fork 一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可
  4. 相比于 AOF,直接基于 RDB 数据文件来重启和恢复 redis 进程,会更快
缺点
  1. 相比于 AOF, 当 redis 因为某种原因(比如停电)突然不能工作后,要想保证数据尽可能少丢失,RDB 可能表现的没有那么多好
  2. RDB 每次在 fork 子进程来执行 RDB 快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒。虽然 AOF 也需要 fork ,但是你可以调整要重写日志的频率,而无需在持久性上进行权衡(这点可以先不用理解,后面讲 AOF, 再说)

四. AOF 数据持久化的优缺点

优点
  1. AOF 可以更好的保护数据不丢失,默认策略是 AOF 会每隔1秒,通过一个后台线程执行一次 fsync 操作。redis进程挂了,最多丢失1秒钟的数据

三个 fsync 策略

1. no fsync at all
2. fsync every second(默认)
3. fsync at every query

简单来讲,fsync 操作,就是保证操作系统 cache 中的数据写入磁盘中(多说无益)

  1. AOF日志文件以 append-only 模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复

如何修复?

假如本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,
在 Redis 下一次启动之前,我们可以通过 redis-check-aof 工具来帮助我们解决数据一致性的问题。
  1. 当 AOF 日志文件过大的时候,redis 能够在后台自动进行 rewrite 操作,并且不会影响客户端的读写。

什么是 rewrite 操作?

AOF采用文件追加方式,为避免文件会越来越大,新增了重写机制。
 
当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,
只保留可以恢复数据的最小指令集.(可以使用命令bgrewriteaof)

重写原理

AOF文件持续增长而过大时,会 fork 出一条新进程来将文件重写(也是先写临时文件最后再rename),
重写 AOF 文件的操作,并不会读取旧的 AOF 文件(因此不会影响旧的 AOF 文件的写入)。
而是将整个内存中的数据用命令的方式生成一个新的 AOF 文件.
  1. AOF 包含一个格式清晰、易于理解的日志文件,用于记录所有的修改操作。因此非常适合做灾难性的误删除的紧急恢复。比如有人不小心用 FLUSHALL 命令清空了所有数据,只要这个时候后台 rewrite 还没有发生,那么就可以停止服务,将最后一条 FLUSHALL 命令给删了,然后重启 redis ,就可以自动恢复所有数据
缺点
  1. 对同一份数据来说,AOF日志文件通常比 RDB 数据快照文件更大

  2. 根据确切的 fsync 策略,AOF 可能比 RDB 慢。但是在将fsync设置为每秒的情况下,性能仍然很高,并且在禁用 fsync 的情况下,即使在高负载下,它也应与RDB一样快。即使在巨大的写负载情况下,RDB 仍然能够提供有关最大延迟的更多保证。

  3. 以前 AOF 发生过 bug,就是通过 AOF 记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。所以说,类似 AOF 这种基于命令日志回放的方式,比基于 RDB 每次持久化一份完整的数据快照文件的方式,更加脆弱一些,容易有bug。不过 AOF 就是为了避免 rewrite 过程导致的 bug,因此每次 rewrite 并不是基于旧的指令日志进行 merge 的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。

总之,AOF 唯一的比较大的缺点,其实就是做数据恢复的时候,会比较慢,还有做冷备,定期的备份,不太方便,可能要自己手写复杂的脚本去做。

未完待续

看到这里,你也许期待会有具体的持久化方案,以及持久化配置等等。这些会在后面的文章补充,因为个人不喜欢篇幅过长,讲得东西一大堆,消化不了~~~

总结

本文主要说了 redis 数据持久化的两种方式以及对应的优缺点。当然文章也出现了对部分人来说相对陌生的名词,比如 fsync,冷备等,以及难以理解,或者很绕的解释,比如讲 AOF 优缺点时,提到的 rewrite 方面的东西。 这都需要多看,多理解,也可以参考他人的文章。(没讲明白的地方,请见谅)

读完此文,可以转入

Redis 持久化方式 - RDB 和 AOF 配置及 rewrite 机制

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!