Redis持久化——RDF与AOF两种方式怎么做?有什么区别?

目录

1. 什么是RDB 

2. save 和 bgsave 命令主动保存数据

2.1 save

2.2 bgsave

3. Redis 内部自动RDB机制

4. RDB 底层是如何实现 bgsave 的?

5. RDB 的缺点

6. 什么是AOF?

7. AOF文件的缺点?

8. AOF 重写文件配置

9. RDB 与 AOF 的区别

10. RDB与AOF的优先级对比?

11. RDB与AOF如何混合使用?

12. 纯缓存模式


1. 什么是RDB 

RDB全称是 Redis Database file(Redis数据备份文件),也被叫做Redis数据快照。

它的原理也很好理解,因为Redis本身是基于内存的,一旦服务器宕机或停电,数据就会丢失,因此 Redis 它本身就带有数据备份的一个功能,它会每隔一段时间将数据从内存写入到磁盘进行保存,保存的数据形成的文件我们就称它为快照,当我们重启 Redis 之后,它就会再次读取快照文件中的数据,将数据恢复,防止数据的丢失,RDB文件默认保存在当前运行目录。

如下图所示,我使用 FinalShell 启动了Redis 的客户端server与服务端cli,pingPong正常,set存和get取也没问题,我们可以看到,在当前运行目录 "myredis" 下,就有一个dump.rdb的文件。它就是数据快照文件

2. save 和 bgsave 命令主动保存数据

2.1 save

save 命令是由 Redis  主进程来执行 RDB 操作,因为 Redis 是单线程的,所以该命令会阻塞所有命令,我们只需要输入 save 即可开启快照保存。

如下图所示,我使用 save 命令保存数据,然后关闭 Redis 再重新启动,此时我没有存储数据,再次 get 获取刚才存储的 name1,可以看到我仍然可以获取到,这就是 save 的功能,可以将我们z之前存入的数据进行持久化保存,下次再重新启动 Redis 时上次存储的数据仍然存在,不影响我们的业务。

但一般情况下我们不推荐使用 save 命令,因为它会阻塞其他命令,而且如果内存中保存的数据量较大,写操作是非常耗费时间的,会导致我们的其他业务也暂停,非常不利于我们业务的进行。

2.2 bgsave

bgsave 全称也叫 Background saving started,意味后台保存,它是来开启一个子进程执行保存数据的工作,而主进程则不受影响。

这里的话也很简单,就和刚才一样运行一下命令即可,这里就不重复演示了。

3. Redis 内部自动RDB机制

除了刚才我所说的手动保存数据的两个命令以外,Redis 内部还提供了自动触发RDB机制,我们可以在 redis.conf 配置文件中找到。

这里补充一点,Redis 内部的RDB机制默认也是使用的 bgsave 命令。

图中的 save 3600 1 表示3600秒之内有一次修改则进行RDB;

save 300 100 表示300秒内有100此操作进行一次RDB;

save 60 10000 表示60秒内有一万次操作进行一次RDB。

我们的 RDB 触发机制应该根据实际业务需求做设置,不能让 basave 过于频繁,尽管是子进程在保存,但还是会消耗资源;但也不能设置的较难触发,否则一旦长时间数据未保存,宕机造成数据丢失的后果也是较为严重的,因此我们需要在这两个方面做取舍,设置一个合理的触发时机,通常我们就默认选择 save 300 100 即可,也可以自定义设置。

4. RDB 底层是如何实现 bgsave 的?

当 Redis 在进行bgsave 持久化操作时,刚才我们知道了,该操作是开启了一个子进程来执行的。bgsave 命令虽然开启了一个子进程避免主进程阻塞,但是在 fork 主进程的这个过程中,主进程仍然是处于阻塞状态的。此时主进程就不能接受用户请求。

得到子进程之后,子进程就可以共享主进程的内存数据,然后读取内存中的数据写入到 RDB 文件。大致流程如下图所示

Redis 是把数据存储在内存中的,但是在 Linux 操作系统底层,操作系统它是不会让这些线程去直接接触内存中的数据的,而是给进程一个页表,你可以把它理解为名单,你要做什么操作,直接在名单上去做,然后操作系统会代替你去执行。而我们在进行 fork 时,其实就是 fork 的页表,然后从页表中去读取数据,再写入到磁盘中。

但是这种情况下会有个问题,如果我的子进程正在读写数据,而主进程却要去修改数据,这个时候就会产生冲突。

因此,为了解决这种情况的发生,fork 采用的是 copy-on-write 的技术

当我们子进程向磁盘去写数据的时候,fork 会把内存中的可能产生冲突的共享数据标记为 readOnly(只读),任何一个进程都只能来读数据而不能写数据,当我们的主进程想要去修改数据的时候,它会先把要写的数据完整的拷贝一份出来(如下图数据B副本),然后对拷贝的数据进行写操作当我们主进程再去读的时候,也会读到拷贝的数据,主进程页表与内存中数据的映射关系发生了改变。如下图所示

