2009-06-03 111 views
12

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

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

  • 使用索引和一个服务器 具有第二服务器访问通过SMB的 指标:没有做不到的,因为我们有 失败 情况的单点;

  • 为两台服务器建立索引,实质上每次编写索引两次:可能性很差,并且可能会出现异步。服务器1索引正常,服务器2耗尽磁盘空间或任何东西;

  • 使用SOLR或KATTA来包装对索引的访问:nope,我们不能在服务器上运行tomcat或类似服务器,我们只有IIS。我发现这可以通过Lucene(JdbcDirectory模块)的Java版本来完成,但是我找不到Lucene.net的任何类似的东西。即使这意味着小的性能下降,我们也会选择这个选项,因为它可以彻底解决并发问题,并与mininum开发同步。

  • 使用Lucene.net DistributedSearch contrib模块:我无法用文档记录关于此的单个链接。我甚至不知道通过查看代码的代码是什么,但在我看来,它实际上将索引拆分到多台机器上,这不是我们想要的。如果索引变大,可能需要一段时间,并且在这段时间内,我们将会成为rsync和朋友,在两台服务器之间来回拷贝索引:返回腐败或不一致的数据给客户,所以我们不得不制定一些我们不想要的特别锁定策略。

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

回答

6

看来最好的解决方案是将两台服务器上的文档编入索引的索引副本。

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

+0

肖恩,这是目前我们的候选人选项。我同意你和它的看法,这似乎是最为抉择的选择。我还试图找到JdbcDirectory的源代码,以查看.NET + SQL服务器的端口是否可行。 将问题保持开放一段时间,看看是否有新的方法出现,否则将接受此答案。 – 2009-06-03 12:44:45

+0

我查了一次同样的事情。这似乎不值得付出努力,因为存在一堆与DB事务相关的东西,这些东西并不是微不足道的。也有使用JDBCDirectory的东西降低速度的抱怨。源文件在Compass项目中 - http://svn.compass-project.org/svn/compass/trunk/src/main/src/org/apache/lucene/store/jdbc/ – 2009-06-03 22:39:04

1

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

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

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

1

在java世界中,我们通过将MQ放在索引前面解决了这个问题。插入仅在从队列中拉出的bean成功时完成,否则它只是回滚它所花费的任何操作,在文档上标记为待处理,并且稍后再次尝试

1

我知道这是一个老问题,但我刚碰到它,想给我的2美分给其他人寻找多服务器实施建议。

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

我会配置负载均衡器后面的两个应用程序服务器。任何索引请求都会将索引文件编入NAS中机器特定的文件夹中。也就是说,NAS上的索引将与您的应用服务器一样多。当搜索请求进入时,您将使用Lucene进行多索引搜索。 Lucene构建了(MultiSearcher)内置的功能,并且性能仍然非常出色。

0

我们保持同步,我们的负载平衡服务器的方式,每一个都有自己的Lucene的副本,是有一些其他的服务器上的任务,运行每5分钟指挥每个负载平衡服务器来更新他们的索引一定的时间戳。

例如,任务发送的'12 /二千○十三分之一12时间戳:35:02.423' 的所有负载平衡的服务器(任务被提交经由查询字符串的时间戳到网页每个负载平衡网站上),那么每个服务器都使用该时间戳来查询数据库,以获取自上次更新到该时间戳以来发生的所有更新,并更新其本地Lucene索引。

每台服务器还将时间戳存储在数据库中,以便知道每台服务器上次更新的时间。因此,如果服务器脱机,当它恢复联机状态时,下次收到时间戳命令时,它将抓取它在脱机时错过的所有更新。