Solr4.8.0源码分析(14)之SolrCloud索引深入(1)
Solr4.8.0源码分析(14) 之 SolrCloud索引深入(1)
上一章节《Solr In Action 笔记(4) 之 SolrCloud分布式索引基础》简要学习了SolrCloud的索引过程,本节开始将通过阅读源码来深入学习下SolrCloud的索引过程。
1. SolrCloud的索引过程流程图
这里借用下《solrCloud Update Request Handling 更新索引流程》流程图:

由上图可以看出,SolrCloud的索引过程主要通过一个索引链过程来实现的,那么本节主要讲述下索引链以及DistributedUpdateProcessor这个过程。
2. SolrCloud update索引链
- SolrCloud的Update索引链的类是UpdateRequestProcessorChain,这个类在Solr初始化的时候就会进行定义。
- SolrCloud的Update索引链的组成可以通过solrconfig.xml进行自定义,比较灵活,例如:
<updateRequestProcessorChain name="key" default="true">
<processor class="package.Class1" />
<processor class="package.Class2" >
<str name="someInitParam1">value</str>
<int name="someInitParam2">42</int>
</processor>
<processor class="solr.LogUpdateProcessorFactory" >
<int name="maxNumToLog">100</int>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
- 如果未自定义UpdateRequestProcessorChain,那么Solr就默认以下三个过程组成索引链,依次如下:
LogUpdateProcessorFactory, 它对应的处理过程为LogUpdateProcessor , 主要负责日志的记录;
DistributedUpdateProcessorFactory, 它对应的处理过程为DistributedUpdateProcessor ,主要负责对version的处理以及request的分发;
RunUpdateProcessorFactory, 它对应的处理过程为DirectUpdateHandler2 ,主要负责将记录add进本shard的lucene中;
- 如果最后一个索引链包含了RunUpdateProcessorFactory,但是没有包含DistributedUpdateProcessorFactory,那么Solr会在索引链init的时候自动在RunUpdateProcessorFactory前面加入DistributedUpdateProcessorFactory;
- 每一次update操作,都会重新创建一个索引链,即createProcessor,然后依次进行下去;
- update操作包含add,delete,commit,所以上述UpdateProcessor都会分别包含processAdd,processDelete,processCommit,依次可以细分成add 索引链,delete索引链,commit索引链。
明白了以上几点,那么开始学习索引链的源码
- 首先来查看索引链的init代码,UpdateRequestProcessorChain.init()在初始化SolrCore的时候就调用了
public void init(PluginInfo info) {
final String infomsg = "updateRequestProcessorChain \"" +
(null != info.name ? info.name : "") + "\"" +
(info.isDefault() ? " (default)" : "");
log.info("creating " + infomsg);
// wrap in an ArrayList so we know we know we can do fast index lookups
// and that add(int,Object) is supported
//从solrcore获取索引链的成员,存放成列表形式。索引链在Solrconfig.xml中是以插件的形式加入的
List<UpdateRequestProcessorFactory> list = new ArrayList
(solrCore.initPlugins(info.getChildren("processor"),UpdateRequestProcessorFactory.class,null));
if(list.isEmpty()){
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
infomsg + " require at least one processor");
}
int numDistrib = 0;
int runIndex = -1;
// hi->lo incase multiple run instances, add before first one
// (no idea why someone might use multiple run instances, but just in case)
//从后往前遍历索引链列表,寻找DistributingUpdateProcessorFactory和RunUpdateProcessorFactory
for (int i = list.size()-1; 0 <= i; i--) {
UpdateRequestProcessorFactory factory = list.get(i);
if (factory instanceof DistributingUpdateProcessorFactory) {
numDistrib++; //DistributingUpdateProcessorFactory的个数不能超过1
}
if (factory instanceof RunUpdateProcessorFactory) {
runIndex = i; //RunUpdateProcessorFactory的编号
}
}
if (1 < numDistrib) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
infomsg + " may not contain more then one " +
"instance of DistributingUpdateProcessorFactory");
}
//如果存在RunUpdateProcessorFactory且没有DistributingUpdateProcessorFactory,
//那么会在RunUpdateProcessorFactory之前加入DistributingUpdateProcessorFactory
if (0 <= runIndex && 0 == numDistrib) {
// by default, add distrib processor immediately before run
DistributedUpdateProcessorFactory distrib
= new DistributedUpdateProcessorFactory();
distrib.init(new NamedList());
list.add(runIndex, distrib);
log.info("inserting DistributedUpdateProcessorFactory into " + infomsg);
}
chain = list.toArray(new UpdateRequestProcessorFactory[list.size()]);
}
- 每当有update请求时候就会触发索引链的创建,UpdateRequestProcessorChain.createProcessor。
public UpdateRequestProcessor createProcessor(SolrQueryRequest req,
SolrQueryResponse rsp)
{
UpdateRequestProcessor processor = null;
UpdateRequestProcessor last = null;
//获取distribPhase 是否需要跳过DistributingUpdateProcessorFactory前面那一过程(即LogUpdateProcessor),该参数不是由客户端生成
final String distribPhase = req.getParams().get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM);
final boolean skipToDistrib = distribPhase != null;
boolean afterDistrib = true; // we iterate backwards, so true to start
//从后往前组件索引链即
//LogUpdateProcessor.next = DistributedUpdateProcessor
//DistributedUpdateProcessor.next = DirectUpdateHandler2
//DirectUpdateHandler2.next = null
for (int i = chain.length-1; i>=0; i--) {
UpdateRequestProcessorFactory factory = chain[i]; if (skipToDistrib) {
if (afterDistrib) {
// 跳过DistributingUpdateProcessorFactory前面的索引链过程
if (factory instanceof DistributingUpdateProcessorFactory) {
afterDistrib = false;
}
} else if (!(factory instanceof UpdateRequestProcessorFactory.RunAlways)) {
// skip anything that doesn't have the marker interface
continue;
}
}
//创建UpdateRequestProcessorFactory对应的UpdateProcessor,并进行连接
processor = factory.getInstance(req, rsp, last);
last = processor == null ? last : processor;
} return last;
}
- 在UpdateRequestProcessorChain.createProcessor会调用UpdateRequestProcessorFactory的getInstance创建对应的updateProcessor,
LogUpdateProcessor
public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) {
return LogUpdateProcessor.log.isInfoEnabled() ? new LogUpdateProcessor(req, rsp, this, next) : null;
}
- DistributedUpdateProcessor
public DistributedUpdateProcessor getInstance(SolrQueryRequest req,
SolrQueryResponse rsp, UpdateRequestProcessor next) { return new DistributedUpdateProcessor(req, rsp, next);
}
RunUpdateProcessorFactory
public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next)
{
return new RunUpdateProcessor(req, next);
}
总结:本节主要学习了SolrCloud分布式索引的整体流程,以及SolrCloud建索引时候索引链的情况,下一节将详细介绍索引链的具体过程。
Solr4.8.0源码分析(14)之SolrCloud索引深入(1)的更多相关文章
- Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2)
Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2) 上一节主要介绍了SolrCloud分布式索引的整体流程图以及索引链的实现,那么本节开始将分别介绍三个索引过程即LogUpdat ...
- Solr4.8.0源码分析(17)之SolrCloud索引深入(4)
Solr4.8.0源码分析(17)之SolrCloud索引深入(4) 前面几节以add为例已经介绍了solrcloud索引链建索引的三步过程,delete以及deletebyquery跟add过程大同 ...
- Solr4.8.0源码分析(16)之SolrCloud索引深入(3)
Solr4.8.0源码分析(16)之SolrCloud索引深入(3) 前面两节学习了SolrCloud索引过程以及索引链的前两步,LogUpdateProcessorFactory和Distribut ...
- Solr4.8.0源码分析(22)之SolrCloud的Recovery策略(三)
Solr4.8.0源码分析(22)之SolrCloud的Recovery策略(三) 本文是SolrCloud的Recovery策略系列的第三篇文章,前面两篇主要介绍了Recovery的总体流程,以及P ...
- Solr4.8.0源码分析(20)之SolrCloud的Recovery策略(一)
Solr4.8.0源码分析(20)之SolrCloud的Recovery策略(一) 题记: 我们在使用SolrCloud中会经常发现会有备份的shard出现状态Recoverying,这就表明Solr ...
- Solr4.8.0源码分析(24)之SolrCloud的Recovery策略(五)
Solr4.8.0源码分析(24)之SolrCloud的Recovery策略(五) 题记:关于SolrCloud的Recovery策略已经写了四篇了,这篇应该是系统介绍Recovery策略的最后一篇了 ...
- Solr4.8.0源码分析(25)之SolrCloud的Split流程
Solr4.8.0源码分析(25)之SolrCloud的Split流程(一) 题记:昨天有位网友问我SolrCloud的split的机制是如何的,这个还真不知道,所以今天抽空去看了Split的原理,大 ...
- Solr4.8.0源码分析(23)之SolrCloud的Recovery策略(四)
Solr4.8.0源码分析(23)之SolrCloud的Recovery策略(四) 题记:本来计划的SolrCloud的Recovery策略的文章是3篇的,但是没想到Recovery的内容蛮多的,前面 ...
- Solr4.8.0源码分析(21)之SolrCloud的Recovery策略(二)
Solr4.8.0源码分析(21)之SolrCloud的Recovery策略(二) 题记: 前文<Solr4.8.0源码分析(20)之SolrCloud的Recovery策略(一)>中提 ...
随机推荐
- angularJS 服务三
路由 一 简介 1.路由机制 为了实现无刷新的视图切换,我们通常会用ajax请求从后台取数据,然后套上HTML模板渲染在页面上,然而ajax的一个致命缺点就是导致浏览器后退按钮失效,尽管我们可以在页面 ...
- Greenplum 数据库架构分析
Greenplum 数据库是最先进的分布式开源数据库技术,主要用来处理大规模的数据分析任务,包括数据仓库.商务智能(OLAP)和数据挖掘等.自2015年10月正式开源以来,受到国内外业内人士的广泛关注 ...
- SQLServer中使用索引视图(物化视图)
物化视图:以前用的普通的视图,普通视图就是一段逻辑语句,对性能没有任何的提升,也不能创建索引,而物化视图会把视图里查询出来的数据在数据库上建立快照,它和物理表一样,可以创建 索引,主键约束等等,性能会 ...
- Win7下Qt5.2中使用OpenGL的glu函数库无法使用的解决方案
最近在Window7使用Qt5.2学习OpenGL时,出现了以OpenGL中glu开头的函数库无法使用的错误,例如: 'gluPerspective' was not declared ...
- [转] 【开源访谈】Muduo 作者陈硕访谈实录
关于开源访谈 开源访谈是开源中国推出的一系列针对国内优秀开源软件作者的访谈,以文字的方式记录并传播.我们希望开源访谈能全面的展现国内开源软件.开源软件作者的现状,着实推动国内开源软件的应用与发展. [ ...
- Java基础知识强化之集合框架笔记08:Collection集合自定义对象并遍历案例(使用迭代器)
1. Collection集合自定义对象并遍历案例(使用迭代器) (1)首先定义一个Student.java,如下: package com.himi.collectionIterator; publ ...
- SimpleDateFormat使用简析
title: SimpleDateFormat使用简析 date: 2016-07-11 11:48:20 tags: Java SimpleDateFormat --- [转载自博客:http:// ...
- vsftp配置主动模式和被动模式
配置文件:/etc/vsftpd/vsftpd.conf 主动模式配置方法: 主动式连接使用的数据通道 connect_from_port_20=YES 支持数据流的被动式连接模式 pasv_enab ...
- codevs3304水果姐逛水果街
/* 线段树开到*4 *4 *4 *4 ! 维护 4个值 区间最大值 区间最小值 从左往右跑最大收益 从右往左跑最大收益 */ #include<iostream> #include< ...
- 设计模式UML图
1.简单工厂模式 2.工厂模式 工厂模式与简单工厂模式的不同在于,每个操作类都有自己的工厂,而且把逻辑判断交给了客户端,而简单工厂的逻辑判断在工厂类里边,当增加新的操作类时,简单工厂需要修改工厂类,而 ...