处理Solr中的大量ID
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了处理Solr中的大量ID相关的知识,希望对你有一定的参考价值。
我需要在Solr中执行在线搜索,即用户需要查找具有特定条件的在线用户列表。
我如何处理这个问题:我们将用户的ID存储在一个表中,并在Solr请求中发送所有在线用户ID
&fq=-id:(id1 id2 id3 ............id5000)
这种方法的问题在于,当id变大时,Solr需要花费太多时间来解决,我们需要通过网络传输大量请求。
一种解决方案可以是在Solr中使用join,但是在线数据会定期更改,我不能每次都对数据进行索引(例如5-10分钟,应该至少一小时)。
其他解决方案我认为根据URL中的某些参数从Solr内部触发此查询。我对Solr内部结构不太了解,所以不知道如何继续。
使用Solr4的软提交,提交已经变得足够便宜,可以将“在线”标志直接存储在用户记录中,并且在查询中只需要&fq = online:true。这减少了通过线路发送5000个id并解析它们所涉及的开销,并让Solr稍微优化了查询。每当有人登录或注销时,设置其状态并在更新时设置commitWithin。无论如何,它值得一试。
我们通过实施数据分片来解决这个问题。
基本上,没有深入到代码细节:
- 编写自己的索引代码 使用consistent hashing来决定哪个ID到哪个Solr服务器 将每个用户数据索引到相关的分片(它可以是几台机器) 确保你有冗余
- 查询Solr分片
使用
shards
参数在Solr中进行分片查询 启动EmbeddedSolr并使用它来执行分片查询 Solr将查询所有分片并合并结果,如果您需要限制每个分片的查询时间,它还会提供超时
即使完全按照上面的说法,我也不相信Solr非常适合这一点。 Solr不太适合搜索不断变化的索引,并且如果您主要通过ID搜索而不是搜索引擎则不需要。
对于我们的项目,我们基本上实现了所有索引构建,负载平衡和查询引擎,并且主要使用Solr作为存储。但是我们已经开始使用Solr,当分片是flaky而不是高性能时,我不确定今天的状态是什么。
最后请注意,如果我今天从头开始构建这个系统而没有我们在过去4年中所做的所有工作,我建议使用缓存来存储当前在线的所有用户(比如memcached或redis)并且在请求时我会简单地迭代所有这些并根据标准过滤掉。按标准过滤可以独立缓存并逐步更新,如果匹配逻辑非常简单,则迭代超过5000条记录也不一定非常耗时。
任何强大的解决方案都将包括将您的数据接近SOLR(批处理)并在内部使用它。在搜索期间没有运行非常大的请求,这是低延迟的事情。你应该开发自己的过滤器;过滤器会偶尔缓存在线用户数据(例如,每分钟)。如果数据经常变化,请考虑实施PostFilter。
你可以在这里找到一个很好的过滤器实现示例:http://searchhub.org/2012/02/22/custom-security-filtering-in-solr/
一个解决方案可以使用solr中的join,但是在线数据会定期更改,并且每次都无法索引数据(例如5-10分钟,它应该至少是一小时)
我认为你可以很好地使用Solr加入,但经过一些即兴创作。
解决方案,我建议如下:
You can have 2 Indexes (Solr Cores)
1. Primary Index (The one you have now)
2. Secondary Index with only two fields , "ID" and "IS_ONLINE"
您现在可以经常更新二级索引(以秒为单位)并使其与您拥有的表保持同步,以存储在线用户。
注意:即使经常更新,此二级索引也不会降低任何性能,前提是我们在delta-import等过程中进行必要的调整,例如使用适当的查询等。
您现在可以在这两个索引上的ID字段上执行Solr join以实现您想要的效果。这是关于如何在Indexes / Solr Core之间执行Solr Joins的link。
以上是关于处理Solr中的大量ID的主要内容,如果未能解决你的问题,请参考以下文章
Solr 高亮是不是还可以指示返回的片段在原始字段中的位置或偏移量?
运行具有大量过滤的 Solr Query 时出现 SocketException
02 Apache Solr: 概览 Solr在信息系统架构中的位置