`
san_yun
  • 浏览: 2655646 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

SolrCore查询过程源码分析

    博客分类:
  • solr
 
阅读更多

一.环境启动代码

SolrResourceLoader.SetSolrHome("/duitang/dist/app/branches/mdrill/trunk/adhoc-core/solr");
SolrResourceLoader.SetSchemaHome("/home/taobao/solr/schema");

ShardPartion.base = "/group/tbdp-etao-adhoc/p4padhoc/tabletest"; //必须的,如果不配置会有异常,SolrCore中会使用ShardPartion.getHdfsRealtimePath
ShardPartion.taskIndex = 1;
ShardPartion.index = IndexUtils.getHdfsForder(1);

String hdfsconf = "/duitang/dist/sys/hadoop-1.2.1/conf/"; //必须的,如果不配置会有异常,ReadOnlyDirectory.getConf()
HadoopUtil.setHdfsConfDir(hdfsconf);

JettySolrRunner jetty = new JettySolrRunner("/solr", 1210);
jetty.start();
while (true)
{
	Thread.sleep(1000);
}

 

二.启动之后通过URL测试

http://localhost:1210/solr/select?q=*:*&indexpartion=20111014

 

三.查询入口SolrDispatchFilter

入口在SolrDispatchFilter中,通过拦截请求中的select来加载对应的requestHandler.代码如下:

 

init():
	CoreContainer.Initializer init = new CoreContainer.Initializer();
	CoreContainer cores = init.initialize();
	core = cores.getCore("");

doFilter():
	final SolrConfig config = core.getSolrConfig();
	SolrRequestParsers parser = new SolrRequestParsers(config);
	SolrQueryRequest solrReq = parser.parse( core, "select", httpServletRequest)
	SolrRequestHandler handler = core.getRequestHandler(null)

	SolrQueryResponse solrRsp = new SolrQueryResponse();
	solrReq.getContext().put( "webapp", req.getContextPath() );
	solrReq.getCore().execute( handler, solrReq, solrRsp );

 

 

四.核心方法SolrCore.execute()

入口SolrCore.execute(),前面都是web请求忽略掉。

SolrCore.execute(SolrRequestHandler handler, SolrQueryRequest req, SolrQueryResponse rsp)执行过程:

SolrCore.execute(SolrRequestHandler handler, SolrQueryRequest req, SolrQueryResponse rsp)
-->handler.handleRequest(req, rsp);
-->setResponseHeaderValues(handler, req, rsp);

 

 

SolrCore实际调用的是SearchHandler.handleRequest(),SearchHandler继承于RequestHandlerBase,覆盖了handleRequestBody(),调用关系如下:

-->RequestHandlerBase.handleRequest(SolrQueryRequest req, SolrQueryResponse rsp)
	-->SearchHandler.handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)

 

SearchHandler.handleRequestBody的实现比较复杂,如果shards不为null,会尝试请求各shards然后对结果合并。这里先看shards为null的情况:

-->QueryComponent.process(ResponseBuilder rb)
	-->SolrIndexSearcher searcher = rb.req.getSearcher();
	-->searcher.search(result,cmd);
-->FacetComponent.process(ResponseBuilder rb)

 req是SolrQueryRequest类型,实际是SolrQueryRequestBase实例,看看其getSearcher()实现方法。

1.SolrQueryRequestBase.getSearcher()
-->String partion=this.getParams().get(CommonParams.PARTION,"default");
-->SolrCore.getSearcher(partion,false,false,higohb);

2.SolrCore.getSearcher(String partion, boolean mdirs, boolean isclearCache, boolean ishb
-->String partionKey=this.corename+"@"+partion+"@"+SolrResourceLoader.getCacheFlushKey(p);
-->SolrCore.getSearcherByPath(p,partionKey, f.getAbsolutePath(), mdirs, isclearCache, ishb)

3.SolrCore.getSearcherByPath(PartionKey p, String partionKey, String path):

if partion.name == "default":
	//初始化IndexReader
	RAMDirectory rd=new RAMDirectory();
	rd.setCore(this,p);
	IndexWriter writer=new IndexWriter(rd, null,new KeepOnlyLastCommitDeletionPolicy(), MaxFieldLength.UNLIMITED);
	writer.setMergeFactor(10);
	writer.setUseCompoundFile(false);
	writer.close();	
	reader=IndexReader.open(rd);

	//初始化SolrIndexSearcher
	SolrIndexSearcher newSearcher = new SolrIndexSearcher(this,	schema, "partion_" + partionKey, reader, true);
	newSearcher.setPartionCacheKey(p);
	newSearcher.setFieldcacheDir(fieldcacheDir);
	newSearcher.setPartionKey(partionKey);
	rtn = newHolderPartion(newSearcher);

	searchCache.put(partionKey, rtn);

else:
	//初始化IndexReader
	MdrillDirectory rtdir = new ReadOnlyDirectory(f, HadoopUtil.hadoopConfDir, ShardPartion.getHdfsRealtimePath(p.tablename, p.partion));
	rtdir.getForSearch()
	fs.mkdirs(new Path(hdfsPath).getParent());	//hdfs_path-->	/group/.../20110111
	path.mkdirs();								//local_path-->	/duitang/.../20110111
	File links=new File(path,"indexLinks");
	while f=links.readline():
		FSDirectory d=LinkFSDirectory.open(f);	
		DirectoryInfo info=new DirectoryInfo();
		info.d=d;
		info.tp=DirectoryInfo.DirTpe.file;
		diskDirector.put(f, info);
	
	IndexReader[] r = new IndexReader[diskDirector.size()];
	for	directory in diskDirector.values:
		r[i] = IndexReader.open(directory)
	
	if r.length==1:
		reader = r[0]
	else:
		reader = new MultiReader(r, true);

	//初始化SolrIndexSearcher(同上)

 可以看到如果indexpartion没有传递默认是default,开辟空的内存,这时没有索引被读取。当有indexpartion时会读取indexpartion目录下的indexLinks。

比如/duitang/dist/app/branches/mdrill/trunk/adhoc-core/solr/data/20110111/indexLinks。indexLinks会记录索引存放的路径,然后分别加载,最后通过MultiReader实现。

 

索引测试路径:

local_path:/duitang/dist/app/branches/mdrill/trunk/adhoc-core/solr/data/20110111

hdfs_path:/group/tbdp-etao-adhoc/p4padhoc/tabletest/index/20110111/part-00001

 

 

最后补充solr容器的关闭,下次分析

"Shutdown" prio=10 tid=0x0000000040e97000 nid=0x7b1d at breakpoint[0x00007f7af4772000]
   java.lang.Thread.State: RUNNABLE
	at org.apache.solr.core.SolrCore.close(SolrCore.java:473)
	at org.apache.solr.core.CoreContainer.shutdown(CoreContainer.java:202)
	- locked <0x00000000e4288b70> (a java.util.LinkedHashMap)
	at org.apache.solr.servlet.SolrDispatchFilter.destroy(SolrDispatchFilter.java:104)
	at org.mortbay.jetty.servlet.FilterHolder.destroyInstance(FilterHolder.java:127)
	at org.mortbay.jetty.servlet.FilterHolder.doStop(FilterHolder.java:107)
	at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:76)
	- locked <0x00000000e4280868> (a java.lang.Object)
	at org.mortbay.jetty.servlet.ServletHandler.doStop(ServletHandler.java:176)
	- locked <0x00000000e4280768> (a org.mortbay.jetty.servlet.ServletHandler)
	at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:76)
	- locked <0x00000000e42807d8> (a java.lang.Object)
	at org.mortbay.jetty.handler.HandlerWrapper.doStop(HandlerWrapper.java:142)
	at org.mortbay.jetty.servlet.SessionHandler.doStop(SessionHandler.java:125)
	at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:76)
	- locked <0x00000000e4280758> (a java.lang.Object)
	at org.mortbay.jetty.handler.HandlerWrapper.doStop(HandlerWrapper.java:142)
	at org.mortbay.jetty.handler.ContextHandler.doStop(ContextHandler.java:592)
	at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:76)
	- locked <0x00000000e4280708> (a java.lang.Object)
	at org.mortbay.jetty.handler.HandlerWrapper.doStop(HandlerWrapper.java:142)
	at org.mortbay.jetty.Server.doStop(Server.java:283)
	at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:76)
	- locked <0x00000000e4280658> (a java.lang.Object)
	at org.mortbay.jetty.Server$ShutdownHookThread.run(Server.java:561)

  

补充SolrCore初始化的stacktrace,下次分析

"2010005445@qtp-385415131-0" daemon prio=10 tid=0x0000000041df3800 nid=0x440c at breakpoint[0x00007f2686060000]
   java.lang.Thread.State: RUNNABLE
	at org.apache.lucene.index.SegmentInfos.read(SegmentInfos.java:278)
	at org.apache.lucene.index.DirectoryReader$1.doBody(DirectoryReader.java:85)
	at org.apache.lucene.index.SegmentInfos$FindSegmentsFile.run(SegmentInfos.java:808)
	at org.apache.lucene.index.DirectoryReader.open(DirectoryReader.java:91)
	at org.apache.lucene.index.IndexReader.open(IndexReader.java:509)
	at org.apache.lucene.index.IndexReader.open(IndexReader.java:369)
	at org.apache.lucene.search.IndexSearcher.<init>(IndexSearcher.java:110)
	at org.apache.lucene.search.spell.SpellChecker.createSearcher(SpellChecker.java:752)
	at org.apache.lucene.search.spell.SpellChecker.swapSearcher(SpellChecker.java:729)
	at org.apache.lucene.search.spell.SpellChecker.setSpellIndex(SpellChecker.java:174)
	- locked <0x00000000e25f3818> (a java.lang.Object)
	at org.apache.lucene.search.spell.SpellChecker.<init>(SpellChecker.java:149)
	at org.apache.solr.spelling.AbstractLuceneSpellChecker.init(AbstractLuceneSpellChecker.java:127)
	at org.apache.solr.spelling.IndexBasedSpellChecker.init(IndexBasedSpellChecker.java:55)
	at org.apache.solr.handler.component.SpellCheckComponent.inform(SpellCheckComponent.java:598)
	at org.apache.solr.core.SolrResourceLoader.inform(SolrResourceLoader.java:523)
	at org.apache.solr.core.SolrCore.<init>(SolrCore.java:385)
	at org.apache.solr.core.CoreContainer.createCore(CoreContainer.java:180)
	at org.apache.solr.core.CoreContainer.getCore(CoreContainer.java:151)
	- locked <0x00000000e2e23bf0> (a java.util.LinkedHashMap)
	at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:148)

 

分享到:
评论

相关推荐

    solr 4.10源码

    - **分析查询机制**:深入`QueryComponent`和`SearchComponent`,研究查询优化和结果处理。 - **测试代码**:通过`src/test`下的单元测试,了解功能实现和边界情况。 5. **开发与调试** - **构建Solr**:使用...

    match-query-parser,在solr中使用不同的查询时间分析器搜索单个字段.zip

    在Solr中,查询解析是搜索过程中的关键环节,它决定了如何将用户的输入转换为对索引的精确查询。这篇博文的重点是`match-query-parser`,这是一个特殊的查询时间分析器,允许我们在特定字段上执行更精确的查询。 在...

    solr(solr-9.0.0-src.tgz)源码

    - `SolrCore`: 代表Solr的单一索引实例,包含了索引、查询和其他核心功能。 - `SolrRequestHandler`: 处理Solr请求的接口,用于定义不同的查询和更新处理逻辑。 - `UpdateRequestProcessorChain`: 更新请求处理链...

    solr1.4教程

    - Core:每个核心包含索引目录、配置文件和SolrCore对象。 - Query解析与处理:包括QueryParser、QParserPlugin等,负责解析查询语句并生成查询对象。 - HighLighting(高亮显示):提供文本片段的高亮功能。 - ...

    Apache Solr 架构分析内部设计篇PDF

    ### Apache Solr 架构分析内部设计篇 #### 一、引言 随着大数据时代的到来,搜索引擎技术在各个领域中的应用越来越广泛。Apache Solr作为一款高性能、可伸缩的企业级搜索平台,凭借其强大的功能及灵活性,在众多...

    solr-parent.rar

    编译过程通常包括解压源码、设置环境变量、运行构建命令,然后生成可部署的 Solr 服务器和客户端库。 5. **扩展和自定义**: 通过源码,开发者可以了解 Solr 插件系统,比如自定义请求处理器、查询解析器、过滤器...

    solr-4.10.3.zip

    在这个过程中,Solr引入了新的特性和改进,同时可能对旧的API和配置文件格式进行了调整,以提高性能和用户体验。4.10.3作为4.x系列的一个稳定版本,它包含了从4.0到4.9一系列更新后的优化,为用户提供了一个可靠的...

    solr教材-PDF版

    - **3.6.4 Solr分词器、过滤器、分析器**:解释如何使用不同的分词器、过滤器和分析器来处理索引数据。 - **3.6.5 Solr高亮使用**:指导如何在搜索结果中突出显示关键词。 #### 四、SolrJ的用法 **4.1 搜索接口的...

    tomcat下部署solr

    总结来说,"tomcat下部署solr"是一个涉及Java Web环境设置、Solr安装、配置和数据处理的过程。在实际操作中,需要对Java、Tomcat和Solr有一定的了解,并且能够灵活配置`schema.xml`来满足特定的搜索需求。

    solr 企业搜索引擎教程

    - **多核配置方法**:在Solr中创建多个独立的核心(core),每个核心可以看作是独立的索引。 - **多核优势**:提高系统的并行处理能力和资源隔离性。 #### 10. Solr 的配置文件说明 - **schema.xml**:定义索引结构...

    solr 的使用及安装

    本文将深入讲解 Solr 的使用及安装过程。 一、Solr 简介 Solr 基于 Lucene 库,提供了一个高度可配置和可扩展的平台,用于处理和索引大量数据,支持多种数据源,如文件、数据库等。其主要特性包括: 1. **全文搜索...

    SolrDispatchFilter对这个过滤器的进行一个全面解析.rar

    2. **多核心处理**:在多核心环境下,SolrDispatchFilter能够处理多个独立的SolrCore,根据请求的上下文选择合适的Core来执行操作。 3. **请求分发**:如果请求涉及到分布式搜索,SolrDispatchFilter会负责将请求...

    solr的使用

    Solr是Apache软件基金会的一个开源项目,是一款强大的全文搜索引擎服务器,它提供了高性能、可扩展的搜索和分析功能。本文将围绕“Solr的使用”这一主题,深入探讨Solr的基本概念、安装配置、索引创建与管理、查询及...

    solr搭建搜索

    标签中提到了“源码”和“工具”,这暗示了Solr的搭建可能涉及到查看源代码以理解其工作原理,以及使用某些工具辅助搭建过程。例如,开发者可能需要阅读Solr的Java源码来定制功能,或者使用像是Postman这样的工具来...

    开源企业搜索引擎SOLR的 应用教程

    - `org.apache.solr.core`:核心组件,如SolrCore。 - `org.apache.solr.update`:索引更新相关的类。 - `org.apache.solr.search`:搜索相关的类。 - `org.apache.solr.handler`:处理请求的组件。 **1.5 版本...

    跟益达学Solr5之从MySQL数据库导入数据并索引

    这个压缩包文件可能包含了Solr的扩展模块或特定配置,例如额外的分析器、查询处理器或插件,这些都可以增强Solr的功能和性能。 总结,通过学习这篇文章,我们可以掌握如何利用Solr 5与MySQL的集成,有效地将数据库...

    Solr初体验

    它由多个独立的 Solr 实例(称为 SolrCore)组成,每个实例可以独立处理搜索请求,并通过 SolrCloud 进行集群管理。 1.2 主要功能 - 全文搜索:Solr 支持对文本进行高效的全文搜索,包括模糊搜索、短语搜索等。 - ...

    利用Solr搭建你的搜索引擎

    标题中的“利用Solr搭建你的搜索引擎”意味着我们将探讨Apache Solr这一开源全文搜索平台的搭建过程。Solr是基于Lucene库的,提供了一个高效、可扩展的搜索和导航功能,广泛应用于各种企业的数据检索需求。 Solr的...

Global site tag (gtag.js) - Google Analytics