目录
编辑一、单节点 Redis 的问题
二、Redis 持久化
1、RDB 持久化
2、RDB 原理
3、RDB 总结
4、AOF 持久化
5、AOF 配置
6、AOF 文件重写
7、RDB 和 AOF 的对比
数据丢失问题:Redis 是内存储存,服务重启可能会丢失数据
并发能力问题:Redis 的并发能力虽然不错,但是无法满足部分高并发的场景 (如 618)
故障恢复问题:如果 Redis 宕机,则服务就不可用了,所以我们得保证整个 Redis 集群是持续可用的
存储能力问题:Redis 基于内存,单节点能存储的数据量有限
RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。
简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。
快照文件称为RDB文件,默认是保存在当前运行目录。
RDB 是把内存中的数据都记录到磁盘中,而磁盘的 IO 是比较大的,一旦整个数据量比较大,耗时就会比较久,那么等待执行完成,才会返回 ok ,主进程才会去执行其它的请求
因此并不推荐使用 RDB ,这个方式比较适合用于整个进程即将停止的时候使用 save ,而更加推荐使用 bgsave
这个保存的命令是在后台异步执行,因为它是由一个额外的进程(子进程)来执行 RDB 的,主进程不会受到影响
所以这个方式比较适合于在 Redis 运行的过程中使用
Redis 内部有触发 RDB 的机制,可以在 redis.conf 文件中找到:
同样的,RDB 的其它配置也可以在 redis.conf 文件中设置
我们知道:当满足一定的条件时,就会触发 bgsave ,完成异步的持久化,异步持久化就是开启一个子进程,由这个子进程去完成对内存数据的读取和写入 RDB
因为是异步的,所以可以做到对主进程几乎零阻塞
为什么说是几乎零阻塞呢?
因为子进程是通过 fork 主进程得到的,这个 fork 的过程是阻塞的,此时主进程只能干这一件事
物理内存可以理解成计算机里面的内存条
主进程要实现对内存中数据的读写,肯定是要在内存中进行操作的,但是在 Linx 系统中,所有的进程都没有办法直接操作物理内存,而是由操作系统给每个内存分配一个虚拟内存
那么主进程只能操作虚拟内存,而后操作系统会维护一个虚拟内存与物理内存之间的映射关系表(页表),从而实现对物理内存数据的读写
而我们执行 fork 的时候,会去创建一个子进程
fork 也就是把页表(映射关系)给拷贝给子进程,当子进程有了和主进程相同的映射关系之后,当子进程在操作自己的虚拟内存时,因为映射关系与主进程一样,所以最终一定可以映射到相同的物理内存区域,这样也就实现了子进程与主进程之间内存空间的共享
此时就无需拷贝内存数据,直接实现了内存共享,这个速度就会变得非常的快,阻塞的时间也就尽可能的缩短了
而后再将数据写到磁盘当中形成新的 RDB 文件,替换掉旧的 RDB 文件
那么子进程在写 RDB 的过程当中,主进程可不可以接受用户的请求,来去修改内存中的数据呢?
可以的,但是如果这个时候,主进程在修改数据,而子进程同时在读数据,读与写之间就会存在冲突
为了避免这个问题的发生,fork 底层会采用 copy-on-write 技术:
当主进程执行读操作的时候,访问共享技术
当主进程执行写操作的时候,则会拷贝一份数据,进行写操作
为了预防一些极端情况的发生,Redis 一般情况下都会预留一些空间,来防止内存溢出的情况发生
RDB 方式 bgsave 的基本流程?
fork 主进程得到一个子进程,共享内存空间
子进程读取内存数据并写入新的 RDB 文件
用新的 RDB 文件替换掉旧的 RDB 文件
RDB 会在什么时候执行? save 60 1000 代表什么含义?
save:默认是服务停止时执行
bgsave:要看停止的条件
代表 60 秒内至少执行你提供 1000 次修改则触发 RDB
RDB 的缺点:
RDB执行间隔时间长,两次RDB之间写入数据有丢失的风险
fork子进程、压缩、写出RDB文件都比较耗时
AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。
比如: 我现在执行一个 set num 123 时,会先把 set num 123 记录到 redis 的 key-value 结构里,而后还会把命令写到 AOF 的文件当中
如果将来 redis 出现了故障,我要恢复,那么就可以直接读取 AOF 文件,把里面的命令从头开始执行一遍,此时里面的数据就可以恢复到原始状态了
AOF 默认是关闭的,需要修改 redis.conf 配置文件来开启 AOF
AOF 的命令记录的频率也可以通过 redis.conf 文件来配置
上述三种命令记录策略的对比:
AOF 因为是记录命令,AOF文件会比RDB文件大的多。
而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。
通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。
Redis 也会在触发阈值时自动去重写 AOF 文件,阈值也可以在 redis.conf 中配置
RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。