分布式缓存-Redis 持久化

一、单点 Redis 的问题

  • 数据丢失问题。Redis 是内存存储,一旦服务宕机重启,数据就有可能会丢失。
  • 并发能力问题。单节点的 Redis 并发能力虽然不错,但也无法满足如 618、双 11 这样的高并发场景。
  • 故障恢复问题。如果 Redis 宕机,则服务不可用,需要一种自动的故障恢复手段。
  • 存储能力问题。Redis 是基于内存存储,但是内存存储是有上限的,而需要被缓存的数据会越来越多,那么单节点的 Redis 则难以满足海量数据的需求。

解决方案:在这里插入图片描述

二、RDB 持久化

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

2.1.执行时机

RDB持久化在四种情况下会执行:

  • 执行save命令
  • 执行bgsave命令
  • Redis停机时
  • 触发RDB条件时

1)save命令

要想让 Redis 执行 RDB,可以使用 redis-cli 命令连接 Redis 客户端,然后执行 save 命令:
在这里插入图片描述
save 命令是由 Redis 主进程来执行的,一旦主进程执行 RDB,就会阻塞所有命令。如果数据量比较大,那么执行 RDB 的时间就会比较久,若此时有其他命令,那么就需要等待 RDB 执行结束。这种方式一般不推荐使用,一般适用于在停止 Redis 服务前执行。

2)bgsave 命令

一般推荐使用 bgsave,该命令会开启一个子进程,由子进程执行 RDB,主进程则不受影响,可继续执行其他命令。比较适合于在 Redis 运行过程中使用。
在这里插入图片描述

3)Redis 停机时

一般 Redis 在停机时会自动执行一次 RDB。
在这里插入图片描述
Redis 重启后会自动加载 RDB 中保存的数据。

4)触发 RDB 条件时

Redis 内部有触发 RDB 的机制,可以在 redis.conf 文件中找到,格式如下:
在这里插入图片描述
RDB 的其他配置也可以在 redis.conf 文件中设置:
在这里插入图片描述
dir 默认为Redis启动时,命令行所在的目录下。

2.2 RDB 的 fork 原理

bgsave 开始时会 fork 主进程得到子进程,子进程共享主进程的内存数据。完成 fork 后读取内存数据并写入 RDB 文件。
Redis 主进程要在内存中实现对数据的读写。在 Linux 系统中,所有的进程都无法直接操作物理内存,而是操作系统给每个进程分配一个虚拟内存。Redis 中的主进程只能操作虚拟内存,操作系统会维护一个虚拟内存与物理内存之间的映射表,这个表被称之为页表。主进程操作虚拟内存,而虚拟内存基于页表的映射关系到物理内存,这样就可以实现对物理内存的读写。而在执行 fork 的时候,主进程会创建一个子进程,fork 的过程并不会将内存数据做拷贝,而仅仅只是将页表进行了拷贝,即将映射关系拷贝给了子进程。这样子进程就有了与主进程相同的映射关系,当子进程在操作自己的虚拟内存时,因为映射关系与主进程相同,最终就会映射到相同的物理内存,这样也就实现了子进程与主进程之间的内存空间共享,因而无需拷贝内存中的数据,而是直接实现内存共享,这样 fork 的速度就会变得非常快,阻塞的时间也就尽可能地缩短了。之后,子进程通过读取自己内存中的数据,再将这些数据写入到磁盘当中,去替换旧的 rdb 文件。
在这里插入图片描述
子进程在写 rdb 文件的过程中,主进程是可以接收用户的请求,修改内存中的数据,如果此时主进程在修改数据,而子进程同时在写数据,那么读与写之间就有可能产生冲突,产生脏数据。为了避免这种情况的发生,fork 的底层采用了一种 copy-on-write 的技术:

  • 当主进程执行读操作时,访问共享内存;
  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。

当主进程需要写数据的时候,fork 首先会将共享内存标记为 read-only,并将需要操作的数据拷贝一份出来,对其进行写操作。
在这里插入图片描述

具体原理分析可以看下这篇文章:十三、Redis持久化之RDB原理

2.3 总结

RDB 方式 bgsave 的基本流程?

  • fork 主进程得到一个子进程,共享内存空间
  • 子进程读取内存数据并写入新的 RDB 文件
  • 用新的 RDB 文件替换旧的 RDB 文件。

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

  • 默认服务停止时
  • 代表 60 秒内至少执行 1000 次修改则触发 RDB

RDB 的缺点?

  • RDB 执行间隔时间长,两次 RDB 之间写入数据有丢失的风险
  • fork 子进程、压缩、写出 RDB 文件都比较耗时

三、AOF 持久化

3.1 AOF 原理

AOF 全称为 Append Only File(追加文件)。Redis 处理的每一个命令都会记录在 AOF 文件中,可以看做是命令日志文件。
在这里插入图片描述

3.2 AOF 配置

AOF 默认是关闭的,需要修改 redis.conf 配置文件来开启 AOF:
在这里插入图片描述
AOF 的命令记录的频率也可以通过 redis.conf 文件来配:
在这里插入图片描述
三种配置对比:
在这里插入图片描述

3.3 AOF 文件重写

因为是记录命令,AOF 文件会比 RDB 文件大的多。而且 AOF 会记录对同一个 key 的多次写操作,但只有最后一次写操作才有意义。通过执行 bgrewriteaof 命令,可以让 AOF 文件执行重写功能,用最少的命令达到相同效果。
在这里插入图片描述
set num 命令执行了两次,但是由于执行了 berewriteaof 命令,只有最后一次的命令才有意义,那么就可以将 set num 123 抛弃不要,而只保留最后两条,而最后两条由于都是 set 命令,可以合并为 MSET 执行。
在这里插入图片描述
可以看出在执行bgrewriteaof命令后,aof 的重写动作是异步执行的。

Redis 也会在触发阈值时自动去重写 AOF 文件。阈值也可以在 redis.conf 中配置:
在这里插入图片描述

四、RDB 与 AOF 对比

RDB 和 AOF 各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。两者同时使用时,在 Redis 重启后,会以 AOF 优先来做恢复。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值