Solr/SolrCloud Faceting细节三则

来源:互联网 发布:linux 添加epel源 编辑:程序博客网 时间:2024/05/21 11:48

我们把Solr当数据仓库用了,常常用到查询统计即Facet。因此,对Facet接触挺多的,它实在是一个很不错的东西。对FacetComponent也有好多东西想分享,但都是找不到一个合适的角度来写,这已是第三稿,希望能写清晰而又简洁。OK,开始吧。

如果你已经知道分布式统计天生自带Bug的,那我们继续往下,否则请略过吧。

我们只考虑facet.sort=count的情况,Faceting为了尽可能减少误差,做了以下两件事。

  1. 加大Slave节点返回的结果集,使得TopK尽可能落在TopN结果集里。当N趋向结果集大小时,误差可以消除。
  2. 使得TopK里的统计完全准确。即当每个分片的TopN都大于等于m,若任意一个Term TA在其中Shard的数量为m+1,在其它分片的数据小于m。此时其它所有分片中都不会统计到Term TA的数量。所有需要做二次统计了,统计其它分片的Term在自己分片的数量,然后再合并再取TopK。

再说回第一件事。Faceting提供两个参数来调整每个Shard返回的数据集大小。分别是

facet.overrequest.count (Advanced) A number of documents, beyond the effective facet.limit to request from each shard in a distributed search facet.overrequest.ratio (Advanced) A multiplier of the effective facet.limit to request from each shard in a distributed search

每个分片最终返回的结果集大小由于这个两个参数同共决定,即是 facet.overrequest.count+facet.overrequest.ratio*facet.limit。默认情况是 K = 10 + 100 * 1.5 = 160

还有一个小细节,顺道讲一下。Faceting的ShardReqeust由QueryComponent发出的,同时与其它组件共用结果集。对了为什么Group与不是与QueryComponent共存呢?因为Group根本就不是一个组件,它只是QueryComponent的一种形式。

最后,我们知道,启用什么组件或不启用什么组件都是由参数控制的,子请求也是一样。
另一方面,SolrCloud的子请求分两个维度,阶段(Stage)和意途(Purpose)。一个阶段可以有多个意途,意途即是涉及的SearchComponent,Stage的话主要由SearchHandler控制。

同一阶段的请求可以由合为一个ShardRequest由SearchHandler发出。

public void addRequest(SearchComponent me, ShardRequest sreq) {    outgoing.add(sreq);    sreq.rb = this;    if ((sreq.purpose & ShardRequest.PURPOSE_PRIVATE) == 0) {        // if this isn't a private request, let other components modify it.        for (SearchComponent component : components) {            if (component != me) {                component.modifyRequest(this, me, sreq); // 各组件对相关请求参数进行改写            }        }    }}
0 0
原创粉丝点击