Solr/SolrCloud Faceting细节三则

我们把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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值