溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

關(guān)于ES性能調(diào)優(yōu)幾件必須知道的事有哪些

發(fā)布時(shí)間:2021-10-20 18:05:16 來(lái)源:億速云 閱讀:193 作者:柒染 欄目:大數(shù)據(jù)

關(guān)于ES性能調(diào)優(yōu)幾件必須知道的事有哪些,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

(零)ElasticSearch架構(gòu)概述

ElasticSearch是現(xiàn)在技術(shù)前沿的大數(shù)據(jù)引擎,常見的組合有ES+Logstash+Kibana作為一套成熟的日志系統(tǒng),其中Logstash是ETL工具,Kibana是數(shù)據(jù)分析展示平臺(tái)。ES讓人驚艷的是他強(qiáng)大的搜索相關(guān)能力和災(zāi)備策略,ES開放了一些接口供開發(fā)者研發(fā)自己的插件,ES結(jié)合中文分詞的插件會(huì)給ES的搜索和分析起到很大的推動(dòng)作用。ElasticSearch是使用開源全文檢索庫(kù)ApacheLucene進(jìn)行索引和搜索的,說(shuō)架構(gòu)必須和Lucene的一些東西打交道。

關(guān)于Lucene:

ApacheLucene將寫入索引的所有信息組織成一種倒排索引(Inverted Index)的結(jié)構(gòu)之中,該結(jié)構(gòu)是種將詞項(xiàng)映射到文檔的數(shù)據(jù)結(jié)構(gòu)。其工作方式與傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)不同,大致來(lái)說(shuō)倒排索引是面向詞項(xiàng)而不是面向文檔的。且Lucene索引之中還存儲(chǔ)了很多其他的信息,如詞向量等等,每個(gè)Lucene都是由多個(gè)段構(gòu)成的,每個(gè)段只會(huì)被創(chuàng)建一次但會(huì)被查詢多次,段一旦創(chuàng)建就不會(huì)再被修改。多個(gè)段會(huì)在段合并的階段合并在一起,何時(shí)合并由Lucene的內(nèi)在機(jī)制決定,段合并后數(shù)量會(huì)變少,但是相應(yīng)的段本身會(huì)變大。段合并的過(guò)程是非常消耗I/O的,且與之同時(shí)會(huì)有些不再使用的信息被清理掉。在Lucene中,將數(shù)據(jù)轉(zhuǎn)化為倒排索引,將完整串轉(zhuǎn)化為可用于搜索的詞項(xiàng)的過(guò)程叫做分析。文本分析由分析器(Analyzer)來(lái)執(zhí)行,分析其由分詞器(Tokenizer),過(guò)濾器(Filter)和字符映射器(Character Mapper)組成,其各個(gè)功能顯而易見。除此之外,Lucene有自己的一套完整的查詢語(yǔ)言來(lái)幫助我們進(jìn)行搜索和讀寫。

 [注]ES中的索引指的是查詢/尋址時(shí)URI中的一個(gè)字段如:[host]:[port(9200)]/[index]/[type]/[ID]?[option],而Lucene中的索引更多地和ES中的分片的概念相對(duì)應(yīng)。

回到ElasticSearch,ES的架構(gòu)遵循的設(shè)計(jì)理念有以下幾個(gè)特征:

1. 合理的默認(rèn)配置:只需修改節(jié)點(diǎn)中的Yaml配置文件,就可以迅捷配置。這和Spring4中對(duì)配置的簡(jiǎn)化有相似的地方。

2. 分布式工作模式:ES強(qiáng)大的Zen發(fā)現(xiàn)機(jī)制不僅支持組廣播也支持點(diǎn)單播,且有“知一點(diǎn)即知天下”之妙。

3. 對(duì)等架構(gòu):節(jié)點(diǎn)之間自動(dòng)備份分片,且使分片本身和樣本之間盡量”遠(yuǎn)離“,可以避免單點(diǎn)故障。且Master節(jié)點(diǎn)和Data節(jié)點(diǎn)幾乎完全等價(jià)。

4. 易于向集群擴(kuò)充新節(jié)點(diǎn):大大簡(jiǎn)化研發(fā)或運(yùn)維將新節(jié)點(diǎn)加入集群所需的工作。

5. 不對(duì)索引中的數(shù)據(jù)結(jié)構(gòu)增加任何限制:ES支持在一個(gè)索引之中存在多種數(shù)據(jù)類型。

