对SolrCloud集群Collection进行手动二次Sharding

咱们已经基于SolrCloud 4.3.1+Tomcat 7搭建了搜索服务器集群,一个Collection对应3个节点上的3个分片(Shard),同时包含对应分片的副本(Replica),此时,该 Collection一共有6000万左右Document,平均每一个分片大约接近2000万。
html

SolrCloud集群节点的具体分布,如图所示:java


只有shard1有一个副本,而且位于不一样的节点上。node

随着索引数据量的增加,若是咱们的Collection的每一个分片都不断的增大,最后致使单个分片在搜索的时候,相应速度成为瓶颈,那么,咱们 要考虑将每一个分片再次进行分片。由于第一次系统规划时已经设置好分片数量,因此每一个分片所包含的Document数量几乎是相同的,也就是说,再次分片 后,从新获得的分片的数量是原来的二倍。apache

目前,SolrCloud不支持自动分片,可是支持手动分片,并且手动分片后获得的新的分片所包含的Document数量有必定的差别(还不清 楚SolrCloud是否支持手动分片后大体均分一个分片)。下面,咱们看一下,在进行手动分片过程当中,须要执行哪些操做,应该如何从新规划整个 SolrCloud集群。tomcat


首先,我增长了一个节点(slave6 10.95.3.67),把集群中原来的配置文件、solr-cloud.war及其Tomcat服务器都拷贝到这个新增的节点上,目的是将 10.95.3.62上的shard1再次分片,而后将再次获得分片运行在新增的10.95.3.67节点上。启动新增节点的Tomcat服务器,它自动 去链接ZooKeeper集群,此时ZooKeeper集群增长live_nodes数量,主要是经过在Tomcat的启动脚本中增长以下内容:服务器

JAVA_OPTS="-server -Xmx4096m -Xms1024m -verbose:gc -Xloggc:solr_gc.log -Dsolr.solr.home=/home/hadoop/applications/solr/cloud/multicore -DzkHost=master:2188,slave1:2188,slave4:2188"

这样,就能告知ZooKeeper集群有新节点加入SolrCloud集群。app

如上图所示,咱们打算将shard1进行二次手动分片,执行以下命令便可:curl

curl 'http://master:8888/solr-cloud/admin/collections?action=SPLITSHARD&collection=mycollection&shard=shard1'

这个过程花费的时间比较长,并且可能会伴有以下异常相应信息:oop

[html] view plaincopyurl

  1. <?xml version="1.0" encoding="UTF-8"?>  

  2. <response>  

  3. <lst name="responseHeader"><int name="status">500</int><int name="QTime">300138</int></lst><lst name="error"><str name="msg">splitshard the collection time out:300s</str><str name="trace">org.apache.solr.common.SolrException: splitshard the collection time out:300s  

  4.      at org.apache.solr.handler.admin.CollectionsHandler.handleResponse(CollectionsHandler.java:166)  

  5.      at org.apache.solr.handler.admin.CollectionsHandler.handleSplitShardAction(CollectionsHandler.java:300)  

  6.      at org.apache.solr.handler.admin.CollectionsHandler.handleRequestBody(CollectionsHandler.java:136)  

  7.      at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:135)  

  8.      at org.apache.solr.servlet.SolrDispatchFilter.handleAdminRequest(SolrDispatchFilter.java:608)  

  9.      at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:215)  

  10.      at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:155)  

  11.      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)  

  12.      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)  

  13.      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)  

  14.      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)  

  15.      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)  

  16.      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)  

  17.      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)  

  18.      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)  

  19.      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)  

  20.      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)  

  21.      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)  

  22.      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)  

  23.      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)  

  24.      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)  

  25.      at java.lang.Thread.run(Thread.java:722)  

  26. </str><int name="code">500</int></lst>  

  27. </response>  

Solr 这个版本,实际真正的执行手动分片的动做已经在SolrCloud集群中进行,能够忽略这个异常。咱们须要注意的是,在进行手动分片的时候,尽可能不要在集 群操做比较频繁的时候进行,例如,我就是在保持10个线程同时进行索引的过程当中进行手动分片的,观察服务器状态,资源消费量比较大,并且速度很慢。

在执行手动分片的过程当中,咱们能够经过Web管理页面。观察当前集群中节点的状态变化。

提交上面的命令之后,能够看到,集群中新增节点的状态,如图所示:


上面的状态是“Recovering”,也就是在将shard1中分红两个子分片,新增节点加入到集群,准备接收分片(或者对应的复制副本),如上图可见,shard3和shard1在新增节点上分别增长了一个副本。

接续看集群状态变化,如图所示:


在 shard1所在节点(10.95.3.62)上,将shard1分红了两个子分片:shard1_0和shard1_1,此时,在10.95.3.62 节点上有3个分片出于“Active”状态。实际上,到目前为止,子分片shard1_0和shard1_1已经彻底接管了shard1分片,只是没有从 图中自动离线退出,这个就须要咱们在管理页面你上手动“unload”掉不须要的shard。

这时,新获得的两个子分片,并无处理以前shard1的两个副本,他们也须要进行分片(其实是从新复制新分片的副本),这个过程,如图所示:


等待“Recovering”恢复完成之后,咱们就能够看到进入“Active”状态的节点图,如图所示:


手动分片的工做基本已经完成,这时候,若是继续索引新的数据,shard1及其副本不会再接收请求,因此数据已经在再次分片的子分片上,请求也会发送到那些子分片的节点上,下面须要将以前的shard1及其分片unload掉,即退出集群,要处理的分片主要包含以下几个:

mycollection_shard1_replica1
mycollection_shard1_replica_2
mycollection_shard1_replica_3

必定不要操做失误,不然可能会形成索引数据丢失的。unload这几个分片之后,新的集群的节点分布,如图所示:


shard1_0和shard1_1两个新的分片,对应的副本,分别以下所示:

mycollection_shard1_0_replica1
mycollection_shard1_0_replica2
mycollection_shard1_0_replica3

mycollection_shard1_1_replica1
mycollection_shard1_1_replica2
mycollection_shard1_1_replica3

下面,咱们对比一下,手动二次分片之后,各个节点上Document的数量,以下表所示:

分片/副本名称 所在节点 文档数量
mycollection_shard1_0_replica1 10.95.3.62 18839290
mycollection_shard1_0_replica2 10.95.3.67 18839290
mycollection_shard1_0_replica3 10.95.3.61 18839290
mycollection_shard1_1_replica1 10.95.3.62 957980
mycollection_shard1_1_replica2 10.95.3.61 957980
mycollection_shard1_1_replica3 10.95.3.67 957980
mycollection_shard2_replica1 10.95.3.62 23719916
mycollection_shard3_replica1 10.95.3.61 23719739
mycollection_shard3_replica1 10.95.3.67 23719739

可见,二次分片的shard1_1上面,Document数量相比于其它分片,十分不均。

SolrCloud也正在不断的更新中,在后续的版本可能会更多地考虑到分片的问题。另外,对于某个节点上的分片若是过大,影响了搜索效率,能够考虑另外一种方案,就是重建索引,即便新增节点,从新索引再次从新分片,并均匀地分布到各个节点上。



参考连接

相关文章
相关标签/搜索