溫馨提示×

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

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

如何進(jìn)行Elasticsearch性能優(yōu)化

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

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)如何進(jìn)行Elasticsearch性能優(yōu)化,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Elasticsearch是目前大數(shù)據(jù)領(lǐng)域最熱門的技術(shù)棧之一,經(jīng)過(guò)近8年的發(fā)展,已從0.0.X版升級(jí)至6.X版本,雖然增加了很多的特性和功能,但是在主體架構(gòu)上,還是沒(méi)有太多的變化。下面就把我對(duì)于ES使用實(shí)踐的一些經(jīng)驗(yàn)總結(jié)一下,供大家參考;也請(qǐng)大家拍磚。

一、 硬件環(huán)境選擇:

如果有條件,盡可能使用SSD硬盤, 不錯(cuò)的CPU。ES的厲害之處在于ES本身的分布式架構(gòu)以及l(fā)ucene的特性。IO的提升,會(huì)極大改進(jìn)ES的速度和性能。

二、系統(tǒng)拓樸設(shè)計(jì):

ES集群在架構(gòu)拓樸時(shí),一般都會(huì)采用Hot-Warm的架構(gòu)模式,即設(shè)置3種不同類型的節(jié)點(diǎn):Master節(jié)點(diǎn)、Hot 節(jié)點(diǎn)和 Warm節(jié)點(diǎn)。

Master節(jié)點(diǎn)設(shè)置:一般會(huì)設(shè)置3個(gè)專用的maste節(jié)點(diǎn),以提供最好的彈性擴(kuò)展能力。當(dāng)然,必須注意discovery.zen.minimum_master_nodes 屬性的設(shè)置,以防split-brain問(wèn)題,使用公式設(shè)置:N/2+1(N為候選master節(jié)點(diǎn)數(shù))。 該節(jié)點(diǎn)保持: node.data: false ; 因?yàn)閙aster節(jié)點(diǎn)不參與查詢、索引操作,僅負(fù)責(zé)對(duì)于集群管理,所以在CPU、內(nèi)存、磁盤配置上,都可以比數(shù)據(jù)節(jié)點(diǎn)低很多。

Hot節(jié)點(diǎn)設(shè)置: 索引節(jié)點(diǎn)(寫節(jié)點(diǎn)),同時(shí)保持近期頻繁使用的索引。 屬于IO和CPU密集型操作,建議使用SSD的磁盤類型,保持良好的寫性能;節(jié)點(diǎn)的數(shù)量設(shè)置一般是大于等于3個(gè)。將節(jié)點(diǎn)設(shè)置為hot類型:

node.attr.box_type: hot

針對(duì)index, 通過(guò)設(shè)置index.routing.allocation.require.box_type: hot 可以設(shè)置將索引寫入hot節(jié)點(diǎn)。

Warm節(jié)點(diǎn)設(shè)置: 用于不經(jīng)常訪問(wèn)的read-only索引。由于不經(jīng)常訪問(wèn),一般使用普通的磁盤即可。內(nèi)存、CPU的配置跟Hot節(jié)點(diǎn)保持一致即可;節(jié)點(diǎn)數(shù)量一般也是大于等于3個(gè)。

當(dāng)索引不再被頻繁查詢時(shí),可通過(guò)index.routing.allocation.require.box_type: warm, 將索引標(biāo)記為warm, 從而保證索引不寫入hot節(jié)點(diǎn),以便將SSD磁盤資源用在刀刃上。一旦設(shè)置這個(gè)屬性,ES會(huì)自動(dòng)將索引合并到warm節(jié)點(diǎn)。同時(shí),也可以在elasticsearch.yml中設(shè)置 index.codec: best_compression 保證warm 節(jié)點(diǎn)的壓縮配置

Coordinating節(jié)點(diǎn):協(xié)調(diào)節(jié)點(diǎn)用于做分布式里的協(xié)調(diào),將各分片或節(jié)點(diǎn)返回的數(shù)據(jù)整合后返回。在ES集群中,所有的節(jié)點(diǎn)都有可能是協(xié)調(diào)節(jié)點(diǎn),但是,可以通過(guò)設(shè)置node.master、node.data 、 node.ingest 都為 false 來(lái)設(shè)置專門的協(xié)調(diào)節(jié)點(diǎn)。需要較好的CPU和較高的內(nèi)存。

