Solr的底层是基于Lucene索引结构,Lucene是一套信息检索工具包,但并不包含搜索引擎系统,它包含了索引结构、读写索引工具、相关性工具、排序等功能。所以,只要是相同版本的Solr和Lucene其用的索引文件是兼容的,solrconfig.xml有使用Lucene的版本信息。如果我们直接利用Lucene来写Solr的索引目录,降低网络开销,并且减去Solr除了索引以外功能做的额外开销,从提升建索引的角度,有不错的提升。
如上图所示:
1、客户端调用Lucene的API直接在本地的Solr的core的目录建索引。(Collection的一个shard的副本其实就是一个core文件)
2、多个客户端,每个客户端对应一个shard副本,注意这里是一个shard只有一个副本的情况下,如果多个副本需要注意副本之间的数据同步的问题。
在实际的场景中,为了防止多线程操作同一个文件带来的问题,Lucene可以在其他目录建立索引,然后通过定期合并索引文件的方式,加载到solr的shard中。流程如下图所示:
过程说明:
1、 客户端程序调用lucene的API进行写索引。
2、 索引写到特定的目录下。
3、 调用solr的索引合并的HTTP接口,进行索引合并。
4、 调用HTTP的合并结构后会将Lucene新建的索引目录合并到Solr的索引中去。
注意:
1、 这种合并的URL如下:http://x.x.x.x:port/solr/admin/cores?action=mergeindexes&core=collection_shard1_replica1&indexDir=/parkfs01/aus/soft/luncenetmp/0
2、 合并后的索引不是可见的,需要重新加载索引,或者重新做提交,提交时候需要打开搜索器使索引可见:http://x.x.x.x:port/ solr/collection/update?commit=true&openSearcher=true这里的collection要改成具体的collection名字。在单节点时候需要重新加载整个core,这个耗时很大,单节点仅仅提交,仍然搜索不到新添加的文档。
有了上面的支撑,结合流程中比较耗时的操作,综合考虑,可以按照下图所示的架构来设计程序:
说明:
1、根据要求生成文档。
2、根据生成的文档列表生成可执行单元,可以执行单元的主要是创建IndexWriter和添加索引动作。
3、将可行对象发送给线程池执行。
4、执行完毕后将需要合并的索引目录和url发送到合并队列,合并队列数量达到一定数量后,执行合并索引动作和提交索引动作。
5、索引线程池存在建立一定数量索引后,会关闭原来的IndexWriter,从新创建的目录生成新的IndexWriter。
注意:
1、因为IndexWriter是线程安全的,所以线程池可以共同操作同一个IndexWriter对象。
2、在合并索引后,不能立刻删除目录,调用SOLR的合并索引的URL返回后,后台也有可能还在合并。
3、经过测试在一个索引文档286个字节条件下,solr6.0版本,速率大概在4.7W和5.1W之间浮动;一个报文2K的情况下,每秒大概有3.5W到4W之间。

本文介绍如何利用Lucene API直接构建Solr索引以提高效率,包括索引构建流程、合并机制及多线程处理策略。

2万+

被折叠的 条评论
为什么被折叠?



