一文搞懂Redis架构演化之路( 二 )


文章插图
这种持久化方案,其实就是我们经常听到的 Redis AOF(Append Only File) 。
Redis AOF 持久化提供了 3 种刷盘机制:

  • appendfsync always:主线程同步 fsync
  • appendfsync no:由 OS fsync
  • appendfsync everysec:后台线程每间隔1秒 fsync
解决了数据实时持久化,我们还会面临另一个问题,数据实时写入 AOF,随着时间的推移,AOF 文件会越来越大,那使用 AOF 恢复时变得非常慢,这该怎么办?
Redis 很贴心地提供了 AOF rewrite 方案,俗称 AOF 「瘦身」,顾名思义,就是压缩 AOF 的体积 。
因为 AOF 里记录的都是每一次写命令,例如执行 set k1 v1,set k1 v2,其实我们只关心数据的最终版本 v2 就可以了 。AOF rewrite 正是利用了这个特点,在 AOF 体积越来越大时(超过设定阈值),Redis 就会定期重写一份新的 AOF,这个新的 AOF 只记录数据的最终版本就可以了 。
一文搞懂Redis架构演化之路

文章插图
这样就可以压缩 AOF 体积 。
除此之外,我们可以换个角度,思考一下还有什么方式可以持久化数据?
这时你就要结合 Redis 的使用场景来考虑了 。
回忆一下,我们在使用 Redis 时,通常把它用作什么场景?
是的,缓存 。
把 Redis 当做缓存来用,意味着尽管 Redis 中没有保存全量数据,对于不在缓存中的数据,我们的业务应用依旧可以通过查询后端数据库得到结果,只不过查询后端数据的速度会慢一点而已,但对业务结果其实是没有影响的 。
基于这个特点,我们的 Redis 数据持久化还可以用「数据快照」的方式来做 。
那什么是数据快照呢?
简单来讲,你可以这么理解:
  • 你把 Redis 想象成一个水杯,向 Redis 写入数据,就相当于往这个杯子里倒水 。
  • 此时你拿一个相机给这个水杯拍一张照片,拍照的这一瞬间,照片中记录到这个水杯中水的容量,就是水杯的数据快照 。

一文搞懂Redis架构演化之路

文章插图
也就是说,Redis 的数据快照,是记录某一时刻下 Redis 中的数据,然后只需要把这个数据快照写到磁盘上就可以了 。
它的优势在于,只在需要持久化时,把数据「一次性」写入磁盘,其它时间都不需要操作磁盘 。
基于这个方案,我们可以「定时」给 Redis 做数据快照,把数据持久化到磁盘上 。
一文搞懂Redis架构演化之路

文章插图
这种方案就是我们经常听到的 Redis RDB,RDB 采用「定时快照」的方式进行数据持久化,它的优点是:
  • 持久化文件体积小(二进制 + 压缩)
  • 写盘频率低(定时写入)
缺点也很明显,因为是定时持久化,数据肯定没有 AOF 实时持久化完整,如果你的 Redis 只当做缓存,对于丢失数据不敏感(可从后端的数据库查询),那这种持久化方式是非常合适的 。
如果让你来选择持久化方案,你可以这样选择:
  • 业务对于数据丢失不敏感,选 RDB
  • 业务对数据完整性要求比较高,选 AOF
理解了 RDB 和 AOF,我们再进一步思考一下,有没有什么办法,既可以保证数据完整性,还能让持久化文件体积更小,恢复更快呢?
回顾一下我们前面讲到的,RDB 和 AOF 各自的特点:
  • RDB 以二进制 + 数据压缩方式存储,文件体积小
  • AOF 记录每一次写命令,数据最全
我们可否利用它们各自的优势呢?
当然可以,这就是 Redis 的「混合持久化」 。
要想数据完整性更高,肯定就不能只用 RDB 了,重点还是要放在 AOF 优化上 。
具体来说,当 AOF 在做 rewrite 时,Redis 先以 RDB 格式在 AOF 文件中写入一个数据快照,再把在这期间产生的每一个写命令,追加到 AOF 文件中 。
因为 RDB 是二进制压缩写入的,这样 AOF 文件体积就变得更小了 。
一文搞懂Redis架构演化之路

文章插图
因为 AOF 体积进一步压缩,你在使用 AOF 恢复数据时,这个恢复时间就会更短了!
Redis 4.0 以上版本才支持混合持久化 。
注意:混合持久化是对 AOF rewrite 的优化,这意味着使用它必须基于 AOF + AOF rewrite 。
这么一番优化,你的 Redis 再也不用担心实例宕机了,当发生宕机时,你就可以用持久化文件快速恢复 Redis 中的数据 。
但这样就没问题了吗?
仔细想一下,虽然我们已经把持久化的文件优化到最小了,但在恢复数据时依旧是需要时间的,在这期间你的业务应用无法提供服务,这怎么办?


推荐阅读