4

刚开始阅读 Lucene.net,我希望我的一些基于 REST 的 Web 服务能够使用 Lucene.net 的强大搜索功能

但是,我遇到了一个链接,该链接说我应该创建一个 Windows 服务(使用 WCF)来执行所有 lucene 搜索/索引等,因为 IIS 会回收应用程序池,这将导致各种锁定问题。

我的问题是,这是正确的吗?如果是这样,是否有另一种方法可以在不创建 Windows 服务(使用 WCF)的情况下解决此问题?另外,由于我有基于 REST 的服务,我是否会从这些服务调用 Windows WCF 服务,这会使事情变慢?

4

2 回答 2

4

索引

在阅读过程中,您会发现索引是使用IndexWriter类完成的。Lucene 一次只允许IndexWriter打开 1 个实例。使用默认锁定时,它会在索引目录中创建一个锁定文件并阻止创建任何其他 IndexWriter 实例。出于这个原因,在您可以更好地控制的过程中实现索引可能会更好。

如果您的索引过程因极端偏见而终止并且您的IndexWriter班级没有关闭,则索引文件夹上的锁定将保持不变,并且不允许其他实例。因此,Lucene 允许您从索引文件夹中解除锁定(使用IndexWriter.unlock)——这是一种危险的方法,因为如果在同一个索引上打开了两个 IndexWriter,它将破坏索引。如果您有一个正在执行索引的 Windows 服务,并且它是您的解决方案中执行索引(和任何更新)的唯一进程,您可以放心地在服务启动时解锁索引文件夹。在基于 Web 服务的环境中,您从 Web 方法执行索引 - 控制和从锁定问题中恢复会成为问题。

搜索

该类IndexSearcher用于搜索。这在只读模式下可以从您的基于服务的代码中完成。我认为没有必要为此创建一组单独的 WCF 方法。

优化

可能需要根据卷定期优化索引的性能。再次在单独的过程中建立索引,您可以每晚、每周或任何需要的时间安排优化。优化是通过调用一种方法来完成的。

索引新数据

如何以及何时让索引过程为新数据建立索引……我不知道你在索引什么数据,所以很难说。在我的场景中,我有负责输入数据的 WCF 方法 - 大量。我要求尽快将收到的数据用于搜索。所以,

我的模型层有一个通知层,当成功提交所需类型的新记录时,会在 MSMQ 的本地队列中插入一条简单的通知消息。

MSMQ 的原因是队列是持久的和事务性的,并且即使在系统重新启动崩溃后,其中的任何消息都可用 - 让我永远不会(咳嗽!)丢失任何消息。

索引服务接收通知,构建 LuceneDocument并对数据进行索引。

还可以通过删除现有索引并爬取 Db 来触发索引服务以执行完整的重新索引。

编辑:

示例架构:

WCF 服务方法将数据提交到模型层。模型层通知侦听客户端在项目上成功发生了 CRUD 操作。侦听客户端在队列中发布通知。

Windows 服务处理数据索引,监视索引请求队列。

ASP.Net 应用程序提供具有搜索功能的用户界面。

于 2012-09-05T05:42:09.880 回答
1

您可以简单地禁用应用程序池回收并在 IIS 中托管您的应用程序/服务。要禁用配置更改的回收,请使用 disallowRotationOnConfigChange 参数。

您还可以将应用程序分为两部分:索引更新和搜索。

处理来自 Windows 服务的索引更新,并让您的 IIS 部分处理搜索(只读)。您可以通过一种机制来检测索引更新并刷新IndexSearchers. 这样,如果您担心使用服务的性能损失,它不会影响搜索时间,这对用户来说是重要的方面。使用此配置,您甚至可以拥有一个主索引更新节点,并在场中的不同 Web 服务器之间分配搜索。唯一的缺点是你没有类中内置的近乎实时的搜索功能IndexWriter

http://wiki.apache.org/lucene-java/NearRealtimeSearch

话虽如此,我从来没有遇到过通过 WCF 服务公开 Lucene 功能的设置的性能问题,尤其是当您使用 NetNamedPipe 在同一台机器上或使用 NetTcp 在本地 LAN 上运行时。

于 2012-09-05T03:24:03.027 回答