6

我需要在 Solr 中执行在线搜索,即用户需要查找具有特定条件的在线用户列表。

我是如何处理这个问题的:我们将用户的 ID 存储在一个表中,然后在 Solr 请求中发送所有在线用户 ID,例如

&fq=-id:(id1 id2 id3 ............id5000)

这种方法的问题是,当 id 变大时,Solr 需要花费太多时间来解决,我们需要通过网络传输大请求。

一种解决方案可以在 Solr 中使用 join,但在线数据会定期更改,我不能每次都索引数据(比如 5-10 分钟,应该至少一个小时)。

其他解决方案我认为基于 URL 中的某些参数从 Solr 内部触发此查询。我对 Solr 内部没有太多了解,所以不知道如何进行。

4

4 回答 4

3

使用 Solr4 的软提交,提交变得足够便宜,可以将“在线”标志直接存储在用户记录中,并且只需在查询中使用 &fq=online:true。这减少了通过网络发送 5000 个 id 和解析它们所涉及的开销,并让 Solr 稍微优化查询。每当有人登录或注销时,设置他们的状态并在更新时设置 commitWithin。无论如何,值得一试。

于 2013-05-05T17:49:18.983 回答
3

我们通过实施数据分片解决了这个问题。

基本上,无需深入研究代码细节:

  • 编写自己的索引代码
    • 使用一致的哈希来决定哪个 ID 去哪个 Solr 服务器
    • 将每个用户数据索引到相关分片(可以是几台机器)
    • 确保你有冗余
  • 查询 Solr 分片
    • shards使用参数在 Solr 中执行分片查询
    • 启动 EmbeddedSolr 并使用它来执行分片查询
    • Solr 将查询所有分片并合并结果,如果您需要限制每个分片的查询时间,它还提供超时

即使我上面说了这么多,我也不相信 Solr 非常适合这个。Solr 不太适合搜索不断变化的索引,而且如果您主要通过 ID 搜索而不需要搜索引擎。

对于我们的项目,我们基本上自己实现了所有的索引构建、负载平衡和查询引擎,并且主要使用 Solr 作为存储。但是当分片不稳定且性能不佳时,我们已经开始使用 Solr ,我不确定它今天的状态。

最后一点,如果我今天从头开始构建这个系统,而没有过去 4 年所做的所有工作,我建议使用缓存来存储当前在线的所有用户(比如memcachedredis),并且在请求时我会只需遍历所有这些并根据标准过滤掉。按条件过滤可以独立缓存并增量更新,如果匹配逻辑非常简单,迭代超过 5000 条记录也不一定非常耗时。

于 2013-05-06T09:14:40.943 回答
2

任何强大的解决方案都将包括使您的数据接近 SOLR(批处理)并在内部使用它。在搜索期间不运行非常大的请求,这是低延迟的事情。您应该开发自己的过滤器;过滤器会不时(比如每分钟)缓存一次在线用户数据。如果数据变化非常频繁,请考虑实施 PostFilter。

您可以在此处找到过滤器实现的一个很好的示例: http ://searchhub.org/2012/02/22/custom-security-filtering-in-solr/

于 2013-05-06T05:56:01.127 回答
0

一种解决方案可以在 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"

您现在可以频繁更新二级索引(以秒为单位)并使其与您拥有的表保持同步,以存储在线用户。

注意:这个二级索引即使经常更新,也不会降低任何性能,只要我们进行必要的调整,比如在增量导入期间使用适当的查询等。

您现在可以在这两个索引的 ID 字段上执行Solr 连接,以实现您想要的。这是有关如何在索引/ Solr 核心之间执行 Solr 连接的链接。

于 2013-05-07T05:57:11.527 回答