一条背景:我是Redis 的开发者,一个 NoSQL 数据库。我正在实现的新功能之一是虚拟内存,因为 Redis 将所有数据都存储在内存中。多亏了 VM Redis 能够将很少使用的对象从内存传输到磁盘,这比让操作系统为我们交换工作要好得多的原因有很多(redis 对象是由许多不连续分配的小对象构建的位置,当通过 Redis 序列化到磁盘时,它们占用的空间比它们所在的内存页面少 10 倍,依此类推)。
现在我有一个在 Linux 上完美运行的 alpha 实现,但在 Mac OS X Snow Leopard 上运行得不是很好。有时,当 Redis 尝试将页面从内存移动到磁盘时,redis 进程会进入几分钟的不间断等待状态。我无法对此进行调试,但这发生在对fseeko()
或的调用中fwrite()
。几分钟后,调用终于返回,redis 继续毫无问题地工作:没有崩溃。
传输的数据量非常小,大约 256 字节。因此,这不应该是执行大量 I/O 的问题。
但是关于作为写操作目标的交换文件有一个有趣的细节。这是一个大文件(26 GB),fopen()
使用ftruncate()
. 最后,文件被unlink()
编辑,以便 Redis 继续引用它,但我们确信当 Redis 进程退出时,操作系统将真正释放交换文件。
好的,这就是全部,但我在这里了解更多细节。顺便说一句,您甚至可以在 Redis git 中找到实际代码,但鉴于这是一个相当复杂的系统,在五分钟内理解它并非易事。
非常感谢您的帮助。