Redis 执行 RDB 快照期间,主进程可以正常处理命令吗?

执行了 save 命令,会在主进程生成 RDB 文件,由于和执行操作命令在同一个线程,所以如果写入 RDB 文件的时间太长,会阻塞主进程。

执行 bgsave 过程中,由于是交给子进程来构建 RDB 文件,主进程还是可以继续工作的,此时主进程依然可以继续处理操作命令,也就是数据是能被修改的,关键的技术就在于写时复制技术。

执行 bgsave 命令的时候,主进程会通过 fork() 创建子进程,此时子进程和父进程是共享同一片内存数据的,因为在创建子进程的时候,会复制父进程的页表,且页表指向的物理内存是同一个,此时如果主进程执行读操作,则主进程和 bgsave 子进程互不影响。

如果主进程执行写操作,则被修改的数据会复制一份副本,然后 bgsave 子进程会把它的副本数据写入 RDB 文件,在这个过程中,主进程仍然可以直接修改原来的数据。

注意,只有在发生修改内存数据的情况时,物理内存才会被复制一份。

举例来说,如果主进程要修改共享数据里的某一块数据(比如键值对 A)时,就会发生写时复制。于是这块数据的物理内存就会被复制一份(键值对 A')。然后主进程在这个数据副本(键值对 A')上进行修改操作。与此同时,bgsave 子进程可以继续把原来的数据(键值对 A)写入到 RDB 文件。

注意,在发生了写时复制后,RDB 快照保存的是原本的内存数据,而主进程刚修改的数据是没办法在这一时间写入 RDB 文件的,只能交由下一次的 bgsave 快照。

所以 Redis 在使用 bgsave 快照过程中,如果主进程修改了内存数据,不管是否是共享的内存数据,RDB 快照都无法写入主进程刚修改的数据,因为此时主进程的内存数据和子进程的内存数据已经分离了,子进程写入到 RDB 文件的内存数据只能是原本的内存数据(快照的定义)。

如果系统恰好在 RDB 快照文件创建完毕后崩溃了,那么 Redis 将会丢失主进程在快照期间修改的数据。

相关推荐
A_cot4 小时前
Redis 的三个并发问题及解决方案(面试题)
java·开发语言·数据库·redis·mybatis
芊言芊语5 小时前
分布式缓存服务Redis版解析与配置方式
redis·分布式·缓存
攻城狮的梦6 小时前
redis集群模式连接
数据库·redis·缓存
Amagi.9 小时前
Redis的内存淘汰策略
数据库·redis·mybatis
无休居士10 小时前
【实践】应用访问Redis突然超时怎么处理?
数据库·redis·缓存
.Net Core 爱好者10 小时前
Redis实践之缓存:设置缓存过期策略
java·redis·缓存·c#·.net
码爸13 小时前
flink 批量压缩redis集群 sink
大数据·redis·flink
微刻时光14 小时前
Redis集群知识及实战
数据库·redis·笔记·学习·程序人生·缓存
丁总学Java15 小时前
如何使用 maxwell 同步到 redis?
数据库·redis·缓存
蘑菇蘑菇不会开花~15 小时前
分布式Redis(14)哈希槽
redis·分布式·哈希算法