? ? ? ?Elasticsearch的路由機制與其分片機制有著直接的關系。Elasticsearch的路由機制即是通過哈希算法,將具有相同哈希值的文檔放置到同一個主分片中。這個和通過哈希算法來進行負載均衡幾乎是一樣的。
? ? ? ? 而Elasticsearch也有一個默認的路由算法:它會將文檔的ID值作為依據(jù)將其哈希到相應的主分片上,這種算法基本上會保持所有數(shù)據(jù)在所有分片上的一個平均分布,而不會產生數(shù)據(jù)熱點。
樂觀并發(fā)控制:
Elasticsearch是分布式的。當文檔被創(chuàng)建、更新或刪除,文檔的新版本會被復制到集群的其它節(jié)點。Elasticsearch即是同步的又是異步的,意思是這些復制請求都是平行發(fā)送的,并無序(out of sequence)的到達目的地。這就需要一種方法確保老版本的文檔永遠不會覆蓋新的版本。在 index 、 get 、 delete 請求時,我們指出每個文檔都有一個 _version 號碼,這個號碼在文檔被改變時加一。
Elasticsearch使用這個 _version 保證所有修改都被正確排序。當一個舊版本出現(xiàn)在新版本之后,它會被簡單的忽略。
分布式文檔存儲
路由文檔到分片
Elasticsearch將文檔存儲的哪一個分片上,是根據(jù)算法:
shard = hash(routing) % number_of_primary_shards
routing 值是一個任意字符串,它默認是 _id 但也可以自定義。這個 routing
字符串通過哈希函數(shù)生成一個數(shù)字,然后除以主切片的數(shù)量得到一個余數(shù)
(remainder),余數(shù)的范圍永遠是 0 到 number_of_primary_shards - 1 ,這個
數(shù)字就是特定文檔所在的分片
新建、索引和刪除文檔都是寫操作,它們必須在主分片上成功完成才能復制到相關的的復制分片上。
而我們?yōu)槭裁磿枰远x的Routing模式呢?首先默認的Routing模式在很多情況下都是能滿足我們的需求的——平均的數(shù)據(jù)分布、對我們來說是透明的、多數(shù)時候性能也不是問題。但是在我們更深入地理解我們的數(shù)據(jù)的特征之后,使用自定義的Routing模式可能會給我們帶來更好的性能。
假設你有一個100個分片的索引。當一個請求在集群上執(zhí)行時會發(fā)生什么呢?
1. 這個搜索的請求會被發(fā)送到一個節(jié)點
2. 接收到這個請求的節(jié)點,將這個查詢廣播到這個索引的每個分片上(可能是主分片,也可能是復制分片)
3. 每個分片執(zhí)行這個搜索查詢并返回結果
4. 結果在通道節(jié)點上合并、排序并返回給用戶
因為默認情況下,Elasticsearch使用文檔的ID(類似于關系數(shù)據(jù)庫中的自增ID,當然,如果不指定ID的話,Elasticsearch使用的是隨機值)將文檔平均的分布于所有的分片上,這導致了Elasticsearch
不能確定文檔的位置,所以它必須將這個請求廣播到所有的100個分片上去執(zhí)行。這同時也解釋了為什么主分片的數(shù)量在索引創(chuàng)建的時候是固定下來的,并且永遠不能改變。因為如果分片的數(shù)量改變了,
所有先前的路由值就會變成非法了,文檔相當于丟失了。
當然在5.0中增加了Shrink接口,它可將分片數(shù)進行收縮成它的因數(shù),如之前你是15個分片,你可以收縮成5個或者3個又或者1個,那么我們就可以想象成這樣一種場景,在寫入壓力非常大的收集階段,
設置足夠多的索引,充分利用shard的并行寫能力,索引寫完之后收縮成更少的shard,提高查詢性能。而自定義的Routing模式,可以使我們的查詢更具目的性。我們不必盲目地去廣播查詢請求,取而代
之的是:我們要告訴Elasticsearch我們的數(shù)據(jù)在哪個分片上。
而當你采集的日志數(shù)據(jù)有明顯的地域性,如數(shù)據(jù)來自北京、河北、浙江、廣東等,當你只需對北京的數(shù)據(jù)進行分析時,設想下如果數(shù)據(jù)是按地域進行存儲的,這樣分析時需要加載的數(shù)據(jù)是不是的大減小
了;這個跟數(shù)據(jù)庫的分區(qū)的做法較為類似。
curl -XPOST 'http://localhost:9200/log_201702/info?routing=beijing' -d '
{
"event": "sample",
"host": "60.11.23.222"
}'
查詢時指定路由
curl -XGET 'http://localhost:9200/log_201702/info_search?routing=beijing' -d '
{
"query": {
"match_all": {}
}
}'
在大規(guī)模集群計算時,使用路由是能大大提高集群的響應速度的,路由、路由、路由重要的事情說三遍。
當然在進行日志存儲時,進行分表(也是數(shù)據(jù)分區(qū)的一種實現(xiàn))也是提高檢索速度的一個重要法寶。
利用Elasticsearch跨表查詢的功能,對指定索引集合的數(shù)據(jù)進行分析,只需要對索引名進行通配(log_2017*)就能夠簡單的指定分析的索引。
curl -XGET 'http://localhost:9200/log_2017*/info_search?routing=beijing' -d '
{
"query": {
"match_all": {}
}
}'
指定路由查詢、跨表查詢這些提高集群檢索性能的利器,當前簡單使用SQL均以支持
指定路由查詢
select * from log_201702@beijing where host between '60.11.0.0' and '60.11.0.0';
"log_201702/beijing" SQL中from的表明中用“@”來定義路由信息
跨表查詢
通配符
select * from log_2017*;
定義表的數(shù)組,用","隔開
select * from log_201701,log_201703 where host = 'xx.xx.xx.xxx';
跨表查詢與指定路由的結合
select * from log_201701,log_201703@beijing where host = 'xx.xx.xx.xxx';
更多使用Elasticsearch的使用技巧請關注合眾開源:
https://github.com/unimassystem