Redis RDB如何持续实际在幕后工作?

时间:2017-10-06 06:39:47

标签: unix process redis

我正在经历Redis RDB持久性。我对RDB持久性有一些疑问,与其缺点有关。

了解到目前为止:

当我们需要定期保存当前在内存中的数据集的快照时,我们应该使用rdb持久性。

我可以理解,通过这种方式,我们可以在服务器发生故障时丢失一些数据。但是我无法理解的另一个缺点是,在使用rdb持久化大型数据集时,fork是多么耗时。

从文档引用

  

RDB经常需要fork()才能使用子进程持久存储在磁盘上   处理。如果数据集很大,Fork()可能会非常耗时   导致Redis停止服务客户端几毫秒或甚至   如果数据集非常大且CPU性能不高,则持续一秒钟   大。 AOF也需要fork(),但你可以调整你想要的频率   重写你的日志而不需要在耐用性方面做出任何折衷。

我知道fork如何根据我的知识工作当父进程分叉它创建一个新的Child进程时我们可以允许子进程基于其pid执行的一些代码,或者我们可以为它提供一些新的可执行文件使用exec()系统调用。

但是,当数据集的大小较大时,我不明白它将如何成为繁重的任务?

我想我知道答案,但我不确定

引用此链接https://www.bottomupcs.com/fork_and_exec.xhtml

当进程调用fork然后

  

操作系统将创建一个与父进程完全相同的新进程。这意味着复制了之前讨论过的所有状态,包括打开文件,寄存器状态和所有内存分配,其中包括程序代码。

根据上述说法,redis的整个数据集将被复制到子级。

我理解对吗?

1 个答案:

答案 0 :(得分:1)

当使用copy-on-write调用标准fork时,操作系统仍然必须复制所有页表条目,如果你有4k小页面和庞大的数据集,这可能需要时间,这就是实际fork()的原因时间慢。

如果您的数据集以稀疏方式进行大量更改,您还可以找到大量时间和内存,因为写入时复制语义会触发在对原始数据进行更改时要复制的实际内存页。 Redis还执行增量重组并保持到期等,因此更活跃的实例通常需要更长时间才能保存到磁盘。

更多阅读:

Faster forking of large processes on Linux?

http://kirkwylie.blogspot.co.uk/2008/11/linux-fork-performance-redux-large.html