16

我配置了一个 Solr 4.4.0 核心,其中包含大约 630k 个文档,原始大小约为 10 GB。每个字段都被复制到文本字段以进行查询和突出显示。当我在没有突出显示的情况下执行搜索时,结果会在大约100 毫秒内返回,但是当突出显示打开时,相同的查询需要10-11 秒。我还注意到,对相同术语的后续查询继续花费大约相同的 10-11 秒。

我对该字段的初始配置如下

<field name="text" type="text_general" indexed="true" stored="true"
   multiValued="true"
   omitNorms="true"
   termPositions="true"
   termVectors="true"
   termOffsets="true" />

发送的查询类似于以下内容

http://solrtest:8983/solr/Incidents/select?q=error+code&fl=id&wt=json&indent=true&hl=true&hl.useFastVectorHighlighter=true

我所有的研究似乎都没有提供关于为什么高光表现如此糟糕的线索。一时兴起,我决定看看omitNorms=true属性是否有效果,我修改了文本字段,清除了数据,然后从头开始重新加载。

<field name="text" type="text_general" indexed="true" stored="true"
   multiValued="true"
   termPositions="true"
   termVectors="true"
   termOffsets="true" />

奇怪的是,这似乎解决了问题。带有突出显示的初始查询耗时2-3 秒,随后的查询耗时不到100 毫秒

但是,因为我们希望omitNorms=true就位,所以我的永久解决方案是拥有两份“文本”字段,一份有属性,一份没有。这个想法是针对一个字段执行查询并突出显示另一个字段。所以现在模式看起来像

<field name="text" type="text_general" indexed="true" stored="true"
   multiValued="true"
   omitNorms="true"
   termPositions="true"
   termVectors="true"
   termOffsets="true" />

<field name="text2" type="text_general" indexed="true" stored="true"
   multiValued="true"
   termPositions="true"
   termVectors="true"
   termOffsets="true" />

查询如下

http://solrtest:8983/solr/Incidents/select?q=error+code&fl=id&wt=json&indent=true&hl=true&hl.fl=text2&hl.useFastVectorHighlighter=true

同样,数据被清除并使用相同的 630k 文档重新加载,但这次索引大小约为 17 GB。(正如预期的那样,因为“文本”字段上的内容是重复的。)

问题是性能数字回到了原来的每次运行 10-11 秒。要么第一次删除 omitNorms 是侥幸,要么发生了其他事情。我不知道什么...

使用 jVisualVM 捕获 CPU 样本展示了以下两种使用大部分 CPU 的方法

org.apache.lucene.search.vectorhighlight.FieldPhraseList.<init>()    8202 ms (72.6%)
org.eclipse.jetty.util.BlockingArrayQueue.poll()                     1902 ms (16.8%)

我见过 init 方法低至 54%,而 poll 数高达 30%。

有任何想法吗?我可以寻找其他任何地方来追踪瓶颈吗?

谢谢

更新

我用相同的数据集但不同的配置做了一堆测试,这就是我发现的……虽然我不明白我的发现。

  • 快速突出显示性能要求omitNorms 未设置为 true。(不知道 omitNorms 和突出显示彼此之间有什么关系。)
  • 然而,这似乎只有在查询和突出显示都是针对同一个字段执行时才成立(即 df = hl.fl)。(再次,不知道为什么......)
  • 然而,另一个,只有在对模式中存在的默认文本字段执行时。

这是我的测试方法-->

  • 测试针对大约 525,000 个文档
  • 几乎所有的字段都被复制到多值文本字段中
  • 在一些测试中,几乎所有字段被复制到发送多值text2字段(该字段与text相同,只是它具有相反的omitNorms设置
  • 每次更改配置,Solr 实例都会停止,data 文件夹会被删除,并重新启动实例

我发现了什么-->

  • 当仅使用文本字段并且存在omitNorms = true时,性能很差(10 秒响应时间)
  • 当仅使用文本字段并且omitNorms = true存在时,性能非常好(亚秒级响应时间)
  • text没有omitNorms = truetext2有时,查询会突出显示在亚秒时间内返回的文本,所有其他组合导致 10-30 秒的响应时间。
  • text确实有omitNorms = truetext2没有时所有带有突出显示的查询组合都会在 7-10 秒内返回。

我好糊涂。。。。

4

1 回答 1

1

我知道这有点过时了,但我遇到了同样的问题并想加入我们的方法。

我们正在从一堆二进制文档中索引文本,并且需要 Solr 来维护有关文档和文本的一些元数据。用户需要根据内容中的元数据和全文搜索来搜索文档,以及查看相关内容的亮点和片段。如果突出显示/片段的内容位于每个文档中的更远位置(例如第 50 页而不是第 2 页),性能问题会变得更糟

由于突出显示的性能不佳,我们不得不将每个文档分解为多个 solr 记录。根据内容字段的长度,我们会将其分成更小的块,将元数据属性复制到每条记录,并为每条记录分配一个每个文档的唯一 ID。然后在查询时,我们将搜索所有这些记录的内容字段,并按我们分配的唯一字段进行分组。由于内容字段更小,Solr 不必深入每个内容字段,而且从最终用户的角度来看,这是完全透明的;尽管它确实为我们增加了一些索引开销。

此外,如果您选择这种方法,您可能需要考虑在每个“子文档”之间稍微重叠几秒,以确保如果在两秒的边界处存在短语匹配,它将正确返回。

希望能帮助到你。

于 2015-07-14T15:26:02.990 回答