對SolrCloud集羣Collection進行手動二次Sharding

我們已經基於SolrCloud 4.3.1+Tomcat 7搭建了搜索服務器集羣,一個Collection對應3個節點上的3個分片(Shard),同時包含對應分片的副本(Replica),此時,該Collection一共有6000萬左右Document,平均每個分片大約接近2000萬。
SolrCloud集羣節點的具體分佈,如圖所示:

只有shard1有一個副本,並且位於不同的節點上。
隨着索引數據量的增長,如果我們的Collection的每個分片都不斷的增大,最後導致單個分片在搜索的時候,相應速度成爲瓶頸,那麼,我們要考慮將每個分片再次進行分片。因爲第一次系統規劃時已經設置好分片數量,所以每個分片所包含的Document數量幾乎是相同的,也就是說,再次分片後,重新得到的分片的數量是原來的二倍。
目前,SolrCloud不支持自動分片,但是支持手動分片,而且手動分片後得到的新的分片所包含的Document數量有一定的差異(還不清楚SolrCloud是否支持手動分片後大致均分一個分片)。下面,我們看一下,在進行手動分片過程中,需要執行哪些操作,應該如何重新規劃整個SolrCloud集羣。

首先,我增加了一個節點(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集羣。
如上圖所示,我們打算將shard1進行二次手動分片,執行如下命令即可:
curl 'http://master:8888/solr-cloud/admin/collections?action=SPLITSHARD&collection=mycollection&shard=shard1'
這個過程花費的時間比較長,而且可能會伴有如下異常相應信息:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<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
     at org.apache.solr.handler.admin.CollectionsHandler.handleResponse(CollectionsHandler.java:166)
     at org.apache.solr.handler.admin.CollectionsHandler.handleSplitShardAction(CollectionsHandler.java:300)
     at org.apache.solr.handler.admin.CollectionsHandler.handleRequestBody(CollectionsHandler.java:136)
     at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:135)
     at org.apache.solr.servlet.SolrDispatchFilter.handleAdminRequest(SolrDispatchFilter.java:608)
     at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:215)
     at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:155)
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
     at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
     at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     at java.lang.Thread.run(Thread.java:722)
</str><int name="code">500</int></lst>
</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也正在不斷的更新中,在後續的版本可能會更多地考慮到分片的問題。另外,對於某個節點上的分片如果過大,影響了搜索效率,可以考慮另一種方案,就是重建索引,即使新增節點,重新索引再次重新分片,並均勻地分佈到各個節點上。


參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章