我想考虑使用 Lucene 为我当前管理的网站提供全文搜索解决方案。该网站完全基于 SQL Server 2008 / C# .NET 4 技术构建。我要索引的数据实际上非常简单,每个记录只有几个字段,并且只有其中一个字段实际上是可搜索的。
我不清楚我需要使用的最佳工具集是什么,或者我应该使用的架构是什么。具体来说:
我应该把索引放在哪里?我见过有人建议将其放在网络服务器上,但这对于大量网络服务器来说似乎是浪费。集中化在这里肯定会更好吗?
如果索引是集中式的,鉴于它仅存在于文件系统上,我将如何查询它?我是否必须有效地将其放在所有网络服务器都可以看到的网络共享上?
是否有任何预先存在的工具可以按计划增量填充 Lucene 索引,从 SQL Server 数据库中提取数据?我在这里推出自己的服务会更好吗?
当我查询索引时,我是否应该只提取一堆记录 ID,然后返回到数据库以获取实际记录,或者我应该直接从索引中提取搜索所需的所有内容?
在这种风味环境中尝试实现像 Solr 这样的东西是否有价值?如果是这样,我可能会给它它自己的 *nix VM 并在 Tomcat 中运行它。但我不确定在这种情况下 Solr 会给我买什么。
我会根据我们选择的实施方式来回答一些Lucene.Net 在 Stack Overflow 上 https://blog.stackoverflow.com/2011/01/stack-overflow-search-now-81-less-crappy/,以及我一路上学到的一些教训:
我应该把索引放在哪里?我见过有人建议将其放在网络服务器上,但这对于大量网络服务器来说似乎是浪费。集中化在这里肯定会更好吗?
- 这取决于你的目标,我们有一个severely未充分利用的 Web 层(~10% CPU),以及进行全文搜索的超载数据库(大约 60% CPU,我们希望它更低)。加载相同的索引each网络层让我们利用这些机器并拥有大量冗余,如果需要,我们仍然可以失去十分之九的 Web 服务器并保持 Stack Exchange 网络正常运行。这样做有一个缺点,它对我们来说是 IO(读取)密集型的,并且购买 Web 层时并没有考虑到这一点(大多数公司通常都是这种情况)。虽然它工作正常,但我们仍然会将我们的 Web 层升级到 SSD,并实现 .Net 端口中遗漏的一些其他位,以弥补这种硬件缺陷(
NIOFSDirectory
例如)。
- 如果我们索引所有数据库,另一个缺点
n
Web 层的时间,但幸运的是,我们并不缺乏网络带宽,而且 SQL Server 缓存结果使得每次增量索引操作都非常快。对于大量的 Web 服务器,仅此一项就可能消除此选项。
如果索引是集中式的,鉴于它仅存在于文件系统上,我将如何查询它?我是否必须有效地将其放在所有网络服务器都可以看到的网络共享上?
- 您可以通过任何一种方式在文件共享上查询它,只需确保一次只有一个正在建立索引(
write.lock
,目录锁定机制将确保这一点,并在您一次尝试多个 IndexWriter 时出错)。
- 请记住我上面的注释,当很多读者飞来飞去时,这是 IO 密集型的,因此您的商店需要足够的带宽,至少缺少 iSCSI 或光纤 SAN,我会谨慎对待这种方法高流量(每天数十万次搜索)使用。
- 另一个考虑因素是如何更新/警告您的网络服务器(或查询它的任何层)。完成索引传递后,您需要重新打开
IndexReader
s 获取新文档的更新索引。我们使用一个Redis消息通道 http://redis.io/topics/pubsub提醒任何关心索引已更新的人...任何消息传递机制都可以在这里工作。
是否有任何预先存在的工具可以按计划增量填充 Lucene 索引,从 SQL Server 数据库中提取数据?我在这里推出自己的服务会更好吗?
- 不幸的是,据我所知,没有,但我可以与您分享我是如何处理这个问题的。
- 当索引特定表(类似于 Lucene 中的文档)时,我们添加了行版本 http://msdn.microsoft.com/en-us/library/ms182776.aspx到那张桌子。当我们索引时,我们根据最后一个行版本(a时间戳 http://msdn.microsoft.com/en-us/library/ms182776.aspx数据类型,作为bigint http://msdn.microsoft.com/en-us/library/ms187745.aspx)。我选择通过一个简单的 .txt 文件在文件系统上存储最后一个索引日期和最后一个索引行版本,原因之一是:Lucene 中的其他所有内容都存储在那里。这意味着如果出现大问题,您可以删除包含索引的文件夹,下一个索引过程将恢复并具有完全最新的索引,只需添加一些代码来处理不存在的内容,这意味着“索引所有内容” 。
当我查询索引时,我是否应该只提取一堆记录 ID,然后返回到数据库以获取实际记录,或者我应该直接从索引中提取搜索所需的所有内容?
- This really取决于您的数据,对于我们来说,将所有内容存储在索引中实际上并不可行(也不建议这样做)。我建议您将搜索结果的字段存储在索引中,我的意思是您需要什么present在用户单击转到完整的[在此处插入类型]之前,您的搜索结果会显示在列表中。
- 另一个考虑因素是数据更改的频率。如果你有很多领域not搜索的内容正在快速变化,您需要重新索引这些行(文档)来更新索引,而不仅仅是当您搜索的字段发生变化时。
在这种风味环境中尝试实现像 Solr 这样的东西是否有价值?如果是这样,我可能会给它它自己的 *nix VM 并在 Tomcat 中运行它。但我不确定在这种情况下 Solr 会给我买什么。
- 当然有,这就是您所说的集中式搜索(搜索次数较多时,您可能会再次达到虚拟机设置的限制,请密切关注)。我们没有这样做,因为它在我们的技术堆栈和构建过程中引入了很多(我们认为)不必要的复杂性,但对于大量的 Web 服务器来说,它使得much更有意义。
- 它给你买了什么?主要是性能和专用索引服务器。代替
n
服务器爬行网络共享(也竞争 IO),它们可以访问单个服务器only处理网络上的请求和结果,而不是抓取索引,因为索引会来回传输更多数据......这将是 Solr 服务器上的本地数据。此外,由于索引服务器较少,因此您不会频繁访问 SQL 服务器。
- What it doesn't买你的也是同样多的冗余,但这取决于你有多重要。如果您可以在降级搜索或没有降级搜索的情况下正常运行,只需让您的应用程序处理即可。如果你can't,那么备份 Solr 服务器或更多服务器也可能是一个有效的解决方案......并且可能需要维护另一个软件堆栈。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)