一条背景:我是 redis,一个NOSQL数据库. 。我正在实现的新功能之一是虚拟内存,因为Redis将所有数据都在内存中获取。多亏了VM Redis能够将很少使用的对象从内存传输到磁盘,这与让OS为我们交换的工作要好得多。当Redis序列化到磁盘时,与他们居住的记忆页相比,它们的空间少10倍,等等。

现在,我有一个在Linux上完美运行的Alpha实现,但在Mac OS X Snow Leopard上不太好。当Redis试图将页面从内存转移到磁盘时,REDIS进程将进入不间断的等待状态几分钟。我无法调试此事,但这要么发生在 fseeko() 或者 fwrite(). 。几分钟后,电话终于返回,Redis继续工作没有问题:没有崩溃。

传输的数据量为 非常 小,大约256个字节。因此,这不应该是大量I/O进行的问题。

但是,关于写操作的目标交换文件有一个有趣的细节。这是一个大文件(26 GB)创建的 fopen() 然后使用 ftruncate(). 。最后,文件是 unlink()ED使Redis继续参考它,但是我们确信,当Redis流程退出时,操作系统将真正释放交换文件。

好的,这就是我的所有细节。顺便说一句,您甚至可以在redis git中找到实际代码,但是鉴于这是一个相当复杂的系统,在五分钟内了解到并不是一件容易的事。

非常感谢您的任何帮助。

有帮助吗?

解决方案

据我了解,HFS+对稀疏文件的支持很差。因此,可能是您的写入触发了一个文件扩展,该文件扩展正在初始化/实现文件的很大一部分。

例如,我知道mmap'ing一个新的大型空文件,然后在几个随机位置写作会在带有HFS+的磁盘上产生一个非常大的文件。这很烦人,因为MMAP和稀疏文件是使用数据的一种非常方便的方式,几乎所有其他平台/文件系统都可以优雅地处理此操作。

交换文件是否线性写入?这意味着我们要么替换现有块,要么在末端编写新块,然后增加免费空间指针?如果是这样,也许进行更频繁的较小的fruncate调用来扩展文件将导致停顿较短。

顺便说一句,我很好奇为什么Redis VM不使用MMAP,然后将块移动以尝试将热块集中到热页面中。

其他提示

安蒂雷斯,我不确定我会有很多帮助,因为我的苹果经验仅限于 Apple ][, ,但我会试一试。

第一件事是一个问题。我本以为,对于虚拟内存,操作速度将比磁盘空间更重要(尤其是对于NOSQL DB,速度是整个点,否则您将使用SQL,不?)。但是,如果您的交换文件为26克,也许不是:-)

有些事情要尝试(如果可能的话)。

  1. 尝试将问题实际隔离到寻求或写作。我很难相信寻求可能需要很长时间,最糟糕的是,这应该是缓冲指针的变化。不过,我没有写OSX,所以我不确定。
  2. 尝试调整交换文件的大小,以查看是否导致问题。
  3. 您是否曾经动态扩展交换文件(而不是预分配)?如果您这样做,那可能是引起问题的原因。
  4. 您是否总是在文件中尽可能低?可能是创建一个26G文件可能实际上无法用数据填充它,但是,如果创建它,然后将其写入最后一个字节,则OS可能必须在此之前将字节归零(如果有的话,请推迟初始化)。
  5. 如果您只是预先分配整个文件(写入每个字节)而不是UNINK,会发生什么?换句话说,将文件放在程序之间的运行之间(如果尚不存在,则创建它)。然后在您的redis启动代码中,只需初始化文件(指针等)即可。这可能会摆脱上述第4点中的任何问题。
  6. 在各个BSD站点上也询问。我不确定封面下的苹果发生了多少变化,但是OSX只是最低级别的BSD(Pax Ducks for Cover)。
  7. 还请考虑在Apple网站上询问(如果您尚未这样做)。

好吧,这是我的小贡献,希望它会有所帮助。祝您项目好运。

您是否关闭了文件的文件缓存? ie fcntl(fd,f_global_nocache,1)

您是否尝试使用Dtrace和或Instruments(Apple的实验DTRACE前端)进行调试?

与Dtrace一起探索豹子

在OS X上调试Chrome

正如Linus在GIT邮件列表中所说的那样:

“我意识到OS X人们很难接受它,但是OS X文件系统通常是总和完全废话 - 甚至比Windows更重要。”

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top