说明
文章内容通过学习小林Coding内的优质文章后整理而来,整理成思维导图的方式是为了帮助自己理解、记忆和复习。如若侵权请联系删除,再次对小林Coding内的优质文章表示感谢。参考文章如下:
- AOF 持久化是怎么实现的?
- RDB 快照是怎么实现的?
- Redis 大 Key 对持久化有什么影响?
思维导图会不断修改完善,下方的文字内容不一定会跟着修改,请大家以思维导图的内容为准。
文章目录
- 说明
- Redis持久化
- AOF日志
- 是什么
- 怎么开启
- 执行流程
- 优点
- 风险
- 三种写回策略
- Always
- Everysec
- No
- 重写机制
- 重写是什么
- 为什么要重写
- 重写过程
- 为什么用新AOF文件
- 为什么用子进程
- 父子进程怎么共享内存数据
- 写时复制是啥
- 什么时候会阻塞主进程
- 主进程修改数据,父子进程数据不一致怎么解决
- 优缺点
- RDB快照
- 是什么
- 相较于AOF的优缺点
- 怎么用
- 快照执行过程
- 混合持久化
- 是什么
- 怎么开启
- 执行过程
- 优点
Redis持久化
AOF日志
是什么
- Redis 每执行一条写操作命令(读操作没必要记录),就把该命令以追加的方式写入到一个AOF文件里
- 重启 Redis 的时候,先去读取这个文件里的命令并执行,数据就恢复了
怎么开启
- 修改redis.conf
# 是否需要持久化存储
appendonly yes
# 产生的AOF文件名称
appendfilename "appendonly.aof"
# 使用什么策略
appendfsync everysec
执行流程
Redis先执行写操作命令,再记录到AOF日志(在主进程完成)
优点
-
避免额外检查开销:如果先写到AOF,需要检查命令是否正确
-
不阻塞当前写操作命令执行
风险
- 日志没有写到磁盘,服务器宕机,数据会丢失
- 可能阻塞下一个命令
三种写回策略
Always
每次写操作都将日志写回硬盘
- 优点:最大程度保证数据不丢失
- 缺点:影响主进程性能
Everysec
每次写操作先将命令写入AOF文件内核缓冲区,每隔一秒将缓冲区内存写回硬盘
- Always和No的折中方案,平衡性能和数据丢失量
No
Redis不控制,交由操作系统控制写回时机。先将命令写入AOF文件内核缓冲区,操作系统决定何时将日志写回硬盘
- 优点:性能较好
- 缺点:操作系统将日志写回硬盘时机不可预知,服务器宕机丢失的数据可能比较多
重写机制
重写是什么
- 对于一个键,只保留最新的命令,减少AOF文件的数据量
- 如先执行set num 1,再执行set num 2,最后只需要保留set num 2,历史命令没用
为什么要重写
随着项目运行,AOF文件越来越大,重启Redis后的恢复速度会下降
重写过程
创建一个子进程来将最新命令先存储到一个新AOF文件,再覆盖旧AOF文件
为什么用新AOF文件
- 避免AOF重写失败造成原AOF文件数据被污染
- 使用新AOF文件,重写失败,直接删除新文件即可
为什么用子进程
-
重写较慢,避免阻塞主进程
-
为什么不用线程
- 多线程会共享内存,修改共享内存数据时,需要加锁保证数据安全,性能较差
- 父子进程以只读方式共享内存数据,如果父子一方要修改共享内存数据,会发生写时复制产生独立数据副本,无需加锁,性能较好
父子进程怎么共享内存数据
创建子进程时,操作系统会将主进程的页表复制给子进程,页表的虚拟地址会指向真实物理地址。父子进程都可以通过页表找到物理内存
写时复制是啥
-
当父进程发生写操作时,操作系统会将相应键的物理内存复制一份出来(会阻塞主进程),这样修改的时候不会影响原有物理内存
-
为什么不在创建子进程的时候将所有物理内存复制一份给子进程,而是复制页表
- 复制物理内存的话,时间长,主进程会长时间堵塞
- 页表内存较小,复制快
什么时候会阻塞主进程
- 复制页表
- 写时复制,bigkey影响较大
主进程修改数据,父子进程数据不一致怎么解决
- 除了AOF缓冲区,Redis还设置了AOF重写缓冲区,重写期间,会将命令追加到AOF重写缓冲区
- 重写完成后,将AOF重写缓冲区的命令追加到AOF文件
优缺点
-
优点:丢失数据可控
-
缺点:AOF日志文件大时,数据恢复慢
RDB快照
是什么
- RDB 快照就是记录某一瞬间的内存二进制数据,AOF 文件记录的是命令
- 每次执行快照,将所有内存数据记录到硬盘,效率较低,因此使用子进程来执行
相较于AOF的优缺点
-
优:直接将RDB文件读入内存即可,数据恢复效率高,无需执行命令
-
缺:快照频率不好把控。频率高,频繁创建子进程和磁盘IO,性能差;频率低,服务器宕机,丢失数据比AOF多
怎么用
修改redis.conf
save 900 1
save 300 10
save 60 10000
- 满足三个条件的任意一个就会执行快照
- save 900 1表示900秒内,执行至少1次数据修改
快照执行过程
- 执行bgsave时,创建一个子进程来生成RDB文件,父子共享内存数据时,原理同AOF
- 主进程修改共享内存数据的话,触发写时复制,生成RDB还是用旧的数据,因此此次更新的数据需要下次bgsave来生成快照
混合持久化
是什么
AOF、RDB合体。使用混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据
怎么开启
修改redis.conf
aof-use-rdb-preamble yes
执行过程
在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件,然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件
优点
-
效率高:因为前半部分是RDB内容
-
丢失数据少:操作命令会被记录到AOF日志