
目录1. 什么是RDB2. save 和 bgsave 命令主动保存数据2.1 save2.2 bgsave3. Redis 内部自动RDB机制4. RDB 底层是如何实现 bgsave 的5. RDB 的缺点6. 什么是AOF7. AOF文件的缺点8. AOF 重写文件配置9. RDB 与 AOF 的区别10. RDB与AOF的优先级对比11. RDB与AOF如何混合使用12. 纯缓存模式1. 什么是RDBRDB全称是 Redis Database file(Redis数据备份文件)也被叫做Redis数据快照。它的原理也很好理解因为Redis本身是基于内存的一旦服务器宕机或停电数据就会丢失因此 Redis 它本身就带有数据备份的一个功能它会每隔一段时间将数据从内存写入到磁盘进行保存保存的数据形成的文件我们就称它为快照当我们重启 Redis 之后它就会再次读取快照文件中的数据将数据恢复防止数据的丢失RDB文件默认保存在当前运行目录。如下图所示我使用 FinalShell 启动了Redis 的客户端server与服务端clipingPong正常set存和get取也没问题我们可以看到在当前运行目录 myredis 下就有一个dump.rdb的文件。它就是数据快照文件2. save 和 bgsave 命令主动保存数据2.1 savesave 命令是由 Redis 主进程来执行 RDB 操作因为 Redis 是单线程的所以该命令会阻塞所有命令我们只需要输入 save 即可开启快照保存。如下图所示我使用 save 命令保存数据然后关闭 Redis 再重新启动此时我没有存储数据再次 get 获取刚才存储的 name1可以看到我仍然可以获取到这就是 save 的功能可以将我们z之前存入的数据进行持久化保存下次再重新启动 Redis 时上次存储的数据仍然存在不影响我们的业务。但一般情况下我们不推荐使用 save 命令因为它会阻塞其他命令而且如果内存中保存的数据量较大写操作是非常耗费时间的会导致我们的其他业务也暂停非常不利于我们业务的进行。2.2 bgsavebgsave 全称也叫 Background saving started意味后台保存它是来开启一个子进程执行保存数据的工作而主进程则不受影响。这里的话也很简单就和刚才一样运行一下命令即可这里就不重复演示了。3. Redis 内部自动RDB机制除了刚才我所说的手动保存数据的两个命令以外Redis 内部还提供了自动触发RDB机制我们可以在 redis.conf 配置文件中找到。这里补充一点Redis 内部的RDB机制默认也是使用的 bgsave 命令。图中的 save 3600 1 表示3600秒之内有一次修改则进行RDBsave 300 100 表示300秒内有100此操作进行一次RDBsave 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持久化方案的两个缺点1RDB 执行时间间隔长两次RDB之间写入数据有丢失风险2fork 子进程压缩写出RDB文件都比较耗时6. 什么是AOFAOF 全程 Append Only File(追加文件)。Redis 处理的每一个命令都会记录在AOF文件中可以把它看作是命令日志文件。AOF在 Redis 中是默认关闭的需要我们在配置文件中去开启在配置文件中找到相关配置如下。appendonly默认为no改为 yes 即可进行开启appendfilenameappendonly.aof 是AOF的文件名称这里不需要改下面还有一个 appendfsync 表示命令记录的频率。always表示每执行一次写命令立即记录到AOF文件中everysec写命令执行先放入AOF缓冲区然后每隔一秒将缓冲区数据写到AOF文件中是默认选项no写命令执行先放入缓冲区由操作系统决定何时写入到磁盘三者的对比如下图所示7. AOF文件的缺点AOF 文件它会把所有的操作命令全部都记录下来就算你对同一个数据进行多次修改操作但是AOF文件仍然还是会把所有之前的操作命令全部都记录下来所以AOF文件的大小通常都会比RDB文件要大。但是我们可以通过 bgrewriteaof 命令让 AOF 文件执行重写功能用最少的命令达到相同的效果。举例我在对 Redis 进行了三次操作set name zhangsanset age 18set 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 的值为yesyes表示开启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 开启