代码之家  ›  专栏  ›  技术社区  ›  axel_c

跨多个应用服务器同步lucene.net索引

  •  13
  • axel_c  · 技术社区  · 15 年前

    我们正在为公司Web应用程序设计搜索架构。我们将使用lucene.net。索引不会太大(大约100000个文档),但搜索服务必须始终处于最新状态。将有新的文档一直添加到索引中,并同时进行搜索。 由于搜索系统必须具有高可用性,因此我们有两个应用程序服务器,它们公开一个WCF服务来执行搜索和索引(每个服务器上都运行该服务的一个副本)。然后,服务器使用lucene.net API访问索引。

    问题是,保持索引始终同步的最佳解决方案是什么?我们考虑了几种选择:

    • 使用一台服务器进行索引和 让第二个服务器访问 通过SMB的索引:没有可以做的,因为我们 有一个单一的失败点 情况;

    • 为两个服务器建立索引,基本上每写一个索引两次:可能性能不好,如果服务器1的索引正常,服务器2的磁盘空间不足或其他原因,也可能会出现去同步;

    • 使用solr或katta包装对索引的访问:不,我们不能让Tomcat或类似的服务器运行,我们只有IIS。

    • 在数据库中存储索引:我发现这可以用Lucene(JDCB目录模块)的Java版本来完成,但是我找不到类似于LuceN.NET的任何东西。即使这意味着一个小的性能损失,我们也会选择这个选项,因为它可以很好地解决Mininum开发中的并发性和同步问题。

    • 使用lucene.net distributedsearch contrib模块:我无法用有关此的文档来提交单个链接。我甚至不知道通过查看代码,这段代码会做什么,但在我看来,它实际上是在多台机器上分割索引,这不是我们想要的。

    • rsync和friends,在两台服务器之间来回复制索引:这让我们感觉很不安全,容易出错,如果索引变大,可能需要一段时间,在此期间,我们将向客户机返回损坏或不一致的数据,因此我们必须制定一些我们不希望的特别锁定策略。

    我知道这是一个复杂的问题,但我相信很多人以前都遇到过。欢迎任何帮助!

    5 回复  |  直到 15 年前
        1
  •  6
  •   Sean Carpenter    15 年前

    最好的解决方案似乎是将两台服务器上的文档索引到它们自己的索引副本中。

    如果您担心索引在一台服务器上成功而在另一台服务器上失败,那么您需要跟踪每台服务器的成功/失败,以便在问题解决后重新尝试失败的文档。这种跟踪将在Lucene之外的任何系统中进行,您使用这些系统来呈现要索引到Lucene的文档。根据索引的完整性对您有多重要,您可能还必须从正在使用的任何负载平衡器中删除发生故障的服务器,直到问题得到解决,并且索引已重新处理任何未完成的文档。

        2
  •  1
  •   itsadok    15 年前

    +肖恩·卡彭特的答案是1。在两台服务器上建立索引似乎是最明智和最安全的选择。

    如果要索引的文档很复杂(Word/PDF和排序),可以在单个服务器上执行一些预处理,然后将其提供给索引服务器,以节省一些处理时间。

    我以前使用过的解决方案包括在一台服务器上创建一个索引块,然后 rsync 将其转移到搜索服务器并将块合并到每个索引中,使用 IndexWriter.AddIndexesNoOptimize .您可以每5分钟创建一个新块,或者每当它达到某个大小时创建一个新块。如果您不必拥有绝对最新的索引,这可能是您的解决方案。

        3
  •  1
  •   Aaron Saunders    15 年前

    在Java世界中,我们通过在索引前面放置一个MQ来解决这个问题。只有当从队列中提取的bean成功时,插入才完成,否则它只是回滚它所采取的任何操作,并在文档上标记为挂起,稍后再试。

        4
  •  1
  •   user1004123    12 年前

    我知道这是一个古老的问题,但我只是遇到了这个问题,我想给其他人2美分,以寻求关于多服务器实现的建议。

    为什么不将索引文件保存在共享的NAS文件夹上?它与将索引存储在您正在考虑的数据库中有什么不同?可以复制数据库以获得高可用性,也可以复制为NAS!

    我将配置负载均衡器后面的两个应用服务器。任何传入的索引请求都将为NAS上特定于计算机的文件夹中的文档编制索引。也就是说,NAS上的索引与应用服务器上的索引一样多。当一个搜索请求出现时,您将使用Lucene进行多索引搜索。Lucene内置了构造(多搜索器)来实现这一点,而且性能仍然很好。

        5
  •  0
  •   Doug S    11 年前

    我们保持负载平衡服务器同步的方法是在其他服务器上执行任务,每5分钟运行一次,命令每个负载平衡服务器将其索引更新到某个时间戳。

    例如,该任务向所有负载平衡服务器发送时间戳“12/1/2013 12:35:02.423”(该任务通过querystring将时间戳提交到每个负载平衡网站上的一个网页),然后每个服务器使用该时间戳查询数据库中自上次更新到该时间戳后发生的所有更新,并且U更新他们的本地Lucene指数。

    每个服务器还将时间戳存储在数据库中,因此它知道每个服务器上次更新的时间。因此,如果服务器脱机,当它重新联机时,下次收到时间戳命令时,它将获取脱机时丢失的所有更新。