刚开始阅读Lucene.net,我希望我的一些基于REST的Web服务能够使用Lucene.net强大的搜索功能
但是我遇到一个链接,说我应该创建一个Windows服务(使用WCF)来执行所有lucene搜索/索引等,因为IIS会回收应用程序池,这将导致各种锁定问题。
我的问题是,这是正确的吗?如果是这样,是否有另一种解决此问题的方法,而无需创建Windows服务(使用WCF)?此外,由于我有基于REST的服务,我是否会从这些服务调用Windows WCF服务,这会使事情变慢?
答案 0 :(得分:4)
在阅读期间,您会发现使用IndexWriter
类完成索引编制。 Lucene一次只允许1 IndexWriter
个实例打开。使用默认锁定时,它会在索引目录中创建一个锁定文件,并阻止创建任何其他IndexWriter实例。因此,在您拥有更多控制权的流程中实施索引可能会更好。
如果索引过程因极端偏见而终止且IndexWriter
类未关闭,则会保留索引文件夹上的锁定,并且不允许其他实例。因为这个Lucene允许你从Indexed文件夹中解锁(使用IndexWriter.unlock
) - 这是一种危险的方法,因为如果在同一个索引上打开两个IndexWriters,它将破坏索引。如果您有一个正在执行索引的Windows服务,并且它是您的解决方案中进行索引(以及任何更新)的唯一过程,您可以在启动服务时自信地解锁索引文件夹。在基于Web服务的环境中,您正在从Web方法执行索引 - 控制和从锁定问题中恢复会出现问题。
IndexSearcher
类用于搜索。这种只读模式可以通过基于服务的代码完成。我认为没有必要为此目的创建一组单独的WCF方法。
索引可能需要根据卷定期针对性能进行优化。再次在单独的流程中进行索引,您可以每晚,每周或根据需要安排优化。优化是通过调用一种方法完成的。
如何以及何时获取索引流程以索引新数据....我不知道您正在索引哪些数据,因此很难说。在我的场景中,我有WCF方法负责输入数据 - 高容量。我要求尽快收到的数据可供搜索。所以,
我的模型层有一个通知层,当成功提交所需类型的新记录时,会在MSMQ中的本地队列中插入一条简单的通知消息。
MSMQ的原因是队列是持久的和事务性的,并且即使在系统重启崩溃之后其中的任何消息都可用 - 允许我永远(咳嗽!)丢失任何消息。
索引服务接收通知,构建Lucene Document
并为数据编制索引。
也可以通过删除爬行Db的现有索引来触发索引服务以执行完整的重新索引。
修改强>
架构示例:
WCF服务方法接受将数据提交到Model层的数据。 Model层通知侦听客户端在项目上成功发生了CRUD操作。侦听客户端将通知发布到队列中。
Windows服务处理数据索引,查看队列以索引请求。
ASP.Net app为用户界面提供搜索功能。
答案 1 :(得分:1)
您可以简单地禁用应用程序池回收并在IIS中托管您的应用程序/服务。 要禁用配置更改的回收,请使用disallowRotationOnConfigChange参数。
您还可以将应用程序拆分为两部分:索引更新和搜索。
处理来自Windows服务的索引更新,并让您的IIS部分处理搜索(只读)。您可以通过检测索引更新的机制来执行此操作,并刷新IndexSearchers
。这样,如果使用服务的性能损失是您的关注点,它将不会影响搜索时间,这是用户的重要方面。使用此配置,您甚至可以拥有主索引更新节点,并在服务器场中的不同Web服务器之间分发搜索。唯一的缺点是你没有近似实时搜索IndexWriter
类中内置的功能。
http://wiki.apache.org/lucene-java/NearRealtimeSearch
话虽这么说,我从未遇到过通过WCF服务公开Lucene功能的设置的性能问题,特别是如果您使用NetNamedPipe在同一台计算机上运行,或者在使用NetTcp的本地LAN上运行。