Solr Sharding將一個Solr的索引分成多個部分,這些被Sharding的索引可能會位于不同的機器上。當數據對于一個節(jié)點來說太大時,您可以通過創(chuàng)建一個或多個Shard來分解它,并將其存儲在各個section中,每個Shard包含唯一的索引片段。
Shard是collection的一個邏輯分區(qū),它包含了這個collection文檔的一個子集,collection中的每個文檔只存在一個Shard中。哪個Shard包含collection中的哪個文檔則取決于該collection的整體Sharding策略。
舉個栗子,我們有一個collection,這個collection的country字段決定了每個文檔應該屬于哪個Shard。因此,具有相同country的文檔將會放置在一起。
不同的collection只是在每個文檔的uniqueKey上使用Hash來確定其屬于哪個Shard。
Sharding很重要,主要有兩個原因:
- 它允許你水平拆分或擴充容量。
- 它允許你跨Shard(可能在多個節(jié)點上)分發(fā)操作(例如,索引跟蹤),從而提高性能/吞吐量。
- 它可以將往Solr中寫數據的壓力分解到不同的Shard中
在SolrCloud之前,Solr支持分布式搜索(Distributed Search),它允許跨多個Shard執(zhí)行一個查詢。所以,查詢是針對整個SOLR索引執(zhí)行的,這樣搜索結果中不會遺漏任何文檔。因此,在Shard之間拆分索引并不僅僅是SolrCloud的概念。
Leaders and Replicas
在SolrCloud中沒有masters或者slaves。相反,每個shard至少由一個物理replica組成,并且其中必定有一個是Leader。
如果leader掛掉了,其他一個replica將自動當選為新leader。
當文檔被發(fā)送到Solr節(jié)點進行索引時,系統(tǒng)首先確定該文檔屬于哪個Shard:
+--------------------+
+------>+ Shard1 |
| +--------------------+
|
|
+------------+ |
| Document +------->+
+------------+ |
|
|
| +--------------------+
+------>+ Shard2 |
+--------------------+
然后,確定哪個節(jié)點托管了該Shard的Leader。然后,將文檔轉發(fā)給當前的Leader進行索引。
+--------------------+
+-------->+ Replica1 |
| +--------------------+
|
|
+------------+ | +--------------------+
| Shard1 +--------------->+ Replica2 |
+------------+ | +--------------------+
|
|
| +--------------------+
+-------->+ Replica3 Leader |
+--------------------+
然后,Leader會將更新轉發(fā)給所有其他replica。
+--------------------+
+-------->+ Replica1 +<-------+
| +--------------------+ |
| |
| |
+------------+ | +--------------------+ |
| Shard1 +--------------->+ Replica2 +<-------+
+------------+ | +--------------------+ |
| |
| |
| +--------------------+ |
+-------->+ Replica3 Leader +--------+
+--------------------+
一個Shard至少由一個物理replica組成,多個物理replica有如下優(yōu)勢:
- 它提供了高可用性,如果Shard中的一個replica掛掉了,其它的replica仍可以提供服務。
- 它允許你擴展搜索吞吐量,這是因為搜索可以在所有的replica上并行執(zhí)行。
Document Routing
Solr通過在創(chuàng)建collection時指定router.name參數,可以指定collection使用的router實現。
Solr中含有兩種sharding策略,一種是默認的compositeId(一致性hash),一般在指定numShards參數時會自動切換到router="compositeId"。另一種是implicit。
如果采用compositeId方式,那么就不能動態(tài)增加shard。如果采用的是implicit方式,就可以動態(tài)的增加shard。
CompositeId
該路由為一致性哈希路由,shards的哈希范圍從0~ffffffff。初始創(chuàng)建collection時必須指定numShards。compositeId路由算法根據numShards的個數計算出每個shard的哈希范圍,在更新或者新增文檔時,根據文檔的uniqueKey的hash坐落在那個hash區(qū)間來決定這份document數據發(fā)送至哪個shard。
0-7fffffff
+--------------------+
+------>+ Shard1 |
| +--------------------+
|
|
+----------------+ document uniqueKey |
| Document +------------------------>+
+----------------+ |
|
| 80000000-ffffffff
| +--------------------+
+------>+ Shard2 |
+--------------------+
使用compositeId路由方式索引可均勻分布在每個shard上。如果你發(fā)現你的不同shard之間的數據量差別非常大,那么很可能你的Shard丟失了數據。
Implicit
If you created the collection and defined the "implicit" router at the time of creation, you can additionally define a router.field parameter to use a field from each document to identify a shard where the document belongs. If the field specified is missing in the document, however, the document will be rejected. You could also use the route parameter to name a specific shard.
該路由方式通過定義router.field指定索引具體落在哪個shard,這與compositeId路由方式索引可均勻分布在每個shard上不同,使用Implicit路由方式索引可能不會均勻分布在每個shard上,這依賴于router.field的值分布是否均勻。