写点什么

Redis 的持久化机制和 AOF 文件重写原理

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:1887 字

    阅读完需:约 6 分钟

redis 提供了三种方式来触发 RDB 机制:save、bgsave 和自动触发。


  1. **save 触发方式:**这种方式不推荐使用,因为在执行 save 命令期间,redis 的主进程会被阻塞而无法继续处理客户端发送过来的命令请求。

  2. **bgsave 触发方式:**与 save 命令不同,执行 bgsave 命令时,redis 会 fork 出一条子进程来完成 RDB 持久化操作,这种方式只会在 fork 操作时发生短暂的阻塞,在子进程执行 RDB 持久化操作的同时,主进程依然可以继续处理客户端发送过来的命令请求。redis 基本都使用这种方式来触发 RDB 机制。

  3. **自动触发方式:**通过在 redis.conf 配置文件中配置来实现,格式为“save m n”,表示 m 秒内,数据如果发生 n 次修改则自动触发 bgsave 命令。


**注意:**RDB 持久化方式是可能发生数据丢失的情况的,刚才说过这种持久化方式是将数据以快照的


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


形式写入二进制文件中,而快照只是某一时刻内存中的数据,试想如果子进程高高兴兴地拿着这个快照去进行持久化了,而这期间主进程继续处理客户端的请求使得内存中的数据发生了修改,那么子进程仅凭手中的快照是无法得知数据已经被修改过了,也就是说主进程的修改在子进程是不会反应出来的,这样将会丢失持久化期间变化的数据内容。

二、AOF 机制

AOF 机制是将每一个写命令通过 write 函数保存到文件中,就好像日志记录一样,与 RDB 不同,AOF 机制记录的不是内存中的数据,而是每一条命令。


这样随之而来一个问题:随着时间的推移,AOF 文件体积会逐渐膨胀变得越来越大。为了解决这个问题,引入了“AOF 文件重写机制”,该机制的原理将在后面谈到,重写之后的新 AOF 文件与旧文件相比,新旧两个文件所保存的数据库状态是相同的,但是新 AOF 文件不会包含浪费空间的冗余命令,因此文件重写机制能大大减小 AOF 文件的体积。


redis 也提供了三种方式来触发 AOF 机制:always、everysec、no。


  1. **always:**每次数据发生修改都会记录到磁盘,这种方式性能较差但数据完整性较好。

  2. **everysec:**每秒记录一次数据,但如果一秒内发生了宕机,将会丢失这一秒钟内修改或新增过的数据。推荐使用这种方式。

  3. **no:**从不同步数据。

三、RDB 机制和 AOF 机制该如何选择?

正所谓小孩子才做选择,大人全都要。通常都是将两种机制结合使用比较好,当然如果场景特殊则参考下表自行定夺。


<table align="center" border="1" cellspacing="0"><tbody><tr><td style="text-align:center;vertical-align:middle;width:142pt;"><p style="margin-left:0pt;"> </p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;"><strong><strong>RDB</strong></strong></p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;"><strong><strong>AOF</strong></strong></p></td></tr><tr><td style="text-align:center;vertical-align:middle;width:142pt;"><p style="margin-left:0pt;"><strong><strong>体积</strong></strong></p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;">小</p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;">大</p></td></tr><tr><td style="text-align:center;vertical-align:middle;width:142pt;"><p style="margin-left:0pt;"><strong><strong>恢复速度</strong></strong></p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;">快</p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;">慢</p></td></tr><tr><td style="text-align:center;vertical-align:middle;width:142pt;"><p style="margin-left:0pt;"><strong><strong>数据安全性</strong></strong></p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;">可能会发生数据丢失</p></td><td style="text-align:center;vertical-align:middle;width:142.05pt;"><p style="margin-left:0pt;">根据策略决定</p></td></tr></tbody></table>

四、AOF 文件重写原理

AOF 重写并不需要对原来的 AOF 文件进行读取、写入和分析等操作,而是直接读取当前数据库状态来实现的。首先从数据库中读取键现在的值,然后用一条命令去记录键值对,用这一条命令代替之前记录该键值对的多个命令。


AOF 文件重写涉及到两个重要的问题及解决办法如下。

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Redis 的持久化机制和AOF文件重写原理