shi*_*eng 5 python java performance caching elasticsearch
Elasticsearch网站上的最新博客文章正在讨论其新的1.4 beta版本的功能。
我对它们如何利用文件系统缓存非常好奇:
最新版本增加了对文档值的支持。本质上,doc值提供与内存中字段数据相同的功能,但是它们在索引时间写入磁盘。他们提供的好处是他们只占用很少的堆空间。从磁盘而不是从内存读取Doc值。虽然磁盘访问速度很慢,但是doc值受益于内核的文件系统缓存。与JVM堆不同,文件系统缓存不受32GB限制的约束。通过将字段数据从堆转移到文件系统缓存,可以使用较小的堆,这意味着可以更快地进行垃圾回收,从而获得更稳定的节点。
在此版本之前,doc值比内存中的现场数据要慢得多。此版本中的更改显着提高了性能,使其几乎与内存中的字段数据一样快。
这是否意味着我们可以操纵文件系统缓存的行为,而不是被动地等待来自操作系统的影响?如果是这样,我们如何在正常的应用程序开发中利用文件系统缓存?说,如果我正在编写Python或Java程序,该怎么做?
文件系统缓存是与操作系统内部工作相关的实现细节,对最终用户是透明的。这不是需要调整或改变的东西。Lucene 在管理索引段时已经使用了文件系统缓存。每次将某些内容(通过 Elasticsearch)索引到 Lucene 时,这些文档都会写入段,这些段首先写入文件系统缓存,然后在一段时间后(当 translog - 一种跟踪被索引的文档的方式 - 是full 例如)缓存的内容被写入实际文件。但是,虽然要索引的文档在文件系统缓存中,但它们仍然可以被访问。
doc values 实现的这种改进指的是这个特性现在能够使用文件系统缓存,因为它们从磁盘读取,放入缓存并从那里访问,而不是占用堆空间。
这篇优秀的博客文章描述了如何访问文件系统缓存:
在我们之前的方法中,我们依赖于使用系统调用在文件系统缓存和本地 Java 堆之间复制数据。直接访问文件系统缓存怎么样?这就是 mmap 所做的!
基本上 mmap 的作用与将 Lucene 索引作为交换文件处理一样。mmap() 系统调用告诉 O/S 内核将我们的整个索引文件虚拟映射到前面描述的虚拟地址空间,并使它们看起来像我们的 Lucene 进程可用的 RAM。然后我们可以访问磁盘上的索引文件,就像它是一个大的 byte[] 数组一样(在 Java 中,这是由 ByteBuffer 接口封装的,以使其可供 Java 代码安全使用)。如果我们从 Lucene 代码访问这个虚拟地址空间,我们就不需要进行任何系统调用,处理器的 MMU 和 TLB 会为我们处理所有映射。如果数据仅在磁盘上,MMU 将引起中断,O/S 内核会将数据加载到文件系统缓存中。如果它已经在缓存中,MMU/TLB 将它直接映射到文件系统缓存中的物理内存。
与在Java程序中使用mmap的实际手段有关,我认为这是这样做的类和方法。