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