Copy-on-Write机制: 父子进程共享内存页 当父进程修改数据时,内核会复制被修改的页 这可能导致内存使用量暂时增加 通俗的话描述一下
可以用一个生活中的例子来通俗解释 Copy-on-Write(写时复制) 机制:
📖 比喻:父子共用一本作业本
假设有一对父子(父进程和子进程)要完成以下任务:
初始状态:父亲有一本写满数据的作业本(Redis内存数据),现在孩子需要做一份完全相同的作业(RDB持久化)。
传统方式(非COW):
✖️ 父亲直接复印整本作业给孩子 → 浪费纸张(内存),而且复印过程很耗时。Copy-on-Write方式(Redis实际采用):
✅ 第一步:父亲直接把作业本借给孩子看,两人暂时共用同一本作业(父子进程共享内存页)。
✅ 第二步:如果父亲要修改作业的某一页(父进程修改数据):✏️ 内核会单独复制这一页给孩子(复制被修改的内存页)
📝 父亲在新复制的页上修改,不影响孩子读原内容
📚 其他未修改的页继续保持共享
💡 关键点:
省资源:一开始不复制全部数据,只有真正修改时才复制局部(节省内存)。
副作用:如果父亲频繁修改作业(Redis写入量大),会导致复制的页越来越多,内存占用暂时上升(这就是BGSAVE期间可能出现的"内存翻倍"现象)。
短暂阻塞:刚开始"借作业本"时(fork子进程),父亲需要整理作业本目录(内核准备进程数据结构),这时会短暂暂停(所有请求被阻塞)。
🌰 Redis中的实际表现:
执行
BGSAVE
时,如果Redis内存有10GB:理想情况:无写入操作 → 内存几乎不增加(共享所有页)
最坏情况:写入全部数据 → 内存临时增加10GB(所有页被复制)
通常情况:增加约1-2GB(只有部分页被修改和复制)
⚠️ 这就是为什么大内存Redis实例执行BGSAVE时,需要预留额外内存空间。