当 redis 调用 bgsave 命令进行持久化操作时,会创建子进程进行生成 rdb 临时文件,这时候如果有写请求进入父进程,是怎么操作的呢?求解答。
1
hecz OP up
|
2
Mirana 2018-03-22 23:19:09 +08:00
fork 和 copy on write 了解一下
|
3
fcten 2018-03-23 00:04:58 +08:00
copy on write。写入的数据会被复制,最坏的情况下 bgsave 会占用两倍的内存。在 master 上 做 bgsave 容易导致 oom,一般会选择在 slave 上做 bgsave
|
4
etc 2018-03-23 00:07:48 +08:00
@fcten 关于这个持久化的时候 fork 出来的子进程会不会占用多一倍的内存,我曾经去翻过官方文档,也没见到有提过这么回事。网上个人博客有些人说有,另外的人也是没提过。
|
7
wobutwo 2018-03-23 10:26:39 +08:00 1
@hecz bgsave 过程中写请求只在父进程进行,子进程不处理(只需把当时 fork 得到的数据存盘就好).
bgsave 时启动的 fork 进程的主要内存开销是拷贝页表、fd 列表等进程数据结构,只有父进程同时在处理写请求从而影响到某些内存页变动才对这些页进行拷贝增加内存占用. |
8
lolizeppelin 2018-03-23 13:56:03 +08:00 via Android
人家说理论最坏情况是 1 倍
理论最坏情况就是 fork 复制部分的内存都被修改过 那么复制或者说快照时间点的内存就会完全的多出来而不是一份映射 |
9
fcten 2018-03-23 14:45:51 +08:00 1
@etc
https://redis.io/topics/faq Redis background saving schema relies on the copy-on-write semantic of fork in modern operating systems: Redis forks (creates a child process) that is an exact copy of the parent. The child process dumps the DB on disk and finally exits. In theory the child should use as much memory as the parent being a copy, but actually thanks to the copy-on-write semantic implemented by most modern operating systems the parent and child process will share the common memory pages. A page will be duplicated only when it changes in the child or in the parent. Since in theory all the pages may change while the child process is saving, Linux can't tell in advance how much memory the child will take |