ElasticSearch裡面的路由功能介紹

2021-09-24 11:40:26 字數 1957 閱讀 5647

2019獨角獸企業重金招聘python工程師標準》

在elaticsearch裡面,路由功能算是乙個高階用法,大多數時候我們用的都是系統預設的路由功能,我們知道乙個es索引可以分多個shard和每個shard又可以有多個replia,那麼現在思考乙個問題,我們新增進去的資料,是如何分布在各個shard上面的,而查詢時候它是又怎麼找到特定的資料呢。

預設情況下,索引資料的分片規則,是下面的公式:

shard_num = hash(_routing) % num_primary_shards
_routing欄位的取值,預設是_id欄位或者是_parent欄位,這樣的取值在hash之後再與有多少個shard的數量取模,最終得到這條資料應該在被分配在那個乙個shard上,也就是說預設是基於hash的分片,保證在每個shard上資料量都近似平均,這樣就不會出現負載不均衡的情況,然後在檢索的時候,es缺省會搜尋所有shard上的資料,最後在master節點上匯聚在處理後,返回最終資料。

但有時候,我們會有另外一種情況,比如說儲存一年的資料,如果按hash去索引,那就是分布非常均勻,這樣的話無論查詢什麼資料都會去所有的shard上查詢,如果資料量比較大,那麼響應速度就比較慢,但這時,我們通過調查發現,一年12個月的資料本身分布並不均勻,有幾個月的資料偏多,有幾個月的資料偏少,理想情況下,資料偏少的月,查詢效能應該更快,但如果是基於hash分片,那麼我們並不能實現這種需求,因為hash分片,查詢時候必須要命中所有shard之後,查詢的結果才是準的,這樣以來,每次查詢都要掃瞄所有shard,比如我已經知道資料本身就是1月份的,那其實最好的情況下,只查詢1月的資料就行,而不需要把一年的資料都掃瞄一遍,導致最終的結果就是慢的更慢,快的也慢,所以我們要針對性的做優化。

那麼如何優化,其實思路也比較明確了,那就是按照月份分割槽,每乙個月的資料都存在指定的分割槽中,如果是mysql那就是每個月份一張表,然後查詢時候,直接查詢對應月份的資料即可,在es和solr中原理也大致如此,唯一不同的地方在於es和solr都比較方便的支援了路由欄位的設定而如果是資料庫,則需要自己通過中介軟體的方式來搞定,比如說mycat等。

下面來介紹如何在es中使用路由字段,先看乙個官網給的簡單的例子:

put my_index/my_type/1?routing=user1&refresh=true 

get my_index/my_type/1?routing=user1

上面的**中,指定了乙個使用者屬性作為路由進行分割槽,然後查詢的時候也必須指定路由。這一點需要注意 只要在索引時候加入路由字段,那麼在以後的get,delete,update操作中都必須使用路由字段,否則會出現問題。

當然,路由字段本身,也是可以被查詢的,看下面的**:

get my_index/_search

}}

除此之外,路由字段,也可以指定多個:

get my_index/_search?routing=user1,user2 

}}

如果指定多個使用者屬性,那麼es會僅僅查詢關聯了這兩個route屬性的shard

put my_index2}}}

put my_index2/my_type/1

缺失路由欄位會丟擲異常:

routing_missing_exception
還需要注意到是如果使用了路由字段,那麼_id欄位只能由使用者保證唯一性,因為同乙個id的資料,如果路由欄位不一樣 它是可以被存在到多個shard中的,而預設情況下是不會出現這種情況的。

最後接著說開頭的例子,如果某個月資料量偏大,全部路由到乙個shard裡面依然效能有問題,es也提供了 同乙個路由的字段的資料可以被分配到多個shard上,注意這是是多個shard,而不是所有shard,當然這裡面有一定 限制一般情況下,不建議使用這種模式。

對solr中路由感興趣的朋友,可以檢視我以前寫的文章:

ElasticSearch裡面的偏好查詢

在es查詢的時候我們可以控制preference,來完成特定shard或節點上的資料查詢,預設情況下查詢是隨機的。假如現在我們有乙份索引5個shard和3個副本,當乙個查詢請求過來的時候,查詢操作如何執行,在沒有使用路由的情況下5個shard的資料肯定都要查詢,然後查詢5個shard時候到底查的是主...

js裡面for迴圈裡面的of和in區別

for in 語句用於遍歷陣列或者物件的屬性名稱 key 鍵名 陣列中的每個元素的索引被視為屬性名稱,所以在使用for in遍歷array時,拿到的是每個元素索引 for in 迴圈只遍歷可列舉屬性。像 array和 object使用內建建構函式所建立的物件都會繼承自object.prototype...

elasticsearch配置詳解

elasticsearch的config資料夾裡面有兩個配置檔案 elasticsearch.yml和logging.yml,第乙個是es的基本配置檔案,第二個是日誌配置檔案,es也是使用log4j來記錄日誌的,所以logging.yml裡的設定按普通log4j配置檔案來設定就行了。下面主要講解下e...