solr分布式搜索源码分析
2013-08-16 09:59
253 查看
基于solr4.4
分布式搜索的主控逻辑是在SearchHandler.handleRequestBody方法中实现的,参见distributed request分支
分布式搜索过程是分阶段stage的,stage的控制在每个componnet的distributedProcess方法中,每个stage的请求输出都会封装在outgoing.add(sreq)中。
component针对每个stage做相应的参数的设置和处理,并输出到outgoing中,在while循环中检测到outgoing有值,则代表需要对该请求,进行分布式的调用;
分布式调用会针对当前的stage提交每个shard的查询,并异步收集所有shard的返回结果。
每个stage计算完成后,对结果进行处理
for(SearchComponent c : components) {
c.handleResponses(rb, srsp.getShardRequest());
}
所有的stage都完成后,调用component.finishStage进行后续的处理
for(SearchComponent c : components) {
c.finishStage(rb);
}
stage主要分两个stage,为makeQuery和getFileds
makeQuery,给url带上查询参数fl=id,score根据情况是否会带,我们知道fl是代表只返回那些field,Solr会取schema配置文件的uniquerField,所以这次请求就只返回id的值。得到id值后,QueryComponent会合并id,如果不同的shard有相同的id,则会只取一个
getFileds,通过QueryComponent来封装请求参数,其中最关键的是封装ids参数,即根据上面请求得到的ids参数把他作为值放到url里,再一次发请求根据id来取对应的field
其实在这两个阶段之前,还有一个阶段是STAGE_PARSE_QUERY,在这个阶段可以计算分布式的idf,不过目前solr没有实现,而是默认每个shard只计算自己的idf,并不会计算全局的idf,在数据量较大的情况下,基于Shard层次的TF-IDF不会有太大的偏差,但是如果分布式索引非常不均衡,可能就要重视相关度的计算问题.
makeQuery stage完成后,对所有shards返回的docs进行mergeIds操作,mergeIds实现中会根据分页把doc放到优先级队列中,根据sort和score进行比较排序,获取当前页面的doc list,这里存在一个问题,优先级队列的size是start+rows,只返回rows大小的给客户端,不过需要对top的start+rows数量的doc进行排序,的对于翻页比较多的情况,代理节点内存的开销和排序计算的CPU开销都会比较大
比如
QueryComponent,
private void handleRegularResponses(ResponseBuilder rb, ShardRequest sreq) {
if ((sreq.purpose & ShardRequest.PURPOSE_GET_TOP_IDS) != 0) {
mergeIds(rb, sreq);
}
if ((sreq.purpose & ShardRequest.PURPOSE_GET_FIELDS) != 0) {
returnFields(rb, sreq);
}
}
分布式搜索的主控逻辑是在SearchHandler.handleRequestBody方法中实现的,参见distributed request分支
分布式搜索过程是分阶段stage的,stage的控制在每个componnet的distributedProcess方法中,每个stage的请求输出都会封装在outgoing.add(sreq)中。
component针对每个stage做相应的参数的设置和处理,并输出到outgoing中,在while循环中检测到outgoing有值,则代表需要对该请求,进行分布式的调用;
分布式调用会针对当前的stage提交每个shard的查询,并异步收集所有shard的返回结果。
每个stage计算完成后,对结果进行处理
for(SearchComponent c : components) {
c.handleResponses(rb, srsp.getShardRequest());
}
所有的stage都完成后,调用component.finishStage进行后续的处理
for(SearchComponent c : components) {
c.finishStage(rb);
}
stage主要分两个stage,为makeQuery和getFileds
makeQuery,给url带上查询参数fl=id,score根据情况是否会带,我们知道fl是代表只返回那些field,Solr会取schema配置文件的uniquerField,所以这次请求就只返回id的值。得到id值后,QueryComponent会合并id,如果不同的shard有相同的id,则会只取一个
getFileds,通过QueryComponent来封装请求参数,其中最关键的是封装ids参数,即根据上面请求得到的ids参数把他作为值放到url里,再一次发请求根据id来取对应的field
其实在这两个阶段之前,还有一个阶段是STAGE_PARSE_QUERY,在这个阶段可以计算分布式的idf,不过目前solr没有实现,而是默认每个shard只计算自己的idf,并不会计算全局的idf,在数据量较大的情况下,基于Shard层次的TF-IDF不会有太大的偏差,但是如果分布式索引非常不均衡,可能就要重视相关度的计算问题.
makeQuery stage完成后,对所有shards返回的docs进行mergeIds操作,mergeIds实现中会根据分页把doc放到优先级队列中,根据sort和score进行比较排序,获取当前页面的doc list,这里存在一个问题,优先级队列的size是start+rows,只返回rows大小的给客户端,不过需要对top的start+rows数量的doc进行排序,的对于翻页比较多的情况,代理节点内存的开销和排序计算的CPU开销都会比较大
比如
QueryComponent,
private void handleRegularResponses(ResponseBuilder rb, ShardRequest sreq) {
if ((sreq.purpose & ShardRequest.PURPOSE_GET_TOP_IDS) != 0) {
mergeIds(rb, sreq);
}
if ((sreq.purpose & ShardRequest.PURPOSE_GET_FIELDS) != 0) {
returnFields(rb, sreq);
}
}
相关文章推荐
- Solr1.4.0源码分析二 Solr分布式搜索中URL的正确用法和原理
- 分布式搜索Elasticsearch源码分析之二------索引过程源码概要分析
- Solr分布式搜索技术实现分析
- SOLR分布式搜索技术实现分析
- Solr分布式搜索技术实现分析
- 分布式搜索Elasticsearch源码分析之二------索引过程源码概要分析
- Solrflux源码分析-Sql Support within Solr-类Sql的solr搜索实现(2)
- Solr分布式搜索技术实现分析
- g729源码分析-5-基音周期搜索(下)
- 分布式事务 TCC-Transaction 源码分析 —— 事务恢复
- 支付宝资深架构师的分布式追踪 & APM 系统 SkyWalking 源码分析— DataCarrier 异步处理库
- solr的用分布式搜索(转)
- Solr4.8.0源码分析(8)之Lucene的索引文件(1)
- 分布式日志收集系统: Facebook Scribe之结构及源码分析
- 天网搜索TSE部分源码分析-url.cpp
- 基于Redis实现分布式锁,Redisson使用及源码分析
- solrCloud 4.7 分布式搜索重要bug
- solr源码分析--数据类型
- sphinx源码分析之搜索(search)
- php与memcached服务器交互的分布式实现源码分析[memcache版]