突出显示时Solr性能非常慢



我配置了一个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 秒。要么第一次删除 omitNorm 是侥幸,要么还有其他事情正在发生。我不知道是什么...

使用 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%,民意调查数字高达 30%。

有什么想法吗?我还能从其他地方追踪瓶颈吗?

谢谢

更新

我已经使用相同的数据集但不同的配置进行了大量测试,这是我发现的......虽然我不明白我的发现。

  • 快速突出显示性能要求省略规范不设置为 true。(不知道省略规范和突出显示之间有什么关系。
  • 但是,仅当查询和突出显示都针对同一字段(即 df = hl.fl)执行时,这才是正确的。(同样,不知道为什么...
  • 但是,另一个,仅当针对架构中存在的默认文本字段执行时。

这是我的测试方式-->

  • 针对大约 525,000 份文档进行了测试
  • 几乎所有字段都复制到多值文本字段
  • 在某些测试中,几乎所有字段也被复制到发送多值 text2 字段中(此字段与文本相同,只是它具有相反的 omitNorm 设置。
  • 每次更改配置时,都会停止 Solr 实例,删除数据文件夹,并启动实例备份

我发现了什么-->

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

我太困惑了....

我知道

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

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

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

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

希望对您有所帮助。

最新更新