Lucene&solr 4 实践(8)

简介: 假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。Lucene 5 有哪些点对大数据倒排索引和检索有优势 1.索引懒加载lazy加载,意味着按时间段或者其他分割的数据可以按需加载2.FST词典结构以及基于图的索引、查询,使得内存消耗更低3.异步合并,使得增量索引合并时的“索引整理”开销或者对查询影响更小4.commitpoint 视图下reader自动更新,使得大规模数据的虚拟分组、全量切换更加方便。

下面关于虚拟分组全量切换做一个文字说明。
对于solr3.X 2.X序列,虚拟分组全量的优势:使得全量切换可以分块实现,事先定义当前core有多少个虚拟子组,然后每个子组的去切换,从而全量在线切换开销大大降低。指导者 taobao sns架构师少昊!
对于solr4.X 5.X序列,暂时没有实现,不过基本流程和下面类似,不同点在reader视图更新上,细节也会发生不同,因为4.X 已经没有multiReader了。

实现基本流程和注意事项:
。预备知识
reader
关系SolrIndexSearcher-->SolrIndexReader-->MultiReader-->IndexReader
reader
关闭SolrIndexSearcher.close-->SolrIndexReade.close-->MultiReader for(;;) subReader.close
计数情况:solrCore.getSearcher() new新的searcher,然后调用IndexFactorynew IndexReader新打开readerreader计数++; 如果是先new底层reanernew的时候计数为1,然后由MultiReader封装的时候,计数又会+1;然后MultiReader里面如果closeSubReader的话,就关闭了,如果非closeSubReader,计数继续++

getSearcher
:通过getSearcher来打开新的索引视图和管理计算
 solrCore.getSearcher()
获取SolrIndexSearcher对象,同时根据参数执行new SolrIndexReader,并关闭SolrIndexSearcher,然后关闭SolrIndexReader
   Future[] waitSearcher = new Future[1];
   currentCore.getSearcher(true, false, waitSearcher);//
参数必须是true false
   if (waitSearcher != null && waitSearcher[0] != null) {
         try {
                waitSearcher[0].get();
         } catch (InterruptedException e1) {
                logger.error("InterruptExeption===> ", e1);
         } catch (ExecutionException e2) {
                  logger.error("ExecutionException===>", e2);
         }
    }

   MultiReader
的继承或者重写(由与包权限,需要自己将一些方法弄出来,内容一样权限打开而已)的时候,getSequentialSubReaders() 方法,只在需要显示控制路由的时候不返回Null,否则需要返回Null
   eg IndexRaderfactory
new IndexReader 里面 new SolrIndexReader 传入RealTimeMultiReader4VroutExtendRealTimeMultiReader4VroutExtend代表当前core管理的 多个虚拟子目录的Reader),此时RealTimeMultiReader4VroutExtend里面的getSequentialSubReaders务必返回null。返回Null表示这一层表示由显示控制路由信息。
   
RealTimeMultiReader4VroutExtend对于core这一层的最顶层reader,里面的每个子reader 就对于每个子目录。由于子目录是遍历查询,传入RealTimeMultiReader4VroutExtend的每个子目录RealTimeRamFlushMainReaders reader 也是一个MultiReader,此时MultiReader查询是遍历,getSequentialSubReaders 直接返回全部的subReaders ok

   
关于MultiReaderReopeninitalize 方法
   reopen
里面的默认参数closeSubReadersreader计数需要注意,initialize里面的参数是否closeSubReaders需要注意。eg 在索引提交或者索引切换的时候,由与多个子目录,每次重新getSearcher、重新new SolrIndexReadernew RealTimeMultiReader4VroutExtendnew 需要切换或者commitRealTimeRamFlushMainReaders ,而RealTimeRamFlushMainReaders里面只替换部分,遍历的时候其他的reader计数会递增,那么dec的时候需要while 循环来关,最后finally 关闭本地cache资源

。基于core的虚拟分组原理
   
就是将当前core虚拟分为多个子目录,每个子目录管理自己的主磁盘索引、内存索引、从磁盘索引、本地内存等。建索引的时候,根据id将数据路由到各子组。检索的时候,根据id将请求路由到对于子组。全量切换的时候,执行单个组的切换,从而内存最大开销多了一份:max(单组资源开销),比之前maxCore开销大大降低内存、磁盘负载。例如:原理core 100M,切换就额外100M,如果分为5组,每组25M(分组后额外的开销还是有的),切换就额外25M,总体150M,比200M省了50M
   
另外,通过自定义的reader,引入本地内存来管理固定部分的数据,并且采取一定压缩算法,从而使得大内存的gc问题得以解决。

。基于core虚拟分组工作关键流程
  (1) solrconfig.xml
中配置IndexReaderFactory
  (2)
在发生索引commit的时候,设置是否更新索引视图参数,接着通过SolrCoregetSearcher方法来间接地调用 IndexReaderFactorynew IndexReader方法来更新索引目录,从而使得新的索引可见。
  (3)
在发生索引core的子组切换的时候,设置那个子组需要切换的参数,接着通过SolrCoregetSearcher方法来间接地调用   IndexReaderFactorynew IndexReader方法来更新索引目录,从而使得新的索引可见。
  (4)
