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

2024-03-31

A 最近关于 Elasticsearch 的博客文章 http://www.elasticsearch.org/blog/elasticsearch-1-4-0-beta-released/网站正在谈论他们新的 1.4 beta 版本的功能。

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

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

在此版本之前,文档值明显慢于内存中的字段数据。此版本中的更改显着提高了性能,使其几乎与内存中的字段数据一样快。

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


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

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

如何访问此文件系统缓存的描述见这篇优秀的博文 http://blog.thetaphi.de/2012/07/use-lucenes-mmapdirectory-on-64bit.html:

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

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

我认为与Java程序中使用mmap的实际手段相关这是执行此操作的类和方法 http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#map%28java.nio.channels.FileChannel.MapMode,%20long,%20long%29.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