solrcloud的官方文檔有對路由的簡短介紹,可是不夠詳細和深刻。solrcloud有兩種路由策略,一種是implicit(我的稱之爲手動路由) ,一種是compositeId(我的稱之爲自動路由);在建立collection的時候,若是沒有指定路由方式,指定了numShards個數,默認是自動路由,即compositeId路由;反之是implicit路由。在solrcloud的admin界面上,能經過collection的state.json看獲得collection的路由策略正則表達式
一、compositeId路由apache
使用compositeId路由,在建立collection的時候必需要指定numShards(分片數)。
compositeId是一種不可擴展的路由策略。json
1.一、compositeId路由原理性能
在建立collection的時候,compositeId路由肯定的分片數(numShards),solr給每一片分配一個32bit hash範圍。例如numShards=4,32位無符號範圍是0-ffffffff(4294967295),那麼每片的範圍是
spa
Shard3 : 0-1073741823
Shard4 : 1073741824-2147483647code
Shard1 : 2147483648-3221225471
Shard2 : 3221225472-4294967295router
在路由document的時候,compositeId路由會先計算document id的(例如document的unikey)murmurhash3 hash值,而後根據document id的hash值肯定文檔路由到那個分片上。例如xml
document id 值爲:abc索引
經過murmurhash3 hash在32bit上的值爲:1073741836ci
經過比較,1073741836落在Shard4範圍內,即該文檔寫入到Shard4中
compositeId路由不只限於經過document id計算murmurhash3 hash來肯定分片;還能夠經過正則表達式來肯定分片,例如:
shard_key!document_id
!號前面是分片的key,這個key不必定非得是shard的名字,保證solr按照這個key計算一致就行;!號後面是文檔id
取shard_key 16 bit hash,取document_id 16bit hash拼接成一個32bit hash,用於肯定文檔的路由。
例如,你須要爲不一樣的用戶分shard,你可能會使用用戶的名字或者ID做爲一個前綴。好比你的用戶是「juanpi」,若是你有一個文檔的ID是「12345」,把前綴插入到文檔的id字段中變成:「juanpi!12345」,在這裏感嘆號是一個分割符號,這裏的「juanpi」定義了這個文檔會指向一個特定的shard。
1.二、compositeId路由查詢
而後在查詢的時候,須要把這個前綴包含到_route_參數裏面(好比:q=solr&_route_=juanpi!)使查詢指向指定的shard。在某些狀況下;這樣操做能提高查詢的性能,由於它省掉了須要在全部shard上發起http查詢請求。
二、implicit路由
2.一、implicit路由原理
該路由方式須要外部指定document具體落在路由到哪一個Shard,這與compositeId路由方式索引可大體均勻分佈在每一個shard上不一樣;implicit路由是在外部控制,若是控制很差有可能分佈不均勻。
在建立collection的時候,不指定shadNume,或者明確指出使用implicit路由,也能夠指定使用某一個field(router.field)路由,這個參數定義了經過使用文檔中的一個字段來肯定文檔是屬於哪一個shard的。可是,若是在一個文檔中指定的字段沒有值得話,這個文檔Solr會拒絕處理。同時也可使用_route_參數來指定一個特定的shard。
也可使用solrj指定
利用solrJ新建索引時,須要在代碼中指定索引具體落在哪一個shard上,添加代碼:
doc.addField("_route_","shard_x");
同時在schema.xml添加字段
<field name="_route_" type="string"/>
2.二、implicit路由查詢
因爲建立collection是例如以下方式
http://localhost:8983/solr/admin/collections?action=CREATE&name=testimplicit&router.name=implicit&shards=shard1,shard2,shard3
而添加document的時候,指定寫入到shard1,shard2,shard3中的某一片,例如
doc.addField("_route_","shard3");
查詢的時候到某個分片查詢便可
三、擴展
3.一、compositeId路由方式擴展
compositeId路由,只能經過手動分裂某一片成兩片,而後刪除原來片的方式擴展
在分裂的過程當中,原分片的數據會大體均勻分紅2份,複製到新生成的兩個分片中
例如,原分片1萬數據,分裂成兩片後,每片大體5千數據
而後再手動刪除原來(1萬數據)的那片
3.二、implicit路由方式擴張
因爲implicit路由在寫入的時候指定了分片,因此能夠自由的增長分片