Elasticsearch的路由(Routing)特性

目錄(?)[-]算法

  1. Elasticsearch路由機制介紹數據庫

  2. 指定個性化路由app

  3. 利用路由機制的查詢負載均衡

  4. 路由機制的總結curl

Elasticsearch路由機制介紹

Elasticsearch的路由機制與其分片機制有着直接的關係。Elasticsearch的路由機制便是經過哈希算法,將具備相同哈希值的文檔放置到同一個主分片中。這個和經過哈希算法來進行負載均衡幾乎是同樣的。oop


而Elasticsearch也有一個默認的路由算法:它會將文檔的ID值做爲依據將其哈希到相應的主分片上,這種算法基本上會保持全部數據在全部分片上的一個平均分佈,而不會產生數據熱點。post


而咱們爲何會須要自定義的Routing模式呢?首先默認的Routing模式在不少狀況下都是能知足咱們的需求的——平均的數據分佈、對咱們來講是透明的、多數時候性能也不是問題。可是在咱們更深刻地理解咱們的數據的特徵以後,使用自定義的Routing模式可能會給咱們帶來更好的性能。性能


假設你有一個100個分片的索引。當一個請求在集羣上執行時會發生什麼呢?ui

1. 這個搜索的請求會被髮送到一個節點url

2. 接收到這個請求的節點,將這個查詢廣播到這個索引的每一個分片上(多是主分片,也多是複製分片)

3. 每一個分片執行這個搜索查詢並返回結果

4. 結果在通道節點上合併、排序並返回給用戶


由於默認狀況下,Elasticsearch使用文檔的ID(相似於關係數據庫中的自增ID,固然,若是不指定ID的話,Elasticsearch使用的是隨機值)將文檔平均的分佈於全部的分片上,這致使了Elasticsearch不能肯定文檔的位置,因此它必須將這個請求廣播到全部的100個分片上去執行。這同時也解釋了爲何主分片的數量在索引建立的時候是固定下來的,而且永遠不能改變。由於若是分片的數量改變了,全部先前的路由值就會變成非法了,文檔至關於丟失了。


而自定義的Routing模式,可使咱們的查詢更具目的性。咱們沒必要盲目地去廣播查詢請求,取而代之的是:咱們要告訴Elasticsearch咱們的數據在哪一個分片上。


原來的查詢語句:「請告訴我,USER1的文檔數量一共有多少」

使用自定義Routing(在USESR ID上)後的查詢語句:「請告訴我,USER1的文檔數量一共有多少,它就在第三個分片上,其它的分片就不要去掃描了」


指定個性化路由

全部的文檔API(get,index,delete,update和mget)都能接收一個routing參數,能夠用來造成個性化文檔分片映射。一個個性化的routing值能夠確保相關的文檔存儲到一樣的分片上——好比,全部屬於同一個用戶的文檔。


第一種方法,也是比較直觀的方法就是直接在請求的URL中指定routing參數:

[plain] view plaincopy

<EMBED id=ZeroClipboardMovie_1 height=18 name=ZeroClipboardMovie_1 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=1&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. curl -XPOST 'http://localhost:9200/store/order?routing=user123' -d '  

  2. {  

  3.     "productName": "sample",  

  4.     "customerID": "user123"  

  5. }'  


這樣咱們就按照用戶的customerID的值將具備相同customerID的文檔置於同一分片上了。


第二種方法就是直接從文檔中提取到對應的路由值:

[plain] view plaincopy

<EMBED id=ZeroClipboardMovie_2 height=18 name=ZeroClipboardMovie_2 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=2&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. curl -XPUT 'http://localhost:9200/store/order/_mapping' -d '  

  2. {  

  3.     "order": {  

  4.         "_routing": {  

  5.             "required": true,  

  6.             "path": "customerID"  

  7.         }  

  8.     }  

  9. }'  


這樣的方法和第一種方法在效果上同樣的,可是有一點須要注意,相比於第一種方法這種方法的效率稍低,由於第一種方法直接就在請求的參數中肯定了路由的值,而第二種方法中,首先須要將文檔讀入以後,再從中提取到對應的路由值。


利用路由機制的查詢

利用路由機制的查詢也是很是簡單明瞭的,只須要在查詢中指定對應的路由值便可:

[plain] view plaincopy

<EMBED id=ZeroClipboardMovie_3 height=18 name=ZeroClipboardMovie_3 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=3&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. curl -XGET 'http://localhost:9200/store/order/_search?routing=user123' -d '  

  2. {  

  3.     "query": {  

  4.         "filtered": {  

  5.             "query": {  

  6.                 "match_all": {}  

  7.             },  

  8.             "filter": {  

  9.                 "term": {  

  10.                     "userID": "user123"  

  11.                 }  

  12.             }  

  13.         }  

  14.     }  

  15. }'  


經過指定的路由值,咱們就能夠直接定位到user123的文檔所在的分片,而不用一股腦的向索引的全部節點都發送請求。這樣的話,會大大減小系統資源的浪費。


固然,也能夠同時指定多個路由值,方法也是顯而易見的,只須要在查詢參數中指定多個路由值便可:

[plain] view plaincopy

<EMBED id=ZeroClipboardMovie_4 height=18 name=ZeroClipboardMovie_4 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=4&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. curl -XGET 'http://localhost:9200/forum/posts/?routing=Admin,Moderator' -d '{}'  



路由機制的總結

實際上,若是不明確指明使用路由機制,實際上路由機制也是在發揮做用的,只是默認的路由值是文檔的id而已。而個性化路由的需求主要是和業務相關的。默認的路由(若是是自動的生成的id)直觀上會把全部的文檔隨機分配到一個分片上,而個性化的路由值就是和業務相關的了。這也會形成一些潛在的問題,好比user123自己的文檔就很是多,有數十萬個,而其餘大多數的用戶只有幾個文檔,這樣的話就會致使user123所在的分片較大,出現數據偏移的狀況,特別是多個這樣的用戶處於同一分片的時候,現象會更明顯。具體的使用仍是要結合實際的應用場景來選擇的。

相關文章
相關標籤/搜索