8

在开发使用压缩磁盘索引或磁盘文件的应用程序时,其中部分索引或文件被重复访问(为了论证,让我们说类似于 Zipfian 发行版),我想知道什么时候足够/更好地依赖操作系统级别的缓存(例如,Debian 系统上的内存映射),什么时候在应用程序层上实现某些东西更好(例如,像FileChannel缓冲或 Memcached 或 Java 代码中的自定义 LRU 缓存)。

例如,一篇文章(参考 Solr)主张为操作系统缓存留出可用内存:

操作系统的缓存非常有用,它显着减少了回答查询所需的时间(即使在完全重新启动服务器之后!),因此请始终记住为操作系统保留一些可用内存。

这让我想知道我的应用程序级缓存是否用 LRU Java 对象的弱映射填充内存是弊大于利,尤其是。由于Java在内存开销方面是如此贪婪......而不是使用该内存来缓存一些最终结果对象,操作系统会更好地使用该空间来缓存大量原始压缩数据吗?另一方面,应用层缓存对于平台独立性会更好,无论代码运行在什么操作系统上都允许缓存。

所以我意识到除了运行几个特定的​​基准测试之外,我不知道如何以有原则的方式回答这个问题。这让我问...

对于是否为应用程序级缓存分配可用内存,或者将该内存用于操作系统级缓存,存在哪些一般准则?

特别是,我希望能够更好地识别编写应用程序级缓存何时是浪费时间,甚至对性能有害。

4

1 回答 1

5

最终的答案总是先测量、分析,然后优化。在有和没有缓存的分析器下运行你的应用程序,看看有什么区别。直接观察是无可替代的。

话虽如此,有一种原则性的方法可以考虑您的问题。想想缓存可以为您做什么:

  • 用时间换记忆。所涉及的时间可能是 I/O 时间,也可能是 CPU 时间。
  • 用工作集记忆的峰值换取工作记忆的更小、更长期的增加。

因此,针对您的具体情况,您需要提出以下问题。

  • 如果没有缓存,您的应用程序 I/O 是否受限?如果您将 98% 的时间用于处理数据,而仅 2% 的时间用于查找数据,那么无论缓存效率如何,缓存都对您没有多大帮助。(在这种情况下,一个非常有效的缓存只会将您的性能提高大约 2%。)
  • 缓存命中避免了多少工作?如果缓存命中避免了一次fread()调用,那么缓存可能对您没有多大作用。但是,如果缓存命中避免随机遍历几个非常大的文件的几百个块,那么它可能会为您节省大量时间。它还可以在操作系统的磁盘缓存中为您节省大量空间,使该内存可用于其他操作系统操作。
  • 缓存命中率是多少?
  • 你需要多大的缓存才能获得良好的命中率(通常高于 75%)?如果答案是数百兆字节,那么您不妨让操作系统的磁盘缓存为您完成工作。

使您的应用程序的这些方面可配置(是否使用缓存,为缓存留出多少内存等)通常非常有帮助,并使用这些设置来查看最适合给定的设置设想。

如今,最有趣的发展之一是固态驱动器的可用性。这些驱动器的吞吐量不如更好的主轴快,但随机访问通常非常出色。这肯定会改变一些事情。

同样,没有什么可以替代分析您的代码。

于 2012-10-27T18:37:55.923 回答