Redis 两种持久化方式 RDB 和 AOF

一、单节点 Redis 的问题

1.1 存在的问题

        1、数据丢失问题:Redis 是内存存储,服务重启可能会丢失数据。

        2、并发能力问题:单节点 Redis 并发能力虽然不错,但也无法满足如 618 这样的高并发场景。

        3、故障恢复问题:如果 Redis 宕机,则服务不可用,需要一种自动的故障恢复手段。        

        4、存储能力问题:Redis 基于内存,单节点能存储的数据量难以满足海量数据需求

1.2 解决方案

二、Redis 持久化

2.1 RDB 持久化

2.1.1 简介

        RDB 全称 Redis Database Backup fileRedis 数据备份文件),也被叫做 Redis 数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当 Redis 实例故障重启后,从磁盘读取快照文件,恢复数据。 快照文件称为 RDB 文件,默认是保存在当前运行目录。

        执行 save 命令会阻塞其他的命令,如下图:

        执行 bgsave 命令时则会开启子进程执行备份任务,如下图:

        注意:Redis 正常停机时会执行一次 RDB,突然断电啥的则不会执行。 

2.1.2 触发机制

        Redis 内部有触发 RDB 的机制,可以在 redis.conf 文件中找到,格式如下:

        RDB 的其它配置也可以在 redis.conf 文件中设置,如下图:

2.1.3 底层实现

        bgsave 开始时会 fork 主进程得到子进程,子进程共享主进程的内存数据。完成 fork 后读取内存数据并写入 RDB 文件。

        如下图,首先数据是存在在物理内存上的,而 redis 的主进程如果想要实现对 redis 数据的读写就需要在物理内存上进行读写,而在 linux 环境下,所有的进程都无法直接操作物理内存,而是由操作系统给每个进程分配一个虚拟内存,即主进程只能操作虚拟内存,而操作系统会维护一个虚拟内存和物理内存之间的映射关系表,又称为页表。所以主进程操作虚拟内存,而虚拟内存基于页表的映射关系操作我们的物理内存,这样就实现了对物理内存的读写了。

        而当我们执行 fork 操作时,会创建一个子进程,fork 的过程中会把页表做一份拷贝,也就是把映射关系拷贝给子进程,子进程有了和主进程一样的映射关系,当子进程在操作自己的虚拟内存时,一定会操作和主进程一样的物理内存区域,就实现了子进程和主进程之间的内存共享了。

        此时,当子进程执行备份操作时,就可以放心的读取自己内存的数据,其实读取的就是主进程的数据。之后再把数据写入到磁盘中新的文件中去。到这为止,异步持久化就实现了。

         如果子进程在写 RDB 的过程中,主进程同时在修改数据,此时读与写之间就会有冲突,甚至出现脏数据。为了避免这种事情的发生,fork 的底层采用的是 copy-on-write 技术,当主进程要写的时候做一次拷贝,现在的内存是共享的,没有做拷贝的。此时 fork 会把共享内存标记成 read-only 只读模式,任何一个进程都只能来读数据而不能写。假设此时用户真的来写数据了。此时先拷贝一份数据,再对拷贝的数据完成一份写操作。一旦完成了拷贝,主进程再做读操作的时候也要从拷贝的数据里面读取了,也就是说主进程的页面的映射关系发生了变化。这个就是 copy-on-write 技术。

        但是在某些极端的情况下,假设 RDB 写的过程比较慢,耗时较长。就在它写的过程中,不断的有新的请求进来,不断的修改共享的数据,导致所有的数据都被修改了一遍。就会导致所有的数据都需要拷贝一份新的,也就意味着 redis 对内存的占用翻倍了,这是极端的情况,几乎不可能发生,但是理论上有可能。因此 redis 都需要预留一部分内存空间。假设服务器内存为 32G,不能把 32G 都交给 redis,还需要预留一部分。 

2.1.4 优缺点

RDB 方式 bgsave 的基本流程

        1、fork 主进程得到一个子进程,共享内存空间

        2、子进程读取内存数据并写入新的 RDB 文件

        3、用新 RDB 文件替换旧的 RDB 文件。

RDB 会在什么时候执行?save 60 1000 代表什么含义?

        1、默认是服务停止时。

        2、代表 60 秒内至少执行 1000 次修改则触发 RDB

RDB 的缺点?

        1、RDB 执行间隔时间长,两次 RDB 之间写入数据有丢失的风险

        2、fork 子进程、压缩、写出 RDB 文件都比较耗时

2.2 AOF 持久化

2.2.1 简介

        AOF 全称为 Append Only File(追加文件)。Redis 处理的每一个写命令都会记录在 AOF 文件,可以看做是命令日志文件。其中 $3 表示下面的字母的个数。

2.2.2 触发机制

        AOF 默认是关闭的,需要修改 redis.conf 配置文件来开启 AOF

        AOF 的命令记录的频率也可以通过 redis.conf 文件来配:

2.2.3 底层机制

        因为是记录命令,AOF 文件会比 RDB 文件大的多。而且 AOF 会记录对同一个 key 的多次写操作,但只有最后一次写操作才有意义。可以通过执行 bgrewriteaof 命令,可以让 AOF 文件执行重写功能,用最少的命令达到相同效果。

        Redis 也会在触发阈值时自动去重写 AOF 文件。阈值也可以在 redis.conf 中配置:

2.3 RDB 和 AOF 对比

        RDB AOF 各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值