本文链接: http://quentinXXZ.iteye.com/blog/2153210
场景需求与分析
我们的做法,一般将索引构建大致分为两类操作,一为全量索引构建,二为增量索引构建。使用solr建索引,一般会在初始状态的时候,进行一次全量构建,根据当前数据源的整体数据生成一套完整索引,可提供服务,但为了保证索引数据的完整且最新,还需要增量索引,使得数据源的改变(包括记录的增加,修改,与删除)体现在这套索引之上。
在solr单core或者单collection的情况下,类似DataImportHandler之类的工具,都能提供这样全量与增量的索引方式。然而,对一套索引仅使用单core或者单collection的情况下,这种方式存在一种问题:索引上的错误累积。如果增量出错,或者增量的几条修改丢失,这样的错误就会一直在索引上累积。除非你删除这套索引,重新做全量,即re-indexing。这样势必就需要开发人员的人工参与与机器的停止维护。而我们有这种定期re-indexing的需求。
Solr Build search分离问题
要保证搜索引擎正常服务,同时又能做re-indexing。这就涉及到了build与search分离的情况。例如在cloud模式下,我们本来希望的状态是,每个分片shard的副本集中的leader在做全量的时候,只作索引的写,而不提供读服务,在完成索引全量写之后,同步给其它的replica。这样确定index构建速度,同时不给leader太大压力。当然这样有也问题,就是同步操作是集中进行的,这样会给网络带宽带来巨大压力。solr的做法不是这样的,在leader做写入时候,同时在提供search服务。可见solr并没有做到明显build search分离。这也是solr本身的一个问题。所以对re-indexing问题 的解决,本质上就是对build search分离问题的解决。
Solr standalone下的re-indexing的实现
为了实现单机形式下的读写分离,其实就是对不同core的分离。假设core名为 search,提供当前服务的索引,可以再新建一个空白的core, 名为search-rebuild,使用与serach相同schemal配置。需要re-index的时候,就可以这样做:
1、停止当前写往search的增量,search正常服务。
2、对search-rebuild进行全量索引构建。
3、完成search-rebuild全量索引后,做一次coreAdmin的SWAP操作,切换两个索引。
Url形式的api如下:
http://localhost:8983/solr/admin/cores?action=SWAP&core=search&other=search-rebuild
Swap所做的就是将两个core对应的名称做一下交换。也就是说,SWAP之后,search对应的索引为原来在search-rebuild建立的全新索引。而search-rebuild对应的索引为原来search的旧版索引。搜索客户端的搜索url无须修改,做到无缝切换。
4、继续对search(已经是新的索引)做增量。
Solr master/slave下的re-indexing的实现
Master/slave情况下,涉及到多台solr server,需要对多台solr server的索引做切换,会复杂得多。但最后发现,其实Master/slave下的re-indexing其实也可以通过与standalone的相似SWAP的方式实现的,而且无须对多台solr进行SWAP,只须SWAP master即可,slave会自动从master同步最新的索引。
没有找到文档,说solr是可以支持这种方式的。做了几次实验,这样的操作都成功了。但还是不放心,所以仔细的阅读了solr的源码,考虑了多这种情形了,相信这样的处理方式是可行的,并成功在线上进行了一次这样的操作,如果读者研究之后仍觉得有问题,请纠正我。
关于master/salve的索引同步的实现代码,主要在ReplicationHandler(master端)与SnapPuller(slave端)。
以下文章master/salve的索引同步的实现过程的分析比较清晰准备。
http://www.kafka0102.com/2010/07/249.html
Solrcloud模式下的re-indexing的实现
Solrcloud下的re-indexing是无法通过swap实现的。以下是Solr中CoreAdminHandler对SWAP请求最终调用的是SolrCore的一段代码:
protected void swap(String n0, String n1) { synchronized (modifyLock) { SolrCore c0 = cores.get(n0); SolrCore c1 = cores.get(n1); if (c0 == null) { // Might be an unloaded transient core c0 = container.getCore(n0); if (c0 == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No such core: " + n0); } } if (c1 == null) { // Might be an unloaded transient core c1 = container.getCore(n1); if (c1 == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No such core: " + n1); } } cores.put(n0, c1); cores.put(n1, c0); c0.setName(n1); c0.getCoreDescriptor().putProperty(CoreDescriptor.CORE_NAME, n1); c1.setName(n0); c1.getCoreDescriptor().putProperty(CoreDescriptor.CORE_NAME, n0); }
可见,SWAP只是简单地对两个内存中CoreDescriptor对象的name进行交换,甚至并没有与zookeeper有任何交涉。所以肯定无法适用于solrcloud的复杂情形。要实现cloud下的re-indexing,在core级别下的swap肯定是不够了,这时候,就需要一种在collection级别下的swap。
最后的解决方法我是在下文中找到,其中就提到了re-indexing的场景,cloudera网站上提供的方法:
http://blog.cloudera.com/blog/2013/10/collection-aliasing-near-real-time-search-for-really-big-data/
原文的片段如下:
Re-indexing
Collection aliases are also useful for re-indexing – especially when dealing with static indices. You
can re-index in a new collection while serving from the existing collection. Once the re-index is
complete, you simply swap in the new collection and then remove the first collection using your read
side aliases.
文中主要介绍的是alias 别名的使用,当然别名除了这种场景的应用,还有其他使用场体。利用Alias的修改,我们就可以实现两个collection之间的SWAP。
另外,提一下利用solrj进行alias操作时遇到的一些版本问题:Solrj4.6.0才开始支持CollectionAdmin操作,但是Solrj4.6.0进行alias create操作有明显bug,Solrj4.6.1修复。同时,solrj应使用与solr-core相同的版本,否则可能会有兼容性问题。所以如果想用java调用,而且使用4.6.1之前版本的solr服务,就需要自行实现该API方法,可参考Solrj4.6.1或以后版本,进行修改。
总结
总之,我所发现的solr对re-indexing的实现是增加了另一套索引再做切换实现的,这样的一个代价,就是增加了磁盘空间的占用,另一个代价就是某时间段占用两倍内存的可能。在solrcloud模式,这种做法不一定需要更多的机器,因为不同collection下的分片副本的core是可以共存于一个solr实例中的。
本文链接: http://quentinXXZ.iteye.com/blog/2153210
相关推荐
在"solr-dataimporthandler-scheduler-1.1"这个源码中,包含了实现DIH调度功能的代码。这通常意味着它提供了一种机制,可以在特定的时间间隔内自动触发数据导入过程,从而确保Solr的索引总是反映出最新数据。这种...
solr-data-import-scheduler-1.1.2,用于solr定时更新索引的jar包,下载后引入到solr本身的dist下面,或者你tomcat项目下面的lib下面
标题中的"solr-8.6.3.tgz+hbase-2.3.3-bin.tar.gz"表明我们有两个重要的开源软件版本:Apache Solr 8.6.3和HBase 2.3.3。Solr是Apache软件基金会的一个项目,主要用于全文搜索、企业级搜索和大数据分析。而HBase则是...
总的来说,Apache Solr6.5.1的定时增量数据导入特性通过`solr-dataimporthandler`和`solr-data-import-scheduler`这两个组件,实现了对数据源的自动化、智能化管理,极大地提高了数据检索的实时性和系统的响应速度。...
"solr-7.7.2+ik-analyzer-solr7x.zip"这个压缩包文件包含了Solr 7.7.2版本与Ik Analyzer的集成,特别针对Solr 7.x系列进行了优化。 Solr 7.7.2版本是Solr的一个稳定发行版,它提供了以下关键特性: 1. **高性能...
使用 `solr-dataimport-scheduler`,你需要在 Solr 的配置文件中定义调度器和数据源,指定数据源的连接参数、查询语句以及导入的字段等。同时,你还需要配置调度器的触发时间和频率,这通常在 `solrconfig.xml` 和 `...
Solr 数据导入调度器(solr-dataimport-scheduler.jar)是一个专门为Apache Solr 7.x版本设计的组件,用于实现数据的定期索引更新。在理解这个知识点之前,我们需要先了解Solr的基本概念以及数据导入处理...
solr-mongo-importer-1.1.0.jar solr-mongo-importer-1.1.0.jar solr-mongo-importer-1.1.0.jar
"apache-solr-dataimportscheduler.jar" 是一个专门为Solr设计的扩展包,用于实现自动化的数据增量更新调度。 首先,我们要理解Solr的数据导入过程。Solr使用DataImportHandler(DIH)来从关系型数据库、XML文件或...
solr6的中文分词器ik-analyzer-solr-6.0.jar,在solr上亲测可用
作为Apache软件基金会项目,Solr拥有活跃的开发者社区,不断提供新功能和改进,以及丰富的文档和示例代码供学习参考。 综上所述,Solr 4.10是强大的全文搜索引擎,尤其适合大规模数据的分布式处理,其丰富的特性和...
经测试apache-solr-dataimportscheduler1.0 版本在solr5.5上已经不能使用,这是本人自己根据情况修改后打的jar包亲测可用
Solr权威指南-上卷-高清-完整目录-2018年1月。。。。。
这个压缩包中的主要文件"apache-solr-dataimportscheduler-1.0.jar"包含了实现这一功能所需的全部Java类和资源。 在Solr中,数据导入通常通过DataImportHandler (DIH) 完成,DIH是一个插件,负责从外部数据源(如...
solr-import-export-json最新代码solr-import-export-json最新代码solr-import-export-json最新代码solr-import-export-json最新代码solr-import-export-json最新代码solr-import-export-json最新代码solr-import-...
Solr-9.0.0是该软件的最新版本,此版本可能包含了一些新的特性和改进,比如性能优化、新的查询语法、更强大的分析器等。 在Solr-9.0.0的压缩包中,通常会包含以下组件: 1. **bin** 文件夹:这个目录下有启动和...
solr 增量更新所需要的包 solr-dataimporthandler-6.5.1 + solr-dataimporthandler-extras-6.5.1 + solr-data-import-scheduler-1.1.2
标题中的"solr-8.11.1-src.tgz"表明这是Apache Solr 8.11.1版本的源代码包,适用于那些希望对Solr进行深度定制或开发的用户。 源代码发布通常包含了编译和构建Solr所需的所有文件,包括Java源代码、配置文件、测试...
在压缩包"apache-solr-1.4.0"中,包含了Solr的源代码、配置文件、示例文档以及其他必要的资源。对于喜欢研究Solr的人来说,这些源代码是深入理解其工作原理、定制功能以及优化性能的重要资料。通过对这些源码的研究...
适用于jdk1.6的项目中. solr-mongo-importer 用1.6打的包 避免使用过程中报jdk版本的错