咱們知道,一個index的數據會被分紅多個分片shard,因此說一個document只能存在與一個shard中。當客戶端建立document的時候,elasticsearch此時就須要決定這個document是放在這個index的哪一個分片shard中,這個過程就稱之爲document routing,即數據路由。算法
算法;shard = hash(routing) % number_of_primary_shards
舉個例子,假設一個index有5個primary shard(p0,p1,p2,p3,p4)。每次對index的一個document進行增刪改查的時候,都會帶過來一個routing number,默認就是這個documentd的_id(多是手動指定,也能夠是自動生成),routing=_id。
假設_id=1,那麼就會將routing=1這個routing值傳入一個hash函數中,產生一個routing值的hash值,假設hash(routing)=21,而後將hash函數產生的值對這個index的primary shard的數量求餘數,21 % 5 = 1
也就決定了這個document就放在p1上。負載均衡
注意:此這個計算過程就能夠看出,決定一個document在哪一個shard上,最重要的值就是routing值,默認是_id,也能夠手動指定,相同的routing值,每次過來,從hash函數中生成的hash值必定是相同的。不管最後計算的hash值是多少,對number_of_primary_shards求餘數,結果必定在0~number_of_primary_shards之間。elasticsearch
默認的routing就是_id,也能夠在發送請求的時候手動指定。
下面作一個比較有趣的例子
先測試一下默認的routing函數
//先插入數據 PUT /test_index/_doc/10 { "test_field": "test10 routing _id" } //獲取數據不帶routing參數 GET /test_index/_doc/10 { "_index" : "test_index", "_type" : "_doc", "_id" : "10", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true, "_source" : { "test_field" : "test10 routing _id" } } //獲取數據帶routing參數 參數值爲_id GET /test_index/_doc/10?routing=10 { "_index" : "test_index", "_type" : "_doc", "_id" : "10", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true, "_source" : { "test_field" : "test10 routing _id" } }
再來測試一下帶上routing值,爲了看到效果咱們讓_id的值與routing的值不同性能
//先插入數據 PUT /test_index/_doc/11?routing=12 { "test_field": "test routing not _id" } //獲取數據不帶routing參數 GET /test_index/_doc/11 { "_index" : "test_index", "_type" : "_doc", "_id" : "11", "found" : false } //獲取數據帶routing參數 參數值爲自定義的值 GET /test_index/_doc/11?routing=12 { "_index" : "test_index", "_type" : "_doc", "_id" : "11", "_version" : 1, "_seq_no" : 9, "_primary_term" : 1, "_routing" : "12", "found" : true, "_source" : { "test_field" : "test routing not _id" } }
手動指定的routing value是頗有用的,能夠保證某一類的document必定被路由到一個shard中去,那麼在後續進行應用級別的負載均衡以及提高批量讀取的性能的時候,是頗有幫助的。測試
經過上面的分析,特別是路由算法,咱們不難知道,在咱們最開始建立索引的時候,肯定了primary shard的數量,以後根據路由算法,每一個document就被路由到了指定的shard上面,以後的各類操做路由規則都是同樣的。試想一下,若是咱們改變了primary shard的數量,那麼路由算法取餘的時候值可能就跟以前的不同了,就會被路由到其它的shard上面去,就會致使數據混亂,本該已經存在的document,可能經過查詢根本查不到,某種程度上說這也會形成數據的丟失。code