? ? ? ?Elasticsearch的路由機(jī)制與其分片機(jī)制有著直接的關(guān)系北戏。Elasticsearch的路由機(jī)制即是通過(guò)哈希算法尿赚,將具有相同哈希值的文檔放置到同一個(gè)主分片中督惰。這個(gè)和通過(guò)哈希算法來(lái)進(jìn)行負(fù)載均衡幾乎是一樣的察皇。
? ? ? ? 而Elasticsearch也有一個(gè)默認(rèn)的路由算法:它會(huì)將文檔的ID值作為依據(jù)將其哈希到相應(yīng)的主分片上茴厉,這種算法基本上會(huì)保持所有數(shù)據(jù)在所有分片上的一個(gè)平均分布,而不會(huì)產(chǎn)生數(shù)據(jù)熱點(diǎn)什荣。
樂(lè)觀并發(fā)控制:
Elasticsearch是分布式的矾缓。當(dāng)文檔被創(chuàng)建、更新或刪除稻爬,文檔的新版本會(huì)被復(fù)制到集群的其它節(jié)點(diǎn)嗜闻。Elasticsearch即是同步的又是異步的,意思是這些復(fù)制請(qǐng)求都是平行發(fā)送的桅锄,并無(wú)序(out of sequence)的到達(dá)目的地琉雳。這就需要一種方法確保老版本的文檔永遠(yuǎn)不會(huì)覆蓋新的版本样眠。在 index 、 get 翠肘、 delete 請(qǐng)求時(shí)吹缔,我們指出每個(gè)文檔都有一個(gè) _version 號(hào)碼,這個(gè)號(hào)碼在文檔被改變時(shí)加一锯茄。
Elasticsearch使用這個(gè) _version 保證所有修改都被正確排序厢塘。當(dāng)一個(gè)舊版本出現(xiàn)在新版本之后,它會(huì)被簡(jiǎn)單的忽略肌幽。
分布式文檔存儲(chǔ)
路由文檔到分片
Elasticsearch將文檔存儲(chǔ)的哪一個(gè)分片上晚碾,是根據(jù)算法:
shard = hash(routing) % number_of_primary_shards
routing 值是一個(gè)任意字符串,它默認(rèn)是 _id 但也可以自定義喂急。這個(gè) routing
字符串通過(guò)哈希函數(shù)生成一個(gè)數(shù)字格嘁,然后除以主切片的數(shù)量得到一個(gè)余數(shù)
(remainder),余數(shù)的范圍永遠(yuǎn)是 0 到 number_of_primary_shards - 1 廊移,這個(gè)
數(shù)字就是特定文檔所在的分片
新建糕簿、索引和刪除文檔都是寫(xiě)操作,它們必須在主分片上成功完成才能復(fù)制到相關(guān)的的復(fù)制分片上狡孔。
而我們?yōu)槭裁磿?huì)需要自定義的Routing模式呢懂诗?首先默認(rèn)的Routing模式在很多情況下都是能滿(mǎn)足我們的需求的——平均的數(shù)據(jù)分布、對(duì)我們來(lái)說(shuō)是透明的苗膝、多數(shù)時(shí)候性能也不是問(wèn)題殃恒。但是在我們更深入地理解我們的數(shù)據(jù)的特征之后,使用自定義的Routing模式可能會(huì)給我們帶來(lái)更好的性能辱揭。
假設(shè)你有一個(gè)100個(gè)分片的索引离唐。當(dāng)一個(gè)請(qǐng)求在集群上執(zhí)行時(shí)會(huì)發(fā)生什么呢?
1. 這個(gè)搜索的請(qǐng)求會(huì)被發(fā)送到一個(gè)節(jié)點(diǎn)
2. 接收到這個(gè)請(qǐng)求的節(jié)點(diǎn)问窃,將這個(gè)查詢(xún)廣播到這個(gè)索引的每個(gè)分片上(可能是主分片亥鬓,也可能是復(fù)制分片)
3. 每個(gè)分片執(zhí)行這個(gè)搜索查詢(xún)并返回結(jié)果
4. 結(jié)果在通道節(jié)點(diǎn)上合并、排序并返回給用戶(hù)
因?yàn)槟J(rèn)情況下域庇,Elasticsearch使用文檔的ID(類(lèi)似于關(guān)系數(shù)據(jù)庫(kù)中的自增ID嵌戈,當(dāng)然,如果不指定ID的話较剃,Elasticsearch使用的是隨機(jī)值)將文檔平均的分布于所有的分片上咕别,這導(dǎo)致了Elasticsearch
不能確定文檔的位置,所以它必須將這個(gè)請(qǐng)求廣播到所有的100個(gè)分片上去執(zhí)行写穴。這同時(shí)也解釋了為什么主分片的數(shù)量在索引創(chuàng)建的時(shí)候是固定下來(lái)的,并且永遠(yuǎn)不能改變雌贱。因?yàn)槿绻制臄?shù)量改變了啊送,
所有先前的路由值就會(huì)變成非法了偿短,文檔相當(dāng)于丟失了。
當(dāng)然在5.0中增加了Shrink接口馋没,它可將分片數(shù)進(jìn)行收縮成它的因數(shù)昔逗,如之前你是15個(gè)分片,你可以收縮成5個(gè)或者3個(gè)又或者1個(gè)篷朵,那么我們就可以想象成這樣一種場(chǎng)景勾怒,在寫(xiě)入壓力非常大的收集階段,
設(shè)置足夠多的索引声旺,充分利用shard的并行寫(xiě)能力笔链,索引寫(xiě)完之后收縮成更少的shard,提高查詢(xún)性能腮猖。而自定義的Routing模式鉴扫,可以使我們的查詢(xún)更具目的性。我們不必盲目地去廣播查詢(xún)請(qǐng)求澈缺,取而代
之的是:我們要告訴Elasticsearch我們的數(shù)據(jù)在哪個(gè)分片上坪创。
而當(dāng)你采集的日志數(shù)據(jù)有明顯的地域性,如數(shù)據(jù)來(lái)自北京姐赡、河北莱预、浙江、廣東等项滑,當(dāng)你只需對(duì)北京的數(shù)據(jù)進(jìn)行分析時(shí)锁施,設(shè)想下如果數(shù)據(jù)是按地域進(jìn)行存儲(chǔ)的,這樣分析時(shí)需要加載的數(shù)據(jù)是不是的大減小
了杖们;這個(gè)跟數(shù)據(jù)庫(kù)的分區(qū)的做法較為類(lèi)似悉抵。
curl -XPOST 'http://localhost:9200/log_201702/info?routing=beijing' -d '
{
"event": "sample",
"host": "60.11.23.222"
}'
查詢(xún)時(shí)指定路由
curl -XGET 'http://localhost:9200/log_201702/info_search?routing=beijing' -d '
{
"query": {
"match_all": {}
}
}'
在大規(guī)模集群計(jì)算時(shí),使用路由是能大大提高集群的響應(yīng)速度的摘完,路由姥饰、路由、路由重要的事情說(shuō)三遍孝治。
當(dāng)然在進(jìn)行日志存儲(chǔ)時(shí)列粪,進(jìn)行分表(也是數(shù)據(jù)分區(qū)的一種實(shí)現(xiàn))也是提高檢索速度的一個(gè)重要法寶。
利用Elasticsearch跨表查詢(xún)的功能谈飒,對(duì)指定索引集合的數(shù)據(jù)進(jìn)行分析岂座,只需要對(duì)索引名進(jìn)行通配(log_2017*)就能夠簡(jiǎn)單的指定分析的索引。
curl -XGET 'http://localhost:9200/log_2017*/info_search?routing=beijing' -d '
{
"query": {
"match_all": {}
}
}'
指定路由查詢(xún)杭措、跨表查詢(xún)這些提高集群檢索性能的利器费什,當(dāng)前簡(jiǎn)單使用SQL均以支持
指定路由查詢(xún)
select * from log_201702@beijing where host between '60.11.0.0' and '60.11.0.0';
"log_201702/beijing" SQL中from的表明中用“@”來(lái)定義路由信息
跨表查詢(xún)
通配符
select * from log_2017*手素;
定義表的數(shù)組鸳址,用","隔開(kāi)
select * from log_201701,log_201703 where host = 'xx.xx.xx.xxx'瘩蚪;
跨表查詢(xún)與指定路由的結(jié)合
select * from log_201701,log_201703@beijing where host = 'xx.xx.xx.xxx';
更多使用Elasticsearch的使用技巧請(qǐng)關(guān)注合眾開(kāi)源:
https://github.com/unimassystem