redis之BGSAVE堵塞redis原因(fork)

  • Fork是造成BGSAVE堵塞Redis的主要原因:

https://redis.io/topics/latency#latency-generated-by-fork

redis之BGSAVE堵塞redis原因(fork)_第1张图片
屏幕快照 2018-07-16 上午11.31.26.png
  • Fork的机制:

Fork会拷贝父进程的所有状态,包括已分配的内存:

“ … the operating system will create a new process that is exactly the same as the parent process. This means all the state that was talked about previously is copied, including open files, register state and all memory allocations,which includes the program code.

The return value from the system call is the only way the process can determine if it was the existing process or a new one. The return value to the parent process will be the Process ID (PID) of the child, whilst the child will get a return value of 0."
(https://www.bottomupcs.com/fork_and_exec.xhtml)

但是Linux的Fork可以设置copy-on-write

“ … copy on write. This means that similar to threads above, the memory is actually shared, rather than copied, between the two processes when fork is called. If the processes are only going to be reading the memory, then actually copying the data is unnecessary.

However, when a process writes to its memory, it needs to be a private copy that is not shared. As the name suggests, copy on write optimises this by only doing the actual copy of the memory at the point when it is written to. "
(https://www.bottomupcs.com/fork_and_exec.xhtml)

此时子进程只需要拷贝父进程的page table,然后把内存设置为只读。当父进程或子进程需要修改共享的内存时,需要copy出私有的page,在新的page上修改。这也是为什么Redis建议把Linux的Transparent Huge Pages(THP)关闭。在THP下,一个page会保存更多的key,因此父进程在处理写操作时可能会做更多的内存copy。

  • 可以通过Redis的日志查看做RDB的过程中,有多少copy-on-write内存(Dirty Pages):

[13351] 09 Jul 14:39:20.564 * Background saving started by pid 44595
[44595] 09 Jul 14:41:41.933 * DB saved on disk
[44595] 09 Jul 14:41:42.179 * RDB: 134 MB of memory used by copy-on-write (这一行显示Redis在做RDB的过程中,主进程copy了多少内存)
[13351] 09 Jul 14:41:42.679 * Background saving terminated with success

这个值也表示Redis在做RDB的过程中所用到的额外的内存。

你可能感兴趣的