在多个应用服务器上同步Lucene.net索引

时间:2009-06-03 11:09:42

标签: lucene lucene.net

我们正在为企业Web应用程序设计搜索体系结构。我们将使用Lucene.net。索引不会很大(大约100,000个文档),但搜索服务必须始终保持最新状态并始终保持最新状态。将始终向索引添加新文档和并发搜索。 由于我们必须具有搜索系统的高可用性,因此我们有2个应用程序服务器,它们公开WCF服务以执行搜索和索引(服务的副本在每个服务器中运行)。然后,服务器使用lucene.net API来访问索引。

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

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

  • 索引到两个服务器,实质上是将每个索引写入两次:可能性能糟糕,并且如果例如,则可能出现异步。服务器1索引正常,服务器2耗尽磁盘空间或其他任何内容;

  • 使用SOLR或KATTA来封装对索引的访问:nope,我们不能在服务器上运行tomcat或类似的东西,我们只有IIS。

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

  • 使用Lucene.net DistributedSearch contrib模块:我无法提供有关此文档的单个链接。我甚至不知道通过查看代码的代码所做的事情,但在我看来,它实际上是在多台机器上拆分索引,这不是我们想要的。

  • rsync和朋友,在两台服务器之间来回复制索引:这对我们来说感觉很乱,容易出错,如果索引变大,可能需要一段时间,在此期间我们会向客户返回损坏或不一致的数据,因此我们必须制定一些我们不想要的临时锁定策略。

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

5 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:2)

我知道这是一个老问题,但我刚刚遇到它,并希望为其他任何寻求多服务器实施建议的人提供2美分。

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

我会配置负载均衡器后面的两个应用服务器。任何索引请求都会将文档索引到NAS上的计算机专用文件夹中。也就是说,NAS上将有与您的应用服务器一样多的索引。当搜索请求进入时,您将使用Lucene进行多索引搜索。 Lucene有内置的构造(MultiSearcher),性能仍然很好。

答案 2 :(得分:1)

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

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

我之前使用的解决方案涉及在一台服务器上创建索引块,然后使用IndexWriter.AddIndexesNoOptimizersync转换到搜索服务器并将块合并到每个索引中。您可以每5分钟或每当达到一定大小时创建一个新块。如果您不必拥有绝对最新的索引,这可能是您的解决方案。

答案 3 :(得分:1)

在java世界中,我们通过在索引前面放置一个MQ来解决这个问题。只有当从队列中取出的bean成功时,插入才会完成,否则它只会回滚它所执行的任何操作,在文档上标记为待处理,稍后再次尝试

答案 4 :(得分:0)

我们保持负载均衡服务器同步的方式,每个都有自己的Lucene副本,就是在其他服务器上运行任务,每5分钟运行一次,命令每个负载均衡的服务器将其索引更新为某个时间戳。

例如,任务向所有负载平衡服务器发送时间戳'12 / 1/2013 12:35:02.423'(任务通过查询字符串将时间戳提交到每个负载均衡网站上的网页) ,然后每个服务器使用该时间戳来查询数据库,查找自上次更新到该时间戳以来发生的所有更新,并更新其本地Lucene索引。

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