SolrIndexSearcher关闭的时候,调用close方法,间接调用reader.decRef,然后调用SolrIndexReader defRef方法里面的in.decRef,进入在IndexReaderFactory new SolrIndexReader中的参数reader里面,例如
RealTimeMultiReader4VroutExtend
decRef方法,在decRef 中之下doClose方法,RealTimeMultiReader4VroutExtenddoClose方法里面遍历关闭每个子目录
protected void doClose() throws IOException {
       // TODO Auto-generated method stub  
       for (int i = 0; i < subReaders.length; i++) {  
           //logger.warn("[lev1] doCloseSubDir="+i+",RefCount="+subReaders[i].getRefCount());  
           if (decrefOnClose[i]) {
               subReaders[i].decRef();
           } else {              
               subReaders[i].close();
           }
       }
   }
每个子目录对应RealTimeRamFlushMainReaders,进入RealTimeRamFlushMainReaders decRef方法里面。这里面根据遍历subReader decRef,进入最底层的 decRef 方法中,这个最底层的reader就是业务自定义、封装了本地cachereander。如果是遍历关闭某个子目录,而其他子目录会因为其他目录的关闭导致的new 新的引用,计数会增多。所以关闭的时候需要while来减少计数。

。基于core虚拟分组example
solrconfig.xml
配置
<indexReaderFactory name="IndexReaderFactory" class="com.taobao.terminator.core.realtime.vrout.RealTimeIndexReaderFactory4VroutExtend">
RealTimeIndexReaderFactory4VroutExten
里面间接地调用自定义的reader

SolrIndexSearcher--
SolrIndexReader(RealTimeMultiReader4VroutExtend)//

RealTimeMultiReader4VroutExtend
也是一个multiReadercore层的Reader抽象

RealTimeMultiReader4VroutExtend-->{RealTimeRamFlushMainReaders,RealTimeRamFlushMainReaders ,RealTimeRamFlushMainReaders..}
/
/
他的元素就是RealTimeRamFlushMainReaders 子目录的抽象

RealTimeRamFlushMainReaders-->{RealTimeIndexReader4VroutExtend,RealTimeIndexReader4VroutExtend,RealTimeIndexReader4VroutExtend ...}

//
他的元素就是RealTimeIndexReader4VroutExtend,对于自定义reader,也即子目录的具体reader

。基于core虚拟分组其他注意事项
由于SolrIndexSearcher对象是core层次的,查询又是路由到子目录的,从而各种默认绑定在SolrIndexSearchercache,特别是DocumentResultCache就失效了。例如 数据分2组,id=1 路由子目录1,返回id=1id=3id=5的文档,内部id号 分别是0,1,2,查询id=2,路由子目录2,返回id=2id=4id=6,内部id分别是0,1,2,此时如果docuementResultCache开启了,根据内部id号,获取的文档就不对了。
 
如果需要cache的话,需要在查询的时候传入路由信息,单独定义个cache配置到solrconfig中,然后处理cache的时候根据路由选择对应cache内容。因为实时、并且将core细分,cache的命中可能降低。cache的选择和位置,需要平衡。

目录
相关文章
|
6月前
|
索引
lucene入门使用
lucene入门使用
38 2
|
XML 存储 JSON
Solr学习总结
Solr学习总结
156 0
Solr学习总结
|
XML JSON 搜索推荐
和 Solr 对比|学习笔记
快速学习和 Solr 对比。
109 0
|
XML 存储 JSON
和 Solr 对比 | 学习笔记
快速学习和 Solr 对比
|
存储 搜索推荐 Java
全文搜索引擎 Lucene Solr ElasticSearch 关系?
全文搜索引擎是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
全文搜索引擎 Lucene Solr ElasticSearch 关系?
|
存储 SQL 编解码
Solr-lucene 使用案例大全
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。 本文sole lucene的使用案例汇总。
231 0
|
自然语言处理 索引
Lucene&solr 4 实践(3)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。本部分主要是针对FSA FST做前期知识储备和基本概念扫盲。FST是lucene4 solr4 的索引和查询的核心! 下面的内容来自多个出去,出去就不一一列举。
118 0
Lucene&solr 4 实践(3)
|
自然语言处理 Java API
Lucene&solr 4 实践(1)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。Solr&Lucene 4.0 好,很好,很强大。对于从lucene2.0 solr0.9 就关注,一直过来的人来讲, 4.X序列除了的架构、风格、API改变了很多很多,更重要的是业务的优化口子更多了,专业知识要求更高。整个架子的容量、包容性、以及适应信息检索的科研,直接上来demo运行easy、深入会很难。需要整理了解的知识点太多了。
108 0
|
自然语言处理 算法 Apache
Lucene&solr 4 实践(5)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。这部分先通透FST的原理和构造方法,方便理解lucene FST、Builder两个核心对象,从而彻底看清基于图的lucene4索引、查询的发展脉络。至于读懂后有神马用,自个琢磨啊! 看懂估计要死伤不少脑细胞哦!
239 0
|
编解码 缓存 自然语言处理
Lucene&Solr 4 实践(2)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。在第一部分,还不完善基础上,进入第二部分吧。结合源码来认识lucene! 重点是:从需求到方案到实践编码到结果、从原理到实现、从结构到细节、从总体认识到西部深入。
107 0