在 Redis 的字典实现中,安全/非安全字典迭代器有什么区别?



我刚刚阅读了dict实现的'dict.c'源代码文件。我已经了解了安全/非安全dict迭代器之间的字面区别,但还不明白为什么要引入非安全迭代器的新概念。

谷歌表示,"新的迭代器可能会执行更少无用的COW"但我不知道它是如何工作的,所以请向这里寻求帮助。

感谢您的帮助,举例说明会更好。

安全/非安全迭代器的目的是明确确定迭代发生在可变还是不可变的数据结构上。在dict实现中,当安全迭代正在进行时,它可以防止对字典执行某些操作(例如重新哈希)。

现在安全迭代器有一个缺点:它们需要在迭代对象本身中增加一个引用计数器,这样对象就知道是否发生了安全迭代。

Redis利用操作系统写时拷贝(COW)机制来处理后台转储。当发生转储时,会调用fork来克隆Redis实例并创建第二个进程。这个过程将对整个数据进行迭代,将所有内容序列化到转储文件中。由于COW机制,大多数页面都是在两个进程之间共享的,因此Redis在转储数据时不会占用两倍的RAM。

现在,只有在只读模式下访问页面时,才能共享这些页面。当两个进程中的一个在内存中写入内容时,操作系统会自动复制相应的页面。

如果系统地使用安全迭代器对所有字典进行迭代,则会有大量页面重复(因为引用计数器更新)。在克隆过程中,数据被认为是不可变的,因此使用不安全的迭代器可以减少COW活动。当Redis中有很多set/hash/zset对象时,这一点最为重要。

最新更新