6. 準(zhǔn)實(shí)時(shí):搜索和版本同步,由于ES是分布式應(yīng)用,一個(gè)重大的挑戰(zhàn)就是一致性問題,無(wú)論索引還是文檔數(shù)據(jù),然而事實(shí)證明ES表現(xiàn)優(yōu)秀。

(一)分片策略

選擇合適的分片數(shù)和副本數(shù)。ES的分片分為兩種,主分片(Primary Shard)和副本(Replicas)。默認(rèn)情況下,ES會(huì)為每個(gè)索引創(chuàng)建5個(gè)分片,即使是在單機(jī)環(huán)境下,這種冗余被稱作過(guò)度分配(Over Allocation),目前看來(lái)這么做完全沒有必要,僅在散布文檔到分片和處理查詢的過(guò)程中就增加了更多的復(fù)雜性,好在ES的優(yōu)秀性能掩蓋了這一點(diǎn)。假設(shè)一個(gè)索引由一個(gè)分片構(gòu)成,那么當(dāng)索引的大小超過(guò)單個(gè)節(jié)點(diǎn)的容量的時(shí)候,ES不能將索引分割成多份,因此必須在創(chuàng)建索引的時(shí)候就指定好需要的分片數(shù)量。此時(shí)我們所能做的就是創(chuàng)建一個(gè)新的索引,并在初始設(shè)定之中指定這個(gè)索引擁有更多的分片。反之如果過(guò)度分配,就增大了Lucene在合并分片查詢結(jié)果時(shí)的復(fù)雜度,從而增大了耗時(shí),所以我們得到了以下結(jié)論:

我們應(yīng)該使用最少的分片!

主分片,副本和節(jié)點(diǎn)最大數(shù)之間數(shù)量存在以下關(guān)系:

節(jié)點(diǎn)數(shù)<=主分片數(shù)*(副本數(shù)+1)

 控制分片分配行為。以上是在創(chuàng)建每個(gè)索引的時(shí)候需要考慮的優(yōu)化方法,然而在索引已創(chuàng)建好的前提下,是否就是沒有辦法從分片的角度提高了性能了呢?當(dāng)然不是,首先能做的是調(diào)整分片分配器的類型,具體是在elasticsearch.yml中設(shè)置cluster.routing.allocation.type屬性,共有兩種分片器even_shard,balanced(默認(rèn))。even_shard是盡量保證每個(gè)節(jié)點(diǎn)都具有相同數(shù)量的分片,balanced是基于可控制的權(quán)重進(jìn)行分配,相對(duì)于前一個(gè)分配器,它更暴漏了一些參數(shù)而引入調(diào)整分配過(guò)程的能力。

每次ES的分片調(diào)整都是在ES上的數(shù)據(jù)分布發(fā)生了變化的時(shí)候進(jìn)行的,最有代表性的就是有新的數(shù)據(jù)節(jié)點(diǎn)加入了集群的時(shí)候。當(dāng)然調(diào)整分片的時(shí)機(jī)并不是由某個(gè)閾值觸發(fā)的,ES內(nèi)置十一個(gè)裁決者來(lái)決定是否觸發(fā)分片調(diào)整,這里暫不贅述。另外,這些分配部署策略都是可以在運(yùn)行時(shí)更新的,更多配置分片的屬性也請(qǐng)大家自行Google。

(二)路由優(yōu)化

ES中所謂的路由和IP網(wǎng)絡(luò)不同,是一個(gè)類似于Tag的東西。在創(chuàng)建文檔的時(shí)候,可以通過(guò)字段為文檔增加一個(gè)路由屬性的Tag。ES內(nèi)在機(jī)制決定了擁有相同路由屬性的文檔,一定會(huì)被分配到同一個(gè)分片上,無(wú)論是主分片還是副本。那么,在查詢的過(guò)程中,一旦指定了感興趣的路由屬性,ES就可以直接到相應(yīng)的分片所在的機(jī)器上進(jìn)行搜索,而避免了復(fù)雜的分布式協(xié)同的一些工作,從而提升了ES的性能。于此同時(shí),假設(shè)機(jī)器1上存有路由屬性A的文檔,機(jī)器2上存有路由屬性為B的文檔,那么我在查詢的時(shí)候一旦指定目標(biāo)路由屬性為A,即使機(jī)器2故障癱瘓,對(duì)機(jī)器1構(gòu)不成很大影響,所以這么做對(duì)災(zāi)況下的查詢也提出了解決方案。所謂的路由,本質(zhì)上是一個(gè)分桶(Bucketing)操作。當(dāng)然,查詢中也可以指定多個(gè)路由屬性,機(jī)制大同小異。

(三)ES上的GC調(diào)優(yōu)

ElasticSearch本質(zhì)上是個(gè)Java程序,所以配置JVM垃圾回收器本身也是一個(gè)很有意義的工作。我們使用JVM的Xms和Xmx參數(shù)來(lái)提供指定內(nèi)存大小,本質(zhì)上提供的是JVM的堆空間大小,當(dāng)JVM的堆空間不足的時(shí)候就會(huì)觸發(fā)致命的OutOfMemoryException。這意味著要么內(nèi)存不足,要么出現(xiàn)了內(nèi)存泄露。處理GC問題,首先要確定問題的源頭,一般有兩種方案:

1. 開啟ElasticSearch上的GC日志

2. 使用jstat命令

3. 生成內(nèi)存Dump

關(guān)于第一條,在ES的配置文件elasticsearch.yml中有相關(guān)的屬性可以配置,關(guān)于每個(gè)屬性的用途這里當(dāng)然說(shuō)不完。

第二條,jstat命令可以幫助我們查看JVM堆中各個(gè)區(qū)的使用情況和GC的耗時(shí)情況。

第三條,最后的辦法就是將JVM的堆空間轉(zhuǎn)儲(chǔ)到文件中去,實(shí)質(zhì)上是對(duì)JVM堆空間的一個(gè)快照。

想了解更多關(guān)于JVM本身GC調(diào)優(yōu)方法請(qǐng)參考:http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

另外,通過(guò)修改ES節(jié)點(diǎn)的啟動(dòng)參數(shù),也可以調(diào)整GC的方式,但是實(shí)質(zhì)上和上述方法是等同的。

(四)避免內(nèi)存交換

這一點(diǎn)很簡(jiǎn)單,由于操作系統(tǒng)的虛擬內(nèi)存頁(yè)交換機(jī)制,會(huì)給性能帶來(lái)障礙,如數(shù)據(jù)寫滿內(nèi)存會(huì)寫入Linux中的Swap分區(qū)。

可以通過(guò)在elasticsearch.yml文件中的bootstrap.mlockall設(shè)置為true來(lái)實(shí)現(xiàn),但是需要管理員權(quán)限,需要修改操作系統(tǒng)的相關(guān)配置文件。

(五)控制索引合并

上文提到過(guò),ES中的分片和副本本質(zhì)上都是Lucene索引,而Lucene索引又基于多個(gè)索引段構(gòu)建(至少一個(gè)),索引文件中的絕大多數(shù)都是只被寫一次,讀多次,在Lucene內(nèi)在機(jī)制控制下,當(dāng)滿足某種條件的時(shí)候多個(gè)索引段會(huì)被合并到一個(gè)更大的索引段,而那些舊的索引段會(huì)被拋棄并移除磁盤,這個(gè)操作叫做段合并。 

Lucene要執(zhí)行段合并的理由很簡(jiǎn)單充分:索引段粒度越小,查詢性能越低且耗費(fèi)的內(nèi)存越多。頻繁的文檔更改操作會(huì)導(dǎo)致大量的小索引段,從而導(dǎo)致文件句柄打開過(guò)多的問題,如修改系統(tǒng)配置,增大系統(tǒng)允許的最大文件打開數(shù)??偟膩?lái)講,當(dāng)索引段由多一個(gè)合并為一個(gè)的時(shí)候,會(huì)減少索引段的數(shù)量從而提高ES性能。對(duì)于研發(fā)者來(lái)講,我們所能做的就是選擇合適的合并策略,盡管段合并完全是Lucene的任務(wù),但隨著Lucene開放更多配置借口,新版本的ES還是提供了三種合并的策略tiered,log_byte_size,log_doc。另外,ES也提供了兩種Lucene索引段合并的調(diào)度器:concurrent和serial。其中各者具體區(qū)別,這里暫不贅述,只是拋磚引玉。

關(guān)于關(guān)于ES性能調(diào)優(yōu)幾件必須知道的事有哪些問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI