在具有多个Web服务器的现有.NET/SQL Server堆栈上实现Lucene

gro*_*wse 28 .net sql-server lucene lucene.net

我想看看Lucene是否为我目前管理的网站提供全文搜索解决方案.该站点完全基于SQL Server 2008/C#.NET 4技术构建.我想要索引的数据实际上非常简单,每条记录只有几个字段,其中只有一个字段可以实际搜索.

我不清楚我需要使用的最佳工具集是什么,或者我应该使用的架构是什么.特别:

  1. 我应该把索引放在哪里?我见过人们建议把它放在网络服务器上,但这对于大量的网络服务器来说似乎很浪费.当然,集中化会更好吗?

  2. 如果索引是集中的,我会如何查询它,因为它只存在于文件系统上?我是否必须将其有效地放在所有网络服务器都可以看到的网络共享上?

  3. 是否有任何预先存在的工具会按计划逐步填充Lucene索引,从SQL Server数据库中提取数据?在这里推销我自己的服务会更好吗?

  4. 当我查询索引时,我是否应该只是拉回一堆记录ID,然后我返回到DB以获取实际记录,或者我是否应该直接从索引中提取搜索所需的所有内容?

  5. 尝试在这种味道环境中实现像Solr这样的东西有价值吗?如果是这样,我可能会给它自己的*nix VM并在Tomcat中运行它.但我不确定Solr会在这种情况下给我买什么.

Nic*_*ver 50

我将根据我们如何选择在Stack Overflow上实现Lucene.Net以及我在此过程中学到的一些经验来回答:

我应该把索引放在哪里?我见过人们建议把它放在网络服务器上,但这对于大量的网络服务器来说似乎很浪费.当然,集中化会更好吗?

  • 这取决于你的目标,我们有一个严重未充分利用的Web层(约10%的CPU),以及一个执行FullText搜索的重载数据库(大约60%的CPU,我们希望它更低).在每个 Web层加载相同的索引让我们利用这些机器并拥有大量冗余,如果需要,我们仍然可以丢失10个Web服务器中的9个并保持堆栈交换网络.这有一个缺点,它对我们来说非常IO(阅读)密集,并且考虑到这一点并未购买Web层(大多数公司通常都是如此).虽然它工作正常,但我们仍然会将我们的Web层升级到SSD并实现.Net端口之外的其他一些位来补偿这种硬件缺陷(NIOFSDirectory例如).
  • 另一个缺点是,如果我们n为Web层索引所有数据库的时间,但幸运的是我们不会因为网络带宽和SQL服务器缓存而缺乏结果,这使得每次都是一个非常快速的delta索引操作.使用大量Web服务器,仅此一项就可以消除此选项.

如果索引是集中的,我会如何查询它,因为它只存在于文件系统上?我是否必须将其有效地放在所有网络服务器都可以看到的网络共享上?

  • 您可以在文件共享上查询它,只需确保一次只有一个索引(write.lock目录锁定机制将确保这一点,并在您一次尝试多个IndexWriters时出错).
  • 请记住上面的注意事项,当很多读者飞来飞去时,这是IO密集型的,因此您的商店需要足够的带宽,至少缺少iSCSI或光纤SAN,我会谨慎对待这种方法.高流量(每天数十万次搜索)使用.
  • 另一个考虑因素是如何更新/警告您的Web服务器(或任何层正在查询它).完成索引传递后,您需要重新打开IndexReaders以获取具有新文档的更新索引.我们使用redis消息传递通道来提醒任何关心索引已更新的人......任何消息传递机制都可以在这里工作.

是否有任何预先存在的工具会按计划逐步填充Lucene索引,从SQL Server数据库中提取数据?在这里推销我自己的服务会更好吗?

  • 不幸的是,我不知道,但我可以与你分享我是如何接近这一点的.
  • 索引特定表(类似于Lucene中的文档)时,我们向该表添加了一个rowversion.当我们索引时,我们选择基于最后一个rowversion(timestamp数据类型,作为bigint拉回).我选择通过一个简单的.txt文件在文件系统上存储最后一个索引日期和最后一个索引的rowversion,原因之一是:Lucene中的所有其他内容都存储在那里.这意味着如果有一个大问题,你可以删除包含索引的文件夹,下一个索引传递将恢复并拥有一个完全最新的索引,只需添加一些代码来处理没有任何意义"索引所有内容" .

当我查询索引时,我是否应该只是拉回一堆记录ID,然后我返回到DB以获取实际记录,或者我是否应该直接从索引中提取搜索所需的所有内容?

  • 实际上取决于您的数据,对于我们来说,将所有内容存储在索引中并不是真的可行(也不建议这样做).我建议您将搜索结果的字段存储在索引中,我指的是在用户单击以完成[在此处插入类型]之前,您需要在列表中显示搜索结果所需的内容.
  • 另一个考虑因素是数据的变化频率.如果您搜索的许多字段正在快速变化,则您需要重新索引这些行(文档)以更新索引,而不仅仅是在您搜索的字段发生更改时.

尝试在这种味道环境中实现像Solr这样的东西有价值吗?如果是这样,我可能会给它自己的*nix VM并在Tomcat中运行它.但我不确定Solr会在这种情况下给我买什么.

  • 当然有,这是您正在谈论的集中搜索(通过大量搜索,您可能会再次使用VM设置达到限制,请密切注意这一点).我们并没有在我们的技术堆栈做到这一点,因为它推出了很多(我们感到)莫须有的复杂性和制造过程,但对Web服务器的数量较多它使得很多更有意义.
  • 它给你带来了什么?主要是性能,以及专用的索引服务器.而不是n服务器抓取网络共享(也竞争IO),他们可以命中一个服务器,通过网络处理请求和结果,而不是抓取索引,这是更多的数据来回...这将在Solr服务器上本地.此外,由于较少的服务器正在编制索引,因此您没有那么多地访问SQL服务器.
  • 不会给你带来多少冗余,但这取决于你的重要性.如果您可以在降级搜索上运行正常或没有它,只需让您的应用程序处理.如果你不能,那么备份Solr服务器或更多也可能是一个有效的解决方案...并且可以维护另一个软件堆栈.