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