如何在Java或Python中使用文件系统缓存?

时间:2014-10-29 03:46:21

标签: java python performance caching elasticsearch

recent blog post on Elasticsearch网站正在讨论新版1.4测试版的功能。

我很好奇他们如何使用文件系统缓存:

  

最新版本增加了对doc值的支持。实质上,doc值提供与内存中fielddata相同的功能,但它们在索引时写入磁盘。它们提供的好处是它们占用的堆空间非常小。 Doc值是从磁盘读取的,而不是从内存中读取的。虽然磁盘访问速度很慢,但doc值会受益于内核的文件系统缓存。与JVM堆不同,文件系统缓存不受32GB限制的约束。通过将fielddata从堆转移到文件系统缓存,您可以使用更小的堆,这意味着更快的垃圾收集,从而更稳定的节点。

     

在此版本发布之前,doc值明显慢于内存中的fielddata。 此版本中的更改大大提高了性能,使其几乎与内存中的fielddata一样快。

这是否意味着我们可以操纵文件系统缓存的行为而不是被动地等待操作系统的影响?如果是这种情况,我们如何在正常的应用程序开发中使用文件系统缓存?比方说,如果我正在编写Python或Java程序,我该怎么做?

1 个答案:

答案 0 :(得分:2)

文件系统缓存是与OS内部工作相关的实现细节,对最终用户是透明的。它不是需要调整或改变的东西。 Lucene在管理索引段时已经使用了文件系统缓存。每次将某些内容索引到Lucene(通过Elasticsearch)时,这些文档都会写入段,这些段首先写入文件系统缓存,然后在一段时间后(当translog - 一种跟踪文档被索引的方式 - 是例如,完整的缓存内容被写入实际文件。但是,虽然要编制索引的文档位于文件系统缓存中,但仍可以访问它们。

doc值实现的这种改进将此功能称为能够立即使用文件系统缓存,因为它们从磁盘读取,放入缓存并从那里访问,而不是占用堆空间。

this excellent blog post

中描述了如何访问此文件系统缓存
  

在我们之前的方法中,我们依赖于使用系统调用来复制文件系统缓存和本地Java堆之间的数据。如何直接访问文件系统缓存?这就是mmap的作用!

     

基本上mmap与将Lucene索引作为交换文件一样处理。 mmap()系统调用告诉O / S内核将我们的整个索引文件虚拟映射到前面描述的虚拟地址空间,并使它们看起来像我们的Lucene进程可用的RAM。然后我们可以在磁盘上访问我们的索引文件,就像它是一个大的byte []数组一样(在Java中,这是由ByteBuffer接口封装的,以使Java代码可以安全使用)。如果我们从Lucene代码访问这个虚拟地址空间,我们不需要做任何系统调用,处理器的MMU和TLB为我们处理所有映射。如果数据仅在磁盘上,则MMU将导致中断,O / S内核将数据加载到文件系统缓存中。如果它已经在缓存中,MMU / TLB将其直接映射到文件系统缓存中的物理内存。

与在Java程序中使用mmap的实际方法相关,我认为是this is the class and method to do so