这是少数数据发生修改时可能出现的情况,还有一种比较罕见的情况,如果我们的数据较多,写的过程比较慢,在这个过程中,大量的数据都发生了修改,那么在操作系统底层会把这些修改的数据全部复制一份,如果再复制数据之前,内存已经快要被Redis 的数据占满了,那么在复制数据的过程中,就会出现内存溢出的情况各位明白吧,就是你现在需要这么多内存空间去复制数据,但是内存不够了,导致内存溢出。这种情况虽然比较罕见,但我们仍需要考虑在内,因此,我们Linux 操作系统在给 Redis 分配内存的时候,通常不会把全部的内存全部交给Redis,而是会保留一部分,防止内存溢出这种情况的发生。

5. RDB 的缺点

通过上面的描述,我们也大概能总结出RDB持久化方案的两个缺点

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

(2)fork 子进程,压缩,写出RDB文件都比较耗时;

6. 什么是AOF?

AOF 全程 Append Only File(追加文件)。Redis 处理的每一个命令都会记录在AOF文件中,可以把它看作是命令日志文件。

AOF在 Redis 中是默认关闭的,需要我们在配置文件中去开启,在配置文件中找到相关配置如下。

appendonly:默认为no,改为 yes 即可进行开启;

appendfilename:"appendonly.aof" 是AOF的文件名称,这里不需要改;

下面还有一个 appendfsync 表示命令记录的频率。

always:表示每执行一次写命令,立即记录到AOF文件中;

everysec:写命令执行先放入AOF缓冲区,然后每隔一秒将缓冲区数据写到AOF文件中,是默认选项;

no:写命令执行先放入缓冲区,由操作系统决定何时写入到磁盘;

三者的对比如下图所示

7. AOF文件的缺点?

AOF 文件它会把所有的操作命令全部都记录下来,就算你对同一个数据进行多次修改操作,但是AOF文件仍然还是会把所有之前的操作命令全部都记录下来,所以AOF文件的大小通常都会比RDB文件要大。

但是,我们可以通过 "bgrewriteaof" 命令让 AOF 文件执行重写功能,用最少的命令达到相同的效果。

举例,我在对 Redis 进行了三次操作,set name zhangsan;set age 18;set name lisi;

经过AOF重写功能之后,上面的三个命令就会转化成 mset name lisi age 18;将三个命令简化成一个命令,减少了所占的存储空间。

8. AOF 重写文件配置

Redis 的AOF文件重写也是有触发阈值的,我们可以使用默认的,也可以在 redis.conf 配置文件中自行配置,这里我截取了配置文件中的一段

auto-aof-rewrite-percentage:后面表示的是百分数,这次的文件相比上次的文件体积增加了百分之百时,就会触发重写;

auto-aof-rewrite-min-size:表示AOF 文件最小为64mb 时会触发重写;

9. RDB 与 AOF 的区别

RDB与AOF都有各自的优缺点,它们的区别大致就如下表中所呈现的,在实际开发过程中往往会结合二者来使用。

10. RDB与AOF的优先级对比?

下图是 redis.conf 配置文件中关于 AOF 功能的一部分注释说明,大概的意思就是,"RDB和AOF两种持久化机制可以共存,也就是可以以一起使用确保我们数据的安全性,如果AOF在初始被开启了,那么AOF将优先于RDB加载,因为AOF比RDB更精确"。如果面试官问你的时候你能顺带答出来这一点,我想会对你刮目相看的,说明你有认真的阅读过 Redis 的配置文件。

RDB与AOF的加载流程图及说明如下所示,

(首先)Redis 再重启之后,它会优先判断是否存在AOF文件,如果存在AOF文件,重启后就会优先加载AOF文件恢复数据,恢复数据成功;

(其次)如果不存在AOF文件,就会再去判断是否有RDB文件,若有RDB文件就会加载RDB文件恢复数据,恢复数据成功;

(最后)若RDB文件与AOF文件都不存在,则恢复数据失败;

11. RDB与AOF如何混合使用?

通过上面RDB与AOF是可以混合使用的,开启混合使用的方式:设置 aof-use-rdb-preamble 的值为yes,yes表示开启,no表示不开启;

RDB镜像做全量持久化,AOF做增量持久化。先使用RDB做快照存贮,再使用AOF持久化记录所有的写操作,当重写策略满足或手动出发重写的时候,将最近的数据存储为最新的RDB记录。简单的来说,混合持久化方式产生的文件一部分是RDB格式,一部分是AOF格式。在进行重启服务的时候,既保证了数据的准确性,又提高了恢复数据的性能。

12. 纯缓存模式

见名知意,纯缓存模式就是让 Redis 只做缓存功能,持久化功能不需要你 Redis 去做,我们会手动持久化或采取别的方式。

说白了,纯缓存模式就是关闭 Redis 的持久化功能,即RDB与AOF功能全都关闭,大家注意,这里所说的关闭是关闭默认的RDB与AOF自动持久化功能,如果我们调用RDB与AOF的持久化命令,Redis 仍然可以进行持久化,只是在关闭之后,Redis 不会再自动进行持久化了

禁用RDB功能执行 save "" 即可,save + 空字符串就可以关闭RDB功能;

禁用AOF功能在配置文件中将 appendonly no 保持关闭即可,不要 yes 开启;

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值