對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也正在不斷的更新中,在後續的版本可能會更多地考慮到分片的問題。另外,對於某個節點上的分片若是過大,影響了搜索效率,能夠考慮另外一種方案,就是重建索引,即便新增節點,從新索引再次從新分片,並均勻地分佈到各個節點上。



參考連接

相關文章
相關標籤/搜索