如何实现Lucene的doc_values?

时间:2014-12-30 05:31:36

标签: solr elasticsearch lucene mmap page-caching

我看到了#34; doc_values"的ES文档。 http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/doc-values.html

" Doc值是在索引时建立的,而不是在搜索时间",那么如果使用doc_values将会构建什么?

" doc值是预先构建的,并且更快地初始化",为什么它更快?

"但没有堆内存使用情况",那么使用页面缓存?

有人可以向我解释doc_values是如何实现的,我应该在什么时候使用?我会定期检查jstat的堆使用情况,我可以看到我还有足够的空间可供使用。

2 个答案:

答案 0 :(得分:4)

  

" Doc值是在索引时建立的,而不是在搜索时间",那么如果使用doc_values将会构建什么?

有两种类型的工作负载,我们需要在数据之上使用柱状视图:排序和聚合。在当前版本的Elasticsearch中有两种情况:

  1. 该字段仅被编入索引。在这种情况下,如果您开始在给定字段上进行排序/聚合,则数据将被延迟取消,并在搜索时放入缓存中,以便您可以访问给定文档ID的值。这意味着反向索引,如
  2. foo -> 0, 1 bar -> 1

    将转换为以下数据结构

    0 -> foo 1 -> foo, bar

    1. 该字段已启用doc值。在这种情况下,数据将在索引时以列式格式存储。在搜索时您需要做的一切就是加载一些关于您的字段及其编码方式的微小元数据。然后,数据将直接从磁盘读取(依靠文件系统缓存来提高性能)。
    2.   

      " doc值是预先构建的,并且更快地初始化",为什么它更快?

      我提到的这种反转过程实际上非常CPU和I / O密集型。结果放在缓存中,但第一次访问仍然很慢,这将损害大型合并后立即运行的所有查询的延迟。您可以通过急切加载fielddata来修复此问题,但即使它会使响应时间更好,它也会将问题转移到其他位置,因为elasticsearch将等待在新点之前加载字段数据,因此对索引的更改将需要更长时间才能显示索引的即时视图可供搜索。

      另一方面,使用doc值,您只需要从磁盘中读取一些微小的元数据即可。

        

      "但没有堆内存使用情况",那么使用页面缓存?

      完全! Doc值需要非常少的堆内存,主要是关于字段字段的元数据以及如何在磁盘上编码内容。其余部分直接从磁盘读取,并依赖于文件系统缓存来提高性能。

        

      有人可以向我解释doc_values是如何实现的,我应该在什么时候使用?我会定期检查jstat的堆使用情况,我可以看到我还有足够的空间可供使用。

      这有点复杂,因为有不同的情况......例如:

      • 取决于字段的类型(数字与字符串)
      • 该字段是单值还是多值
      • 该字段的基数
      • 数据的某些模式...例如,我们在编码数字字段时检查公约数,以便在所有值共享公约数时具有更高效的压缩。如果您使用秒或日精度编码时间戳,通常会发生这种情况,因为所有值都是1000的倍数。

      但在实践中,重要的是要知道它基本上是一个非常大的mmap文件,它是按顺序读取的,所以即使是基于磁盘的,它仍然对你的友好I / O系统。

      如果这是您感兴趣的内容,you can read more about it

      关于何时应使用doc值,我认为您应该在计划排序或聚合的所有字段上启用doc值。默认情况下,在下一个弹性搜索主要版本中,有关于启用文档值的持续discussion

答案 1 :(得分:1)

Simon Willnauer在2011年Lucene Revolution上发表了关于DocValues的演讲,请关注Doc his presentation for a 40 minute long introduction关于DocValues是什么以及为什么它们整洁。

Doc Values是现代搜索平台除搜索之外所做的所有“其他事情”的优化,例如分面,突出显示等。

Solr社区Wiki还有一个description of DocValues以及它们的用途:

  

对于我们现在通常与搜索相关联的其他功能,例如排序,分面和突出显示,此方法效率不高。例如,分面引擎必须查找每个文档中出现的每个术语,这些术语将构成结果集并提取文档ID以构建构面列表。在Solr中,这是在内存中维护的,并且加载速度很慢(取决于文档的数量,术语等)。   在Lucene 4.0中,引入了一种新方法。 DocValue字段现在是面向列的字段,在索引时构建了文档到值的映射。这种方法有望减轻fieldCache的一些内存需求,并且可以更快地查找分面,排序和分组。

它们的实现在org.apache.lucene.index.DocValues以及支持使用DocValues的每种字段类型中都可用(每种字段类型都必须明确使用DocValues)。