第七篇:Redis 为什么要同时支持 RDB 和 AOF?
Redis 为什么要同时支持 RDB 和 AOF?
上一篇我们聊了《Redis 为什么使用跳表,而不是红黑树?》,看到了 Redis 在设计数据结构时的一贯思路:它追求的从来不是"理论上最优秀"的方案,而是在性能、实现复杂度和实际业务之间找到一个平衡点。
这种思想,在 Redis 的持久化设计上体现得更加明显。
很多人第一次学习 Redis 时都会有这样的疑问:既然 RDB 能把内存里的数据保存下来,为什么还要设计一个 AOF?反过来说,如果 AOF 能记录每一次写操作,那 RDB 又还有什么存在的意义?
如果把这个问题理解透了,你就真正理解了 Redis 对"性能"和"可靠性"的取舍。
Redis 为什么需要持久化?
Redis 最大的特点,就是所有数据都保存在内存里。
内存的访问速度远远快于磁盘,这也是 Redis 能达到几十万甚至上百万 QPS 的原因。
但内存有一个天然缺点。
断电就会丢失。
假设现在缓存中保存着:
user:1 -> Tom user:2 -> Jack user:3 -> Lucy服务器突然断电,再次启动 Redis,内存已经恢复成初始状态,所有数据都会消失。对于缓存来说,这可能还能接受。但是很多公司,都会把下面这些数据放进 Redis:
- 登录 Token
- 秒杀库存
- 排行榜
- 热点统计
- 配置信息
如果重启一次全部丢失,显然无法接受。
所以 Redis 必须想办法,把内存里的数据保存到磁盘。
最容易想到的方法,就是保存整个内存
如果让你来设计,你大概率会想到最直接的方案。
既然内存里面保存的是所有数据,那直接把整块内存写到磁盘,下次启动的时候再读回来,不就可以了吗?
这就是 RDB 的思想。可以简单理解成:
Memory │ ▼ 生成 RDB 文件 │ ▼ 重启时重新加载RDB 保存的是某一个时刻 Redis 的完整快照,因此恢复速度非常快。
启动 Redis 时,只需要读取一个文件,就能快速恢复所有数据。
看起来,这已经解决问题了。但是,它还有一个明显缺点。
如果刚保存完,服务器就宕机呢?
假设 Redis 每五分钟生成一次 RDB。时间线可能是这样:
12:00 ↓ 生成 RDB ↓ 12:04 大量写入数据 ↓ 12:05 服务器断电重新启动以后。Redis 只能恢复到:
12:00之后四分钟的数据,全部丢失。如果业务要求数据尽可能少丢,这种方案显然不够。于是 Redis 又开始思考,既然整份快照丢失的数据太多,那能不能不要每次保存整个数据库,而是只记录发生变化的内容?
AOF 的思路完全不同
AOF 并不会保存整个数据库。
它记录的是:执行过哪些写命令。
例如:
SET name Tom HSET user:1 age 18 LPUSH order 1001这些命令都会按照执行顺序写入 AOF 文件。
当 Redis 重启时,只需要重新执行一遍这些命令,数据库就恢复了。
整个过程可以理解成:
客户端写命令 │ ▼ 写入 AOF │ ▼ Redis 重启 │ ▼ 重新执行命令因此,相比 RDB,AOF 能够保存更多的数据。
那是不是只保留 AOF 就够了?
很多人看到这里,会觉得答案已经出来了。
AOF 丢失数据更少,那为什么不直接删除 RDB?其实,两种方案各有优势。先来看 RDB 它最大的特点就是:
恢复速度快。
因为整个文件就是一份完整的数据快照,Redis 不需要执行任何命令,只需要把数据直接加载到内存即可。
而 AOF 就不一样了,假设 Redis 已经运行一年,每天执行几十万条命令,AOF 文件里面,可能已经累计了几千万甚至上亿条写操作,重启时,需要:
读取 AOF ↓ 解析命令 ↓ 重新执行 ↓ 恢复数据命令越多,恢复时间越长。因此,在启动速度这一点上,RDB 明显更有优势。
AOF 还有另一个问题
来看下面这段命令。
INCR stock INCR stock INCR stock INCR stock INCR stock真正需要保存的结果,其实只是:
stock = 5但是 AOF 必须把五条命令全部记录下来,随着 Redis 运行时间越来越长,AOF 文件也会越来越大,如果一直这样增长,不仅占用磁盘空间,还会拖慢 Redis 的恢复速度。所以 Redis 又设计了一套机制。
AOF Rewrite它会重新生成一份新的 AOF,把大量重复命令压缩成最终结果。
例如刚才五次:
INCR stock最终可能变成:
SET stock 5文件立即缩小很多。
下一篇,我们就专门介绍 Rewrite 为什么能做到这一点。
Redis 为什么最终保留两套持久化方案?
为什么 Redis 同时支持 RDB 和 AOF?因为它们解决的是两个完全不同的问题。
RDB 更像是一次拍照
数据库 ↓ 拍一张快照 ↓ 保存下来恢复速度快,占用空间小,但两次快照之间的数据可能丢失。
而 AOF 更像是一本操作日志。
执行命令 ↓ 记录命令 ↓ 重新执行命令数据更加完整,但文件更大,恢复速度也更慢。
所以 Redis 并没有要求开发者二选一,而是把两种方案组合起来。
RDB 提供快速恢复能力。
AOF 提供更好的数据安全。
不同业务,可以根据自己的需求进行选择。这正是 Redis 一贯坚持的设计思想:
不是追求一种万能方案,而是让不同方案互相弥补彼此的缺点。
总结
很多人学习 Redis 持久化时,都会问:
RDB 和 AOF,到底哪个更好?
Redis 从来没有打算让其中一个取代另一个。
RDB 解决的是恢复速度的问题。
AOF 解决的是数据可靠性的问题。
正因为两者关注点不同,所以它们才能长期共存,并且一直都是 Redis 持久化体系中不可缺少的一部分。
上一篇:《Redis 为什么使用跳表,而不是红黑树?》
下一篇:《Redis 为什么不会每次修改都写磁盘?》
如果这篇文章对你有帮助,欢迎点赞、收藏。
你觉得,如果只能在 RDB 和 AOF 中保留一种,Redis 最终会选择谁?欢迎在评论区聊聊你的看法。
