【问题标题】:How to handle very frequent updates to a Lucene index如何处理对 Lucene 索引的非常频繁的更新
【发布时间】:2011-04-19 14:14:55
【问题描述】:

我正在尝试制作一个索引/搜索应用程序的原型,该应用程序使用非常不稳定的索引数据源(论坛、社交网络等),以下是一些性能要求,

  1. 非常快的周转时间(我的意思是任何新数据(例如论坛上的新消息)都应该很快(不到一分钟)出现在搜索结果中)

  2. 我需要定期丢弃旧文档,以确保搜索结果没有过时。

  3. 最后但同样重要的是,搜索应用程序需要响应。 (延迟大约 100 毫秒,应该支持至少 10 qps)

我目前的所有要求都可以在不使用 Lucene 的情况下满足(这将让我满足所有 1,2 和 3),但我预计未来会有其他要求(如搜索相关性等),其中 Lucene更容易实现。但是,由于 Lucene 是为比我目前正在处理的更复杂的用例而设计的,因此我很难满足我的性能要求。

这里有一些问题,

一个。我读到 IndexWriter 类中的 optimize() 方法很昂贵,不应该被频繁更新的应用程序使用,有什么替代方案?

b.为了进行增量更新,我需要不断提交新数据,并不断刷新索引阅读器以确保它有可用的新数据。这些将影响上面的 1 和 3。我应该尝试重复索引吗?解决此问题的常用方法有哪些?

c。我知道 Lucene 提供了一个删除方法,它可以让您删除与某个查询匹配的所有文档,在我的情况下,我需要删除所有超过某个年龄的文档,现在一个选项是为每个文档添加一个日期字段文档并使用它稍后删除文档。是否可以对文档 ID 进行范围查询(我可以创建自己的 id 字段,因为我认为由 lucene 创建的字段会不断变化)以删除文档?它比比较以字符串表示的日期更快吗?

我知道这些都是非常开放的问题,所以我不是在寻找详细的答案,我会尽量将您的所有答案视为建议,并用它们来指导我的设计。谢谢!如果您需要任何其他信息,请告诉我。

【问题讨论】:

    标签: performance indexing lucene


    【解决方案1】:

    Lucene 现在支持Near Real Time Search。本质上,您每次进行搜索时都会从 IndexWriter 获得一个 Reader。在达到 RAM 缓冲区大小或在写入器上调用显式 commit 之前,内存中的更改不会进入磁盘。由于通过跳过 commit 避免了磁盘 IO,因此即使使用新数据,搜索也会快速返回。

    Lucene 的 NRT 的问题之一是索引对数合并算法。将 10 个文档添加到段后触发合并。接下来,合并这 10 个片段以创建一个包含 100 个文档的片段,依此类推。现在,如果您有 999,999 个文档,并且触发了合并,则需要相当长的时间才能返回,从而破坏了您的“实时”承诺。

    LinkedIn 已发布 Zoie,这是一个基于 Lucene 的库,可解决此问题。这是在生产中实时处理的,每天处理数百万次更新和搜索。

    大多数情况下,Lucene 将支持您的所有要求,因为您将丢弃旧的更新并且移动窗口的大小大致是恒定的。如果没有,您可能不得不尝试在战场上证明的Zoie。

    【讨论】:

      【解决方案2】:

      您可能要考虑使用 Solr 而不是直接使用 Lucene。 Solr 处理您提到的所有需求(近实时更新、删除文档、性能/分片、范围查询),它会比您自己的手动代码做得更好。您不必处理 IndexReader 级别的问题,即更新后何时刷新 IndexReader。

      就范围查询而言,Solr 具有 TrieField 功能,这使得数字范围查询非常快。见http://www.lucidimagination.com/blog/2009/05/13/exploring-lucene-and-solrs-trierange-capabilities/

      【讨论】:

        【解决方案3】:

        A:我认为在最新版本的 Lucene 中,优化方法并不是真正需要的,而根据我对 C 项的建议,它确实不需要。

        B:同样,我认为使用最新版本的 Lucene,搜索者会知道更新何时完成,并且无需您做任何特别的事情即可处理。

        C:我会避免删除,而只是每天创建一个新索引。如果将文档的年龄存储在索引中,则可以使用现有索引创建新索引。在编写索引期间,获取所有年轻文档,遍历它们并将它们添加到新索引中。有一个名为 getCurrentIndex 的公共 util 方法,搜索者使用它来获取最新的实时索引。保留 1 或 2 个旧索引以防万一,您应该一切顺利。

        【讨论】:

          【解决方案4】:

          您可以将索引搜索器缓存一小段时间,然后重新打开它。为此,我们使用了 asp.net WebCache,它具有 CacheItemUpdateCallback,在 chached 项目过期之前被调用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多