三、ES的內(nèi)存設(shè)置:

由于ES構(gòu)建基于lucene, 而lucene設(shè)計(jì)強(qiáng)大之處在于lucene能夠很好的利用操作系統(tǒng)內(nèi)存來(lái)緩存索引數(shù)據(jù),以提供快速的查詢性能。lucene的索引文件segements是存儲(chǔ)在單文件中的,并且不可變,對(duì)于OS來(lái)說(shuō),能夠很友好地將索引文件保持在cache中,以便快速訪問(wèn);因此,我們很有必要將一半的物理內(nèi)存留給lucene ; 另一半的物理內(nèi)存留給ES(JVM heap )。所以, 在ES內(nèi)存設(shè)置方面,可以遵循以下原則:

1. 當(dāng)機(jī)器內(nèi)存小于64G時(shí),遵循通用的原則,50%給ES,50%留給lucene。

2.  當(dāng)機(jī)器內(nèi)存大于64G時(shí),遵循以下原則:

a. 如果主要的使用場(chǎng)景是全文檢索, 那么建議給ES Heap分配 4~32G的內(nèi)存即可;其它內(nèi)存留給操作系統(tǒng), 供lucene使用(segments cache), 以提供更快的查詢性能。

b.  如果主要的使用場(chǎng)景是聚合或排序, 并且大多數(shù)是numerics, dates, geo_points 以及not_analyzed的字符類型, 建議分配給ES Heap分配 4~32G的內(nèi)存即可,其它內(nèi)存留給操作系統(tǒng),供lucene使用(doc values cache),提供快速的基于文檔的聚類、排序性能。

c.  如果使用場(chǎng)景是聚合或排序,并且都是基于analyzed 字符數(shù)據(jù),這時(shí)需要更多的 heap size, 建議機(jī)器上運(yùn)行多ES實(shí)例,每個(gè)實(shí)例保持不超過(guò)50%的ES heap設(shè)置(但不超過(guò)32G,堆內(nèi)存設(shè)置32G以下時(shí),JVM使用對(duì)象指標(biāo)壓縮技巧節(jié)省空間),50%以上留給lucene。

3. 禁止swap,一旦允許內(nèi)存與磁盤的交換,會(huì)引起致命的性能問(wèn)題。 通過(guò): 在elasticsearch.yml 中 bootstrap.memory_lock: true, 以保持JVM鎖定內(nèi)存,保證ES的性能。

4. GC設(shè)置原則:

a. 保持GC的現(xiàn)有設(shè)置,默認(rèn)設(shè)置為:Concurrent-Mark and Sweep (CMS),別換成G1GC,因?yàn)槟壳癎1還有很多BUG。

b. 保持線程池的現(xiàn)有設(shè)置,目前ES的線程池較1.X有了較多優(yōu)化設(shè)置,保持現(xiàn)狀即可;默認(rèn)線程池大小等于CPU核心數(shù)。如果一定要改,按公式((CPU核心數(shù)* 3)/ 2)+ 1 設(shè)置;不能超過(guò)CPU核心數(shù)的2倍;但是不建議修改默認(rèn)配置,否則會(huì)對(duì)CPU造成硬傷。

四、 集群分片設(shè)置:

ES一旦創(chuàng)建好索引后,就無(wú)法調(diào)整分片的設(shè)置,而在ES中,一個(gè)分片實(shí)際上對(duì)應(yīng)一個(gè)lucene 索引,而lucene索引的讀寫會(huì)占用很多的系統(tǒng)資源,因此,分片數(shù)不能設(shè)置過(guò)大;所以,在創(chuàng)建索引時(shí),合理配置分片數(shù)是非常重要的。一般來(lái)說(shuō),我們遵循一些原則:

1. 控制每個(gè)分片占用的硬盤容量不超過(guò)ES的最大JVM的堆空間設(shè)置(一般設(shè)置不超過(guò)32G,參加上文的JVM設(shè)置原則),因此,如果索引的總?cè)萘吭?00G左右,那分片大小在16個(gè)左右即可;當(dāng)然,最好同時(shí)考慮原則2。

2. 考慮一下node數(shù)量,一般一個(gè)節(jié)點(diǎn)有時(shí)候就是一臺(tái)物理機(jī),如果分片數(shù)過(guò)多,大大超過(guò)了節(jié)點(diǎn)數(shù),很可能會(huì)導(dǎo)致一個(gè)節(jié)點(diǎn)上存在多個(gè)分片,一旦該節(jié)點(diǎn)故障,即使保持了1個(gè)以上的副本,同樣有可能會(huì)導(dǎo)致數(shù)據(jù)丟失,集群無(wú)法恢復(fù)。所以, 一般都設(shè)置分片數(shù)不超過(guò)節(jié)點(diǎn)數(shù)的3倍。

五、 Mapping建模:

1. 盡量避免使用nested或 parent/child,能不用就不用;nested query慢, parent/child query 更慢,比nested query慢上百倍;因此能在mapping設(shè)計(jì)階段搞定的(大寬表設(shè)計(jì)或采用比較smart的數(shù)據(jù)結(jié)構(gòu)),就不要用父子關(guān)系的mapping。

2. 如果一定要使用nested fields,保證nested fields字段不能過(guò)多,目前ES默認(rèn)限制是50。參考:

index.mapping.nested_fields.limit :50

因?yàn)獒槍?duì)1個(gè)document, 每一個(gè)nested field, 都會(huì)生成一個(gè)獨(dú)立的document, 這將使Doc數(shù)量劇增,影響查詢效率,尤其是JOIN的效率。

3. 避免使用動(dòng)態(tài)值作字段(key),  動(dòng)態(tài)遞增的mapping,會(huì)導(dǎo)致集群崩潰;同樣,也需要控制字段的數(shù)量,業(yè)務(wù)中不使用的字段,就不要索引??刂扑饕淖侄螖?shù)量、mapping深度、索引字段的類型,對(duì)于ES的性能優(yōu)化是重中之重。以下是ES關(guān)于字段數(shù)、mapping深度的一些默認(rèn)設(shè)置:

index.mapping.nested_objects.limit :10000

index.mapping.total_fields.limit:1000

index.mapping.depth.limit: 20

六、 索引優(yōu)化設(shè)置:

1.設(shè)置refresh_interval 為-1,同時(shí)設(shè)置number_of_replicas 為0,通過(guò)關(guān)閉refresh間隔周期,同時(shí)不設(shè)置副本來(lái)提高寫性能。

2. 修改index_buffer_size 的設(shè)置,可以設(shè)置成百分?jǐn)?shù),也可設(shè)置成具體的大小,大小可根據(jù)集群的規(guī)模做不同的設(shè)置測(cè)試。

indices.memory.index_buffer_size:10%(默認(rèn))

indices.memory.min_index_buffer_size: 48mb(默認(rèn))

indices.memory.max_index_buffer_size

3. 修改translog相關(guān)的設(shè)置:

a. 控制數(shù)據(jù)從內(nèi)存到硬盤的操作頻率,以減少硬盤IO??蓪ync_interval的時(shí)間設(shè)置大一些。

index.translog.sync_interval:5s(默認(rèn))。

b. 控制tranlog數(shù)據(jù)塊的大小,達(dá)到threshold大小時(shí),才會(huì)flush到lucene索引文件。

index.translog.flush_threshold_size:512mb(默認(rèn))

4. _id字段的使用,應(yīng)盡可能避免自定義_id, 以避免針對(duì)ID的版本管理;建議使用ES的默認(rèn)ID生成策略或使用數(shù)字類型ID做為主鍵。

5. _all字段及_source字段的使用,應(yīng)該注意場(chǎng)景和需要,_all字段包含了所有的索引字段,方便做全文檢索,如果無(wú)此需求,可以禁用;_source存儲(chǔ)了原始的document內(nèi)容,如果沒(méi)有獲取原始文檔數(shù)據(jù)的需求,可通過(guò)設(shè)置includes、excludes 屬性來(lái)定義放入_source的字段。

6. 合理的配置使用index屬性,analyzed 和not_analyzed,根據(jù)業(yè)務(wù)需求來(lái)控制字段是否分詞或不分詞。只有 groupby需求的字段,配置時(shí)就設(shè)置成not_analyzed, 以提高查詢或聚類的效率。

七、 查詢優(yōu)化:

1. query_string 或 multi_match的查詢字段越多, 查詢?cè)铰?梢栽趍apping階段,利用copy_to屬性將多字段的值索引到一個(gè)新字段,multi_match時(shí),用新的字段查詢。

2. 日期字段的查詢, 尤其是用now 的查詢實(shí)際上是不存在緩存的,因此, 可以從業(yè)務(wù)的角度來(lái)考慮是否一定要用now, 畢竟利用query cache 是能夠大大提高查詢效率的。

3. 查詢結(jié)果集的大小不能隨意設(shè)置成大得離譜的值, 如query.setSize不能設(shè)置成 Integer.MAX_VALUE, 因?yàn)镋S內(nèi)部需要建立一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)放指定大小的結(jié)果集數(shù)據(jù)。

4. 盡量避免使用script,萬(wàn)不得已需要使用的話,選擇painless & experssions 引擎。一旦使用script查詢,一定要注意控制返回,千萬(wàn)不要有死循環(huán)(如下錯(cuò)誤的例子),因?yàn)镋S沒(méi)有腳本運(yùn)行的超時(shí)控制,只要當(dāng)前的腳本沒(méi)執(zhí)行完,該查詢會(huì)一直阻塞。

如: {

    “script_fields”:{

        “test1”:{

            “l(fā)ang”:“groovy”,

            “script”:“while(true){print 'don’t use script'}”

        }

    }

}

5. 避免層級(jí)過(guò)深的聚合查詢, 層級(jí)過(guò)深的group by , 會(huì)導(dǎo)致內(nèi)存、CPU消耗,建議在服務(wù)層通過(guò)程序來(lái)組裝業(yè)務(wù),也可以通過(guò)pipeline的方式來(lái)優(yōu)化。

6. 復(fù)用預(yù)索引數(shù)據(jù)方式來(lái)提高AGG性能:

如通過(guò) terms aggregations 替代 range aggregations, 如要根據(jù)年齡來(lái)分組,分組目標(biāo)是: 少年(14歲以下) 青年(14-28) 中年(29-50) 老年(51以上), 可以在索引的時(shí)候設(shè)置一個(gè)age_group字段,預(yù)先將數(shù)據(jù)進(jìn)行分類。從而不用按age來(lái)做range aggregations, 通過(guò)age_group字段就可以了。

7. Cache的設(shè)置及使用:

a) QueryCache: ES查詢的時(shí)候,使用filter查詢會(huì)使用query cache, 如果業(yè)務(wù)場(chǎng)景中的過(guò)濾查詢比較多,建議將querycache設(shè)置大一些,以提高查詢速度。

indices.queries.cache.size: 10%(默認(rèn)),可設(shè)置成百分比,也可設(shè)置成具體值,如256mb。

當(dāng)然也可以禁用查詢緩存(默認(rèn)是開啟), 通過(guò)index.queries.cache.enabled:false設(shè)置。

b) FieldDataCache: 在聚類或排序時(shí),field data cache會(huì)使用頻繁,因此,設(shè)置字段數(shù)據(jù)緩存的大小,在聚類或排序場(chǎng)景較多的情形下很有必要,可通過(guò)indices.fielddata.cache.size:30% 或具體值10GB來(lái)設(shè)置。但是如果場(chǎng)景或數(shù)據(jù)變更比較頻繁,設(shè)置cache并不是好的做法,因?yàn)榫彺婕虞d的開銷也是特別大的。

c) ShardRequestCache: 查詢請(qǐng)求發(fā)起后,每個(gè)分片會(huì)將結(jié)果返回給協(xié)調(diào)節(jié)點(diǎn)(Coordinating Node), 由協(xié)調(diào)節(jié)點(diǎn)將結(jié)果整合。

如果有需求,可以設(shè)置開啟;  通過(guò)設(shè)置index.requests.cache.enable: true來(lái)開啟。

不過(guò),shard request cache只緩存hits.total, aggregations, suggestions類型的數(shù)據(jù),并不會(huì)緩存hits的內(nèi)容。也可以通過(guò)設(shè)置indices.requests.cache.size: 1%(默認(rèn))來(lái)控制緩存空間大小。

上述就是小編為大家分享的如何進(jìn)行Elasticsearch性能優(yōu)化了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(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