大纲
- 为什么要做数据持久化
- 数据持久化方式(RDB 和 AOF 介绍)
- RDB 的优缺点
- AOF 的优缺点
开篇
本文着重讲得是 redis 数据持久化,不会去介绍 redis 是什么,它的特性是什么,以及安装方式,使用场景等等。
正文
一. 为什么要做数据持久化
或者我们还可以这样问,什么情况下需要做数据持久化?
这需要结合你的业务场景去选择,当然大部分情况下,还是建议大家去做 redis 的数据持久化。
回到原题,我们做数据持久化的目的是用于故障恢复。
举个例子:
我最近接手到的 xx 系统,它的数据就直接存在 redis 中,或者说我们就是把 redis 当作一个持久化数据库在用,这样做的原因就先不说了。根据这样一个应用场景,假设我们不做数据持久化,万一 redis 挂掉,我们的数据就全没了,如何跟客户去交代??? ~~~~~ 只能跑路~~~
那么问题又来了,
-
redis 是怎么做数据持久化的?
-
如果我们做了数据持久化,就能保证一条数据都不会丢了吗?
请接着往下看 ⬇️️️
二. redis 数据持久化方式
redis 提供了两种不同的持久化方式: RDB 和 AOF。
-
RDB : 定期保存一份 redis 快照数据到 rdb 文件当中
-
AOF : 把每一个写操作都记录在一个日志文件里
说的通俗一点就是:
RDB 就是将 redis 的数据保存到一份 rdb 文件中,当我们启动 redis 时,redis 会把这个文件的数据 load 到内存中。(这里先不要管 redis 如何 load 的)
AOF 就是记录每一个 redis 写指令, 比如 set key value。当需要恢复数据时,redis 会把这个文件的这些写指令,全都执行一遍。
也许到这里你还是会有很多疑问,比如:
- 写文件写到一半,redis 挂掉怎么办? 因为文件不完整了
- 生成数据快照的时候,如果 redis 挂掉,不也是会丢数据吗?
这些下面会提到,另外只凭上面讲得那些设计,你也应该要想到会出现这样那样的问题。
三. RDB 数据持久化的优缺点
优点
- RDB 非常适合做冷备,它会把每个时间点的完整数据保存到一份 rbd 文件中。比如把过去 24 小时的数据按每 1 小时保存一次,或者过去 30 天的数据,每隔一天保存一次
- RDB对于灾难恢复非常有用,它是一个紧凑的文件,可以传输到远程的安全存储上
- RDB对 redis 对外提供的读写服务影响非常小,可以让 redis 保持高性能,因为 redis 主进程只需要 fork 一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可
- 相比于 AOF,直接基于 RDB 数据文件来重启和恢复 redis 进程,会更快
缺点
- 相比于 AOF, 当 redis 因为某种原因(比如停电)突然不能工作后,要想保证数据尽可能少丢失,RDB 可能表现的没有那么多好
- RDB 每次在 fork 子进程来执行 RDB 快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒。虽然 AOF 也需要 fork ,但是你可以调整要重写日志的频率,而无需在持久性上进行权衡(这点可以先不用理解,后面讲 AOF, 再说)
四. AOF 数据持久化的优缺点
优点
- AOF 可以更好的保护数据不丢失,默认策略是 AOF 会每隔1秒,通过一个后台线程执行一次 fsync 操作。redis进程挂了,最多丢失1秒钟的数据
三个 fsync 策略
1. no fsync at all
2. fsync every second(默认)
3. fsync at every query
简单来讲,fsync 操作,就是保证操作系统 cache 中的数据写入磁盘中(多说无益)
- AOF日志文件以 append-only 模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复
如何修复?
假如本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,
在 Redis 下一次启动之前,我们可以通过 redis-check-aof 工具来帮助我们解决数据一致性的问题。
- 当 AOF 日志文件过大的时候,redis 能够在后台自动进行 rewrite 操作,并且不会影响客户端的读写。
什么是 rewrite 操作?
AOF采用文件追加方式,为避免文件会越来越大,新增了重写机制。
当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,
只保留可以恢复数据的最小指令集.(可以使用命令bgrewriteaof)
重写原理
AOF文件持续增长而过大时,会 fork 出一条新进程来将文件重写(也是先写临时文件最后再rename),
重写 AOF 文件的操作,并不会读取旧的 AOF 文件(因此不会影响旧的 AOF 文件的写入)。
而是将整个内存中的数据用命令的方式生成一个新的 AOF 文件.
- AOF 包含一个格式清晰、易于理解的日志文件,用于记录所有的修改操作。因此非常适合做灾难性的误删除的紧急恢复。比如有人不小心用 FLUSHALL 命令清空了所有数据,只要这个时候后台 rewrite 还没有发生,那么就可以停止服务,将最后一条 FLUSHALL 命令给删了,然后重启 redis ,就可以自动恢复所有数据
缺点
-
对同一份数据来说,AOF日志文件通常比 RDB 数据快照文件更大
-
根据确切的 fsync 策略,AOF 可能比 RDB 慢。但是在将fsync设置为每秒的情况下,性能仍然很高,并且在禁用 fsync 的情况下,即使在高负载下,它也应与RDB一样快。即使在巨大的写负载情况下,RDB 仍然能够提供有关最大延迟的更多保证。
-
以前 AOF 发生过 bug,就是通过 AOF 记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。所以说,类似 AOF 这种基于命令日志回放的方式,比基于 RDB 每次持久化一份完整的数据快照文件的方式,更加脆弱一些,容易有bug。不过 AOF 就是为了避免 rewrite 过程导致的 bug,因此每次 rewrite 并不是基于旧的指令日志进行 merge 的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。
总之,AOF 唯一的比较大的缺点,其实就是做数据恢复的时候,会比较慢,还有做冷备,定期的备份,不太方便,可能要自己手写复杂的脚本去做。
未完待续
看到这里,你也许期待会有具体的持久化方案,以及持久化配置等等。这些会在后面的文章补充,因为个人不喜欢篇幅过长,讲得东西一大堆,消化不了~~~
总结
本文主要说了 redis 数据持久化的两种方式以及对应的优缺点。当然文章也出现了对部分人来说相对陌生的名词,比如 fsync,冷备等,以及难以理解,或者很绕的解释,比如讲 AOF 优缺点时,提到的 rewrite 方面的东西。 这都需要多看,多理解,也可以参考他人的文章。(没讲明白的地方,请见谅)
读完此文,可以转入
Redis 持久化方式 - RDB 和 AOF 配置及 rewrite 机制
来源:oschina
链接:https://my.oschina.net/u/3984985/blog/3162452