Lucene索引:按帐户共享还是隔离?

时间:2011-04-25 21:21:51

标签: lucene.net lucene

我正在评估Lucene在SaaS应用程序中实现全局搜索功能。

我们不希望用户看到其他帐户的内容,因此搜索将始终受到帐户的限制。

拥有一个帐户ID字段的单个索引或每个帐户一个索引更好吗?每种方法的优点和缺点是什么?

我担心的是,由于频繁更新,全局索引可能会影响性能。

谢谢。

修改

  • 估计总文件数:500,0000
  • 帐号:4000
  • 永远不会在帐户之间共享可索引数据
  • 帐户用户可能每天多次更新其可索引数据(大多数情况下不超过100)
  • 初始设置过程后,索引数据量趋于稳定
  • 我们需要为每个文档存储10-20个字段

3 个答案:

答案 0 :(得分:2)

除了常见问题(例如索引更新等)之外,我还会考虑一些事情:

  1. lucene返回排名结果的方式取决于某些“语料库范围”统计信息,例如术语在该字段中出现的文档总数。因此,如果客户a的索引统计数据不适合客户b,那么除了存在安全风险之外,它会损害两个客户的相关性......如果奥斯卡足够聪明,他真的可以开始撤销bob的文档,因为它的性质倒排索引:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.159.9682你可以用这个排名算法来解决这个问题:https://issues.apache.org/jira/browse/LUCENE-2864
  2. lucene中的其他一些内容适用于“整个字段”或“整体索引”,如果将索引组合在一起,您应该知道它们无法在每个客户的基础上进行真正的更改: omitTF(如果你在一个字段的单个文档中设置它,它在该字段中被省略),相似性(在任何已发布的lucene版本中,你只能设置相似性,所以客户将无法调整排名模型),拼写检查(你必须破解一些东西,每个客户都有自己的“过滤”拼写检查索引),...
  3. 另一方面,如果你有很多术语,需要相当多的RAM,并且通过为每个客户提供他们自己的索引,你需要更多的内存来保存RAM中的术语索引,用于所有索引。但是,你可以通过调整像termIndexInterval / Divisor这样的东西来降低这一点。

答案 1 :(得分:1)

如果是我,如果没有监管原因你不能,我会将它们全部转储到一个索引中。这只是我的“不要优化你不必要的”帽子说话。

第一个问题是合法的:你是否允许共同托管和混合数据,即使它是通过逻辑方式分开的。这取决于您的律师,客户和服务协议。这不是技术问题。

假设你可以,那么接下来的问题是其他用户对彼此的影响。如果用户A正在使用系统而用户B正在导入他们的100K文档,那是否会影响用户A?它是否会影响用户A,因为Lucene的工作原理,或仅仅是因为导入和索引文档时出现的整体系统负载。

试一试,看看。

关键是要确保您的客户端系统不直接访问Lucene,而是通过某种外观访问。这个外观是强制客户端隔离的理想场所,如果您稍后决定需要对索引进行分片,它也是重定向流量的好地方。

也许你需要撕掉一个重度用户。或者你向那些在SLA中保证更多资源的人出售更高水平的响应时间

但现在决定更好的道路是什么?呃,似乎很早。

500K文件并不是Lucene的大量数据。如果您发现在单个实例中托管所有功能都不可行,请确保您的实施具有灵活性以便稍后添加功能。通过“添加功能”我的意思是,添加它。实际上并不是基于客户端进行分片。但是有一个很好的观点,它可以实现,而不会在以后重做一堆管道。

答案 2 :(得分:1)

我已经在这里和那里做了一些“安全修剪”索引 - 如果允许的话肯定是可能的。也就是说,我对具有多个客户端的SAAS类型的一般倾向是尽可能地将客户分开,原因如下:

a)确保编码错误不会导致数据泄露,愤怒的客户,诉讼和其他问题。 b)使每个客户端的定制变得更加容易 - 您的整个代码库不需要处理特定于客户端的fubar请求 c)从第一天开始强制你进入一个水平可扩展的架构 - 如果添加实例很容易,缩放很容易,对吗?

哦,肯定会接受Will Hartung的建议 - 门面搜索,那些东西真的不应该从它的层面爬出来。