成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Elasticsearch 性能優(yōu)化詳解

開(kāi)發(fā) 前端
ES 一旦創(chuàng)建好索引后,就無(wú)法調(diào)整分片的設(shè)置,而在 ES 中,一個(gè)分片實(shí)際上對(duì)應(yīng)一個(gè) lucene 索引,而 lucene 索引的讀寫(xiě)會(huì)占用很多的系統(tǒng)資源,因此,分片數(shù)不能設(shè)置過(guò)大;

硬件配置優(yōu)化

升級(jí)硬件設(shè)備配置一直都是提高服務(wù)能力最快速有效的手段,在系統(tǒng)層面能夠影響應(yīng)用性能的一般包括三個(gè)因素:CPU、內(nèi)存和 IO,可以從這三方面進(jìn)行 ES 的性能優(yōu)化工作。

CPU 配置

一般說(shuō)來(lái),CPU 繁忙的原因有以下幾個(gè):

  • 線(xiàn)程中有無(wú)限空循環(huán)、無(wú)阻塞、正則匹配或者單純的計(jì)算;
  • 發(fā)生了頻繁的 GC;
  • 多線(xiàn)程的上下文切換;

大多數(shù) Elasticsearch 部署往往對(duì) CPU 要求不高。因此,相對(duì)其它資源,具體配置多少個(gè)(CPU)不是那么關(guān)鍵。你應(yīng)該選擇具有多個(gè)內(nèi)核的現(xiàn)代處理器,常見(jiàn)的集群使用 2 到 8 個(gè)核的機(jī)器。如果你要在更快的 CPUs 和更多的核數(shù)之間選擇,選擇更多的核數(shù)更好。多個(gè)內(nèi)核提供的額外并發(fā)遠(yuǎn)勝過(guò)稍微快一點(diǎn)點(diǎn)的時(shí)鐘頻率。

內(nèi)存配置

如果有一種資源是最先被耗盡的,它可能是內(nèi)存。排序和聚合都很耗內(nèi)存,所以有足夠的堆空間來(lái)應(yīng)付它們是很重要的。即使堆空間是比較小的時(shí)候,也能為操作系統(tǒng)文件緩存提供額外的內(nèi)存。因?yàn)?Lucene 使用的許多數(shù)據(jù)結(jié)構(gòu)是基于磁盤(pán)的格式,Elasticsearch 利用操作系統(tǒng)緩存能產(chǎn)生很大效果。

64 GB 內(nèi)存的機(jī)器是非常理想的,但是 32 GB 和 16 GB 機(jī)器也是很常見(jiàn)的。少于8 GB 會(huì)適得其反(你最終需要很多很多的小機(jī)器),大于 64 GB 的機(jī)器也會(huì)有問(wèn)題。

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

內(nèi)存分配

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

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

  • 如果主要的使用場(chǎng)景是全文檢索,那么建議給 ES Heap 分配 4~32G 的內(nèi)存即可;其它內(nèi)存留給操作系統(tǒng),供 lucene 使用(segments cache),以提供更快的查詢(xún)性能。
  • 如果主要的使用場(chǎng)景是聚合或排序,并且大多數(shù)是 numerics,dates,geo_points 以及 not_analyzed 的字符類(lèi)型,建議分配給 ES Heap 分配 4~32G 的內(nèi)存即可,其它內(nèi)存留給操作系統(tǒng),供 lucene 使用,提供快速的基于文檔的聚類(lèi)、排序性能。
  • 如果使用場(chǎng)景是聚合或排序,并且都是基于 analyzed 字符數(shù)據(jù),這時(shí)需要更多的 heap size,建議機(jī)器上運(yùn)行多 ES 實(shí)例,每個(gè)實(shí)例保持不超過(guò) 50% 的 ES heap 設(shè)置(但不超過(guò) 32 G,堆內(nèi)存設(shè)置 32 G 以下時(shí),JVM 使用對(duì)象指標(biāo)壓縮技巧節(jié)省空間),50% 以上留給 lucene。

禁止 swap

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

GC 設(shè)置

老的版本中官方文檔 中推薦默認(rèn)設(shè)置為:Concurrent-Mark and Sweep(CMS),給的理由是當(dāng)時(shí)G1 還有很多 BUG。

原因是:已知JDK 8附帶的HotSpot JVM的早期版本存在一些問(wèn)題,當(dāng)啟用G1GC收集器時(shí),這些問(wèn)題可能導(dǎo)致索引損壞。受影響的版本早于JDK 8u40隨附的HotSpot版本。來(lái)源于官方說(shuō)明

實(shí)際上如果你使用的JDK8較高版本,或者JDK9+,我推薦你使用G1 GC;因?yàn)槲覀兡壳暗捻?xiàng)目使用的就是G1 GC,運(yùn)行效果良好,對(duì)Heap大對(duì)象優(yōu)化尤為明顯。修改jvm.options文件,將下面幾行:

-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly

更改為

-XX:+UseG1GC
-XX:MaxGCPauseMillis=50

其中 -XX:MaxGCPauseMillis是控制預(yù)期的最高GC時(shí)長(zhǎng),默認(rèn)值為200ms,如果線(xiàn)上業(yè)務(wù)特性對(duì)于GC停頓非常敏感,可以適當(dāng)設(shè)置低一些。但是 這個(gè)值如果設(shè)置過(guò)小,可能會(huì)帶來(lái)比較高的cpu消耗。

G1對(duì)于集群正常運(yùn)作的情況下減輕G1停頓對(duì)服務(wù)時(shí)延的影響還是很有效的,但是如果是你描述的GC導(dǎo)致集群卡死,那么很有可能換G1也無(wú)法根本上解決問(wèn)題。通常都是集群的數(shù)據(jù)模型或者Query需要優(yōu)化。

磁盤(pán)

硬盤(pán)對(duì)所有的集群都很重要,對(duì)大量寫(xiě)入的集群更是加倍重要(例如那些存儲(chǔ)日志數(shù)據(jù)的)。硬盤(pán)是服務(wù)器上最慢的子系統(tǒng),這意味著那些寫(xiě)入量很大的集群很容易讓硬盤(pán)飽和,使得它成為集群的瓶頸。

在經(jīng)濟(jì)壓力能承受的范圍下,盡量使用固態(tài)硬盤(pán)(SSD)。固態(tài)硬盤(pán)相比于任何旋轉(zhuǎn)介質(zhì)(機(jī)械硬盤(pán),磁帶等),無(wú)論隨機(jī)寫(xiě)還是順序?qū)懀紩?huì)對(duì) IO 有較大的提升。

  1. 如果你正在使用 SSDs,確保你的系統(tǒng) I/O 調(diào)度程序是配置正確的。當(dāng)你向硬盤(pán)寫(xiě)數(shù)據(jù),I/O 調(diào)度程序決定何時(shí)把數(shù)據(jù)實(shí)際發(fā)送到硬盤(pán)。大多數(shù)默認(rèn) *nix 發(fā)行版下的調(diào)度程序都叫做 cfq(完全公平隊(duì)列)。
  2. 調(diào)度程序分配時(shí)間片到每個(gè)進(jìn)程。并且優(yōu)化這些到硬盤(pán)的眾多隊(duì)列的傳遞。但它是為旋轉(zhuǎn)介質(zhì)優(yōu)化的:機(jī)械硬盤(pán)的固有特性意味著它寫(xiě)入數(shù)據(jù)到基于物理布局的硬盤(pán)會(huì)更高效。
  3. 這對(duì) SSD 來(lái)說(shuō)是低效的,盡管這里沒(méi)有涉及到機(jī)械硬盤(pán)。但是,deadline 或者 noop 應(yīng)該被使用。deadline 調(diào)度程序基于寫(xiě)入等待時(shí)間進(jìn)行優(yōu)化,noop 只是一個(gè)簡(jiǎn)單的 FIFO 隊(duì)列。

這個(gè)簡(jiǎn)單的更改可以帶來(lái)顯著的影響。僅僅是使用正確的調(diào)度程序,我們看到了 500 倍的寫(xiě)入能力提升。

如果你使用旋轉(zhuǎn)介質(zhì)(如機(jī)械硬盤(pán)),嘗試獲取盡可能快的硬盤(pán)(高性能服務(wù)器硬盤(pán),15k RPM 驅(qū)動(dòng)器)。

使用 RAID0 是提高硬盤(pán)速度的有效途徑,對(duì)機(jī)械硬盤(pán)和 SSD 來(lái)說(shuō)都是如此。沒(méi)有必要使用鏡像或其它 RAID 變體,因?yàn)?Elasticsearch 在自身層面通過(guò)副本,已經(jīng)提供了備份的功能,所以不需要利用磁盤(pán)的備份功能,同時(shí)如果使用磁盤(pán)備份功能的話(huà),對(duì)寫(xiě)入速度有較大的影響。

最后,避免使用網(wǎng)絡(luò)附加存儲(chǔ)(NAS)。人們常聲稱(chēng)他們的 NAS 解決方案比本地驅(qū)動(dòng)器更快更可靠。除卻這些聲稱(chēng),我們從沒(méi)看到 NAS 能配得上它的大肆宣傳。NAS 常常很慢,顯露出更大的延時(shí)和更寬的平均延時(shí)方差,而且它是單點(diǎn)故障的。

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

索引優(yōu)化主要是在 Elasticsearch 的插入層面優(yōu)化,Elasticsearch 本身索引速度其實(shí)還是蠻快的,具體數(shù)據(jù),我們可以參考官方的 benchmark 數(shù)據(jù)。我們可以根據(jù)不同的需求,針對(duì)索引優(yōu)化。

批量提交

當(dāng)有大量數(shù)據(jù)提交的時(shí)候,建議采用批量提交(Bulk 操作);此外使用 bulk 請(qǐng)求時(shí),每個(gè)請(qǐng)求不超過(guò)幾十M,因?yàn)樘髸?huì)導(dǎo)致內(nèi)存使用過(guò)大。

比如在做 ELK 過(guò)程中,Logstash indexer 提交數(shù)據(jù)到 Elasticsearch 中,batch size 就可以作為一個(gè)優(yōu)化功能點(diǎn)。但是優(yōu)化 size 大小需要根據(jù)文檔大小和服務(wù)器性能而定。

像 Logstash 中提交文檔大小超過(guò) 20MB,Logstash 會(huì)將一個(gè)批量請(qǐng)求切分為多個(gè)批量請(qǐng)求。

如果在提交過(guò)程中,遇到 EsRejectedExecutionException 異常的話(huà),則說(shuō)明集群的索引性能已經(jīng)達(dá)到極限了。這種情況,要么提高服務(wù)器集群的資源,要么根據(jù)業(yè)務(wù)規(guī)則,減少數(shù)據(jù)收集速度,比如只收集 Warn、Error 級(jí)別以上的日志。

增加 Refresh 時(shí)間間隔

為了提高索引性能,Elasticsearch 在寫(xiě)入數(shù)據(jù)的時(shí)候,采用延遲寫(xiě)入的策略,即數(shù)據(jù)先寫(xiě)到內(nèi)存中,當(dāng)超過(guò)默認(rèn)1秒(index.refresh_interval)會(huì)進(jìn)行一次寫(xiě)入操作,就是將內(nèi)存中 segment 數(shù)據(jù)刷新到磁盤(pán)中,此時(shí)我們才能將數(shù)據(jù)搜索出來(lái),所以這就是為什么 Elasticsearch 提供的是近實(shí)時(shí)搜索功能,而不是實(shí)時(shí)搜索功能。

如果我們的系統(tǒng)對(duì)數(shù)據(jù)延遲要求不高的話(huà),我們可以通過(guò)延長(zhǎng) refresh 時(shí)間間隔,可以有效地減少 segment 合并壓力,提高索引速度。比如在做全鏈路跟蹤的過(guò)程中,我們就將 index.refresh_interval 設(shè)置為30s,減少 refresh 次數(shù)。再如,在進(jìn)行全量索引時(shí),可以將 refresh 次數(shù)臨時(shí)關(guān)閉,即 index.refresh_interval 設(shè)置為-1,數(shù)據(jù)導(dǎo)入成功后再打開(kāi)到正常模式,比如30s。

在加載大量數(shù)據(jù)時(shí)候可以暫時(shí)不用 refresh 和 repliccas,index.refresh_interval 設(shè)置為-1,index.number_of_replicas 設(shè)置為0。

相關(guān)原理,請(qǐng)參考[原理:ES原理之索引文檔流程詳解]

修改 index_buffer_size 的設(shè)置

索引緩沖的設(shè)置可以控制多少內(nèi)存分配給索引進(jìn)程。這是一個(gè)全局配置,會(huì)應(yīng)用于一個(gè)節(jié)點(diǎn)上所有不同的分片上。

indices.memory.index_buffer_size: 10%
indices.memory.min_index_buffer_size: 48mb

indices.memory.index_buffer_size 接受一個(gè)百分比或者一個(gè)表示字節(jié)大小的值。默認(rèn)是10%,意味著分配給節(jié)點(diǎn)的總內(nèi)存的10%用來(lái)做索引緩沖的大小。這個(gè)數(shù)值被分到不同的分片(shards)上。如果設(shè)置的是百分比,還可以設(shè)置 min_index_buffer_size (默認(rèn) 48mb)和 max_index_buffer_size(默認(rèn)沒(méi)有上限)。

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

一是控制數(shù)據(jù)從內(nèi)存到硬盤(pán)的操作頻率,以減少硬盤(pán) IO。可將 sync_interval 的時(shí)間設(shè)置大一些。默認(rèn)為5s。

index.translog.sync_interval: 5s

也可以控制 tranlog 數(shù)據(jù)塊的大小,達(dá)到 threshold 大小時(shí),才會(huì) flush 到 lucene 索引文件。默認(rèn)為512m。

index.translog.flush_threshold_size: 512mb

translog我們?cè)赱原理:ES原理之索引文檔流程詳解]也有介紹。

注意 _id 字段的使用

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

注意 _all 字段及 _source 字段的使用

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

合理的配置使用 index 屬性

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

減少副本數(shù)量

Elasticsearch 默認(rèn)副本數(shù)量為3個(gè),雖然這樣會(huì)提高集群的可用性,增加搜索的并發(fā)數(shù),但是同時(shí)也會(huì)影響寫(xiě)入索引的效率。

在索引過(guò)程中,需要把更新的文檔發(fā)到副本節(jié)點(diǎn)上,等副本節(jié)點(diǎn)生效后在進(jìn)行返回結(jié)束。使用 Elasticsearch 做業(yè)務(wù)搜索的時(shí)候,建議副本數(shù)目還是設(shè)置為3個(gè),但是像內(nèi)部 ELK 日志系統(tǒng)、分布式跟蹤系統(tǒng)中,完全可以將副本數(shù)目設(shè)置為1個(gè)。

查詢(xún)方面優(yōu)化

Elasticsearch 作為業(yè)務(wù)搜索的近實(shí)時(shí)查詢(xún)時(shí),查詢(xún)效率的優(yōu)化顯得尤為重要。

路由優(yōu)化

當(dāng)我們查詢(xún)文檔的時(shí)候,Elasticsearch 如何知道一個(gè)文檔應(yīng)該存放到哪個(gè)分片中呢?它其實(shí)是通過(guò)下面這個(gè)公式來(lái)計(jì)算出來(lái)的。

shard = hash(routing) % number_of_primary_shards

routing 默認(rèn)值是文檔的 id,也可以采用自定義值,比如用戶(hù) ID。

不帶 routing 查詢(xún)

在查詢(xún)的時(shí)候因?yàn)椴恢酪樵?xún)的數(shù)據(jù)具體在哪個(gè)分片上,所以整個(gè)過(guò)程分為2個(gè)步驟:

  • 分發(fā):請(qǐng)求到達(dá)協(xié)調(diào)節(jié)點(diǎn)后,協(xié)調(diào)節(jié)點(diǎn)將查詢(xún)請(qǐng)求分發(fā)到每個(gè)分片上。
  • 聚合:協(xié)調(diào)節(jié)點(diǎn)搜集到每個(gè)分片上查詢(xún)結(jié)果,再將查詢(xún)的結(jié)果進(jìn)行排序,之后給用戶(hù)返回結(jié)果。

帶 routing 查詢(xún)

查詢(xún)的時(shí)候,可以直接根據(jù) routing 信息定位到某個(gè)分配查詢(xún),不需要查詢(xún)所有的分配,經(jīng)過(guò)協(xié)調(diào)節(jié)點(diǎn)排序。

向上面自定義的用戶(hù)查詢(xún),如果 routing 設(shè)置為 userid 的話(huà),就可以直接查詢(xún)出數(shù)據(jù)來(lái),效率提升很多。

Filter VS Query

盡可能使用過(guò)濾器上下文(Filter)替代查詢(xún)上下文(Query)

  • Query:此文檔與此查詢(xún)子句的匹配程度如何?
  • Filter:此文檔和查詢(xún)子句匹配嗎?

Elasticsearch 針對(duì) Filter 查詢(xún)只需要回答「是」或者「否」,不需要像 Query 查詢(xún)一樣計(jì)算相關(guān)性分?jǐn)?shù),同時(shí)Filter結(jié)果可以緩存。

深度翻頁(yè)

在使用 Elasticsearch 過(guò)程中,應(yīng)盡量避免大翻頁(yè)的出現(xiàn)。

正常翻頁(yè)查詢(xún)都是從 from 開(kāi)始 size 條數(shù)據(jù),這樣就需要在每個(gè)分片中查詢(xún)打分排名在前面的 from+size 條數(shù)據(jù)。協(xié)同節(jié)點(diǎn)收集每個(gè)分配的前 from+size 條數(shù)據(jù)。協(xié)同節(jié)點(diǎn)一共會(huì)受到 N*(from+size) 條數(shù)據(jù),然后進(jìn)行排序,再將其中 from 到 from+size 條數(shù)據(jù)返回出去。如果 from 或者 size 很大的話(huà),導(dǎo)致參加排序的數(shù)量會(huì)同步擴(kuò)大很多,最終會(huì)導(dǎo)致 CPU 資源消耗增大。

可以通過(guò)使用 Elasticsearch scroll 和 scroll-scan 高效滾動(dòng)的方式來(lái)解決這樣的問(wèn)題。

也可以結(jié)合實(shí)際業(yè)務(wù)特點(diǎn),文檔 id 大小如果和文檔創(chuàng)建時(shí)間是一致有序的,可以以文檔 id 作為分頁(yè)的偏移量,并將其作為分頁(yè)查詢(xún)的一個(gè)條件。

腳本(script)合理使用

我們知道腳本使用主要有 3 種形式,內(nèi)聯(lián)動(dòng)態(tài)編譯方式、_script 索引庫(kù)中存儲(chǔ)和文件腳本存儲(chǔ)的形式;一般腳本的使用場(chǎng)景是粗排,盡量用第二種方式先將腳本存儲(chǔ)在 _script 索引庫(kù)中,起到提前編譯,然后通過(guò)引用腳本 id,并結(jié)合 params 參數(shù)使用,即可以達(dá)到模型(邏輯)和數(shù)據(jù)進(jìn)行了分離,同時(shí)又便于腳本模塊的擴(kuò)展與維護(hù)。

Cache的設(shè)置及使用

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

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

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

  • FieldDataCache: 在聚類(lèi)或排序時(shí),field data cache會(huì)使用頻繁,因此,設(shè)置字段數(shù)據(jù)緩存的大小,在聚類(lèi)或排序場(chǎng)景較多的情形下很有必要,可通過(guò)indices.fielddata.cache.size:30% 或具體值10GB來(lái)設(shè)置。但是如果場(chǎng)景或數(shù)據(jù)變更比較頻繁,設(shè)置cache并不是好的做法,因?yàn)榫彺婕虞d的開(kāi)銷(xiāo)也是特別大的。
  • ShardRequestCache: 查詢(xún)請(qǐng)求發(fā)起后,每個(gè)分片會(huì)將結(jié)果返回給協(xié)調(diào)節(jié)點(diǎn)(Coordinating Node), 由協(xié)調(diào)節(jié)點(diǎn)將結(jié)果整合。如果有需求,可以設(shè)置開(kāi)啟; 通過(guò)設(shè)置index.requests.cache.enable: true來(lái)開(kāi)啟。不過(guò),shard request cache只緩存hits.total, aggregations, suggestions類(lèi)型的數(shù)據(jù),并不會(huì)緩存hits的內(nèi)容。也可以通過(guò)設(shè)置indices.requests.cache.size: 1%(默認(rèn))來(lái)控制緩存空間大小。

更多查詢(xún)優(yōu)化經(jīng)驗(yàn)

  • query_string 或 multi_match的查詢(xún)字段越多, 查詢(xún)?cè)铰?梢栽趍apping階段,利用copy_to屬性將多字段的值索引到一個(gè)新字段,multi_match時(shí),用新的字段查詢(xún)。
  • 日期字段的查詢(xún), 尤其是用now 的查詢(xún)實(shí)際上是不存在緩存的,因此, 可以從業(yè)務(wù)的角度來(lái)考慮是否一定要用now, 畢竟利用query cache 是能夠大大提高查詢(xún)效率的。
  • 查詢(xún)結(jié)果集的大小不能隨意設(shè)置成大得離譜的值, 如query.setSize不能設(shè)置成 Integer.MAX_VALUE, 因?yàn)镋S內(nèi)部需要建立一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)放指定大小的結(jié)果集數(shù)據(jù)。
  • 避免層級(jí)過(guò)深的聚合查詢(xún), 層級(jí)過(guò)深的aggregation , 會(huì)導(dǎo)致內(nèi)存、CPU消耗,建議在服務(wù)層通過(guò)程序來(lái)組裝業(yè)務(wù),也可以通過(guò)pipeline的方式來(lái)優(yōu)化。
  • 復(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)行分類(lèi)。從而不用按age來(lái)做range aggregations, 通過(guò)age_group字段就可以了。

通過(guò)開(kāi)啟慢查詢(xún)配置定位慢查詢(xún)

不論是數(shù)據(jù)庫(kù)還是搜索引擎,對(duì)于問(wèn)題的排查,開(kāi)啟慢查詢(xún)?nèi)罩臼鞘直匾模珽S 開(kāi)啟慢查詢(xún)的方式有多種,但是最常用的是調(diào)用模板 API 進(jìn)行全局設(shè)置:

PUT  /_template/{TEMPLATE_NAME}
{
 
  "template":"{INDEX_PATTERN}",
  "settings" : {
    "index.indexing.slowlog.level": "INFO",
    "index.indexing.slowlog.threshold.index.warn": "10s",
    "index.indexing.slowlog.threshold.index.info": "5s",
    "index.indexing.slowlog.threshold.index.debug": "2s",
    "index.indexing.slowlog.threshold.index.trace": "500ms",
    "index.indexing.slowlog.source": "1000",
    "index.search.slowlog.level": "INFO",
    "index.search.slowlog.threshold.query.warn": "10s",
    "index.search.slowlog.threshold.query.info": "5s",
    "index.search.slowlog.threshold.query.debug": "2s",
    "index.search.slowlog.threshold.query.trace": "500ms",
    "index.search.slowlog.threshold.fetch.warn": "1s",
    "index.search.slowlog.threshold.fetch.info": "800ms",
    "index.search.slowlog.threshold.fetch.debug": "500ms",
    "index.search.slowlog.threshold.fetch.trace": "200ms"
  },
  "version"  : 1
}
 
PUT {INDEX_PAATERN}/_settings
{
    "index.indexing.slowlog.level": "INFO",
    "index.indexing.slowlog.threshold.index.warn": "10s",
    "index.indexing.slowlog.threshold.index.info": "5s",
    "index.indexing.slowlog.threshold.index.debug": "2s",
    "index.indexing.slowlog.threshold.index.trace": "500ms",
    "index.indexing.slowlog.source": "1000",
    "index.search.slowlog.level": "INFO",
    "index.search.slowlog.threshold.query.warn": "10s",
    "index.search.slowlog.threshold.query.info": "5s",
    "index.search.slowlog.threshold.query.debug": "2s",
    "index.search.slowlog.threshold.query.trace": "500ms",
    "index.search.slowlog.threshold.fetch.warn": "1s",
    "index.search.slowlog.threshold.fetch.info": "800ms",
    "index.search.slowlog.threshold.fetch.debug": "500ms",
    "index.search.slowlog.threshold.fetch.trace": "200ms"
}

這樣,在日志目錄下的慢查詢(xún)?nèi)罩揪蜁?huì)有輸出記錄必要的信息了。

{CLUSTER_NAME}_index_indexing_slowlog.log
{CLUSTER_NAME}_index_search_slowlog.log

數(shù)據(jù)結(jié)構(gòu)優(yōu)化

基于 Elasticsearch 的使用場(chǎng)景,文檔數(shù)據(jù)結(jié)構(gòu)盡量和使用場(chǎng)景進(jìn)行結(jié)合,去掉沒(méi)用及不合理的數(shù)據(jù)。

盡量減少不需要的字段

如果 Elasticsearch 用于業(yè)務(wù)搜索服務(wù),一些不需要用于搜索的字段最好不存到 ES 中,這樣即節(jié)省空間,同時(shí)在相同的數(shù)據(jù)量下,也能提高搜索性能。

避免使用動(dòng)態(tài)值作字段,動(dòng)態(tài)遞增的 mapping,會(huì)導(dǎo)致集群崩潰;同樣,也需要控制字段的數(shù)量,業(yè)務(wù)中不使用的字段,就不要索引。控制索引的字段數(shù)量、mapping 深度、索引字段的類(lèi)型,對(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

Nested Object vs Parent/Child

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

如果一定要使用 nested fields,保證 nested fields 字段不能過(guò)多,目前 ES 默認(rèn)限制是 50。因?yàn)獒槍?duì) 1 個(gè) document,每一個(gè) nested field,都會(huì)生成一個(gè)獨(dú)立的 document,這將使 doc 數(shù)量劇增,影響查詢(xún)效率,尤其是 JOIN 的效率。

index.mapping.nested_fields.limit: 50

對(duì)比

Nested Object

Parent/Child

優(yōu)點(diǎn)

文檔存儲(chǔ)在一起,因此讀取性高

父子文檔可以獨(dú)立更新,互不影響

缺點(diǎn)

更新父文檔或子文檔時(shí)需要更新整個(gè)文檔

為了維護(hù) join 關(guān)系,需要占用部分內(nèi)存,讀取性能較差

場(chǎng)景

子文檔偶爾更新,查詢(xún)頻繁

子文檔更新頻繁

選擇靜態(tài)映射,非必需時(shí),禁止動(dòng)態(tài)映射

盡量避免使用動(dòng)態(tài)映射,這樣有可能會(huì)導(dǎo)致集群崩潰,此外,動(dòng)態(tài)映射有可能會(huì)帶來(lái)不可控制的數(shù)據(jù)類(lèi)型,進(jìn)而有可能導(dǎo)致在查詢(xún)端出現(xiàn)相關(guān)異常,影響業(yè)務(wù)。

此外,Elasticsearch 作為搜索引擎時(shí),主要承載 query 的匹配和排序的功能,那數(shù)據(jù)的存儲(chǔ)類(lèi)型基于這兩種功能的用途分為兩類(lèi),一是需要匹配的字段,用來(lái)建立倒排索引對(duì) query 匹配用,另一類(lèi)字段是用做粗排用到的特征字段,如 ctr、點(diǎn)擊數(shù)、評(píng)論數(shù)等等。

document 模型設(shè)計(jì)

對(duì)于 MySQL,我們經(jīng)常有一些復(fù)雜的關(guān)聯(lián)查詢(xún)。在 es 里該怎么玩兒,es 里面的復(fù)雜的關(guān)聯(lián)查詢(xún)盡量別用,一旦用了性能一般都不太好。

最好是先在 Java 系統(tǒng)里就完成關(guān)聯(lián),將關(guān)聯(lián)好的數(shù)據(jù)直接寫(xiě)入 es 中。搜索的時(shí)候,就不需要利用 es 的搜索語(yǔ)法來(lái)完成 join 之類(lèi)的關(guān)聯(lián)搜索了。

document 模型設(shè)計(jì)是非常重要的,很多操作,不要在搜索的時(shí)候才想去執(zhí)行各種復(fù)雜的亂七八糟的操作。es 能支持的操作就那么多,不要考慮用 es 做一些它不好操作的事情。如果真的有那種操作,盡量在 document 模型設(shè)計(jì)的時(shí)候,寫(xiě)入的時(shí)候就完成。另外對(duì)于一些太復(fù)雜的操作,比如 join/nested/parent-child 搜索都要盡量避免,性能都很差的。

集群架構(gòu)設(shè)計(jì)

合理的部署 Elasticsearch 有助于提高服務(wù)的整體可用性。

主節(jié)點(diǎn)、數(shù)據(jù)節(jié)點(diǎn)和協(xié)調(diào)節(jié)點(diǎn)分離

Elasticsearch 集群在架構(gòu)拓樸時(shí),采用主節(jié)點(diǎn)、數(shù)據(jù)節(jié)點(diǎn)和負(fù)載均衡節(jié)點(diǎn)分離的架構(gòu),在 5.x 版本以后,又可將數(shù)據(jù)節(jié)點(diǎn)再細(xì)分為“Hot-Warm”的架構(gòu)模式。

Elasticsearch 的配置文件中有 2 個(gè)參數(shù),node.master 和 node.data。這兩個(gè)參數(shù)搭配使用時(shí),能夠幫助提供服務(wù)器性能。

主(master)節(jié)點(diǎn)

配置 node.master:true 和 node.data:false,該 node 服務(wù)器只作為一個(gè)主節(jié)點(diǎn),但不存儲(chǔ)任何索引數(shù)據(jù)。我們推薦每個(gè)集群運(yùn)行3 個(gè)專(zhuān)用的 master 節(jié)點(diǎn)來(lái)提供最好的彈性。使用時(shí),你還需要將 discovery.zen.minimum_master_nodes setting 參數(shù)設(shè)置為 2,以免出現(xiàn)腦裂(split-brain)的情況。用 3 個(gè)專(zhuān)用的 master 節(jié)點(diǎn),專(zhuān)門(mén)負(fù)責(zé)處理集群的管理以及加強(qiáng)狀態(tài)的整體穩(wěn)定性。因?yàn)檫@ 3 個(gè) master 節(jié)點(diǎn)不包含數(shù)據(jù)也不會(huì)實(shí)際參與搜索以及索引操作,在 JVM 上它們不用做相同的事,例如繁重的索引或者耗時(shí),資源耗費(fèi)很大的搜索。因此不太可能會(huì)因?yàn)槔厥斩鴮?dǎo)致停頓。因此,master 節(jié)點(diǎn)的 CPU,內(nèi)存以及磁盤(pán)配置可以比 data 節(jié)點(diǎn)少很多的。

數(shù)據(jù)(data)節(jié)點(diǎn)

配置 node.master:false 和 node.data:true,該 node 服務(wù)器只作為一個(gè)數(shù)據(jù)節(jié)點(diǎn),只用于存儲(chǔ)索引數(shù)據(jù),使該 node 服務(wù)器功能單一,只用于數(shù)據(jù)存儲(chǔ)和數(shù)據(jù)查詢(xún),降低其資源消耗率。

在 Elasticsearch 5.x 版本之后,data 節(jié)點(diǎn)又可再細(xì)分為“Hot-Warm”架構(gòu),即分為熱節(jié)點(diǎn)(hot node)和暖節(jié)點(diǎn)(warm node)。

hot 節(jié)點(diǎn):

hot 節(jié)點(diǎn)主要是索引節(jié)點(diǎn)(寫(xiě)節(jié)點(diǎn)),同時(shí)會(huì)保存近期的一些頻繁被查詢(xún)的索引。由于進(jìn)行索引非常耗費(fèi) CPU 和 IO,即屬于 IO 和 CPU 密集型操作,建議使用 SSD 的磁盤(pán)類(lèi)型,保持良好的寫(xiě)性能;我們推薦部署最小化的 3 個(gè) hot 節(jié)點(diǎn)來(lái)保證高可用性。根據(jù)近期需要收集以及查詢(xún)的數(shù)據(jù)量,可以增加服務(wù)器數(shù)量來(lái)獲得想要的性能。

將節(jié)點(diǎn)設(shè)置為 hot 類(lèi)型需要 elasticsearch.yml 如下配置:

node.attr.box_type: hot

如果是針對(duì)指定的 index 操作,可以通過(guò) settings 設(shè)置 index.routing.allocation.require.box_type: hot 將索引寫(xiě)入 hot 節(jié)點(diǎn)。

warm 節(jié)點(diǎn):

這種類(lèi)型的節(jié)點(diǎn)是為了處理大量的,而且不經(jīng)常訪(fǎng)問(wèn)的只讀索引而設(shè)計(jì)的。由于這些索引是只讀的,warm 節(jié)點(diǎn)傾向于掛載大量磁盤(pán)(普通磁盤(pán))來(lái)替代 SSD。內(nèi)存、CPU 的配置跟 hot 節(jié)點(diǎn)保持一致即可;節(jié)點(diǎn)數(shù)量一般也是大于等于 3 個(gè)。

將節(jié)點(diǎn)設(shè)置為 warm 類(lèi)型需要 elasticsearch.yml 如下配置:

node.attr.box_type: warm

同時(shí),也可以在 elasticsearch.yml 中設(shè)置 index.codec:best_compression 保證 warm 節(jié)點(diǎn)的壓縮配置。

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

協(xié)調(diào)(coordinating)節(jié)點(diǎn)

協(xié)調(diào)節(jié)點(diǎn)用于做分布式里的協(xié)調(diào),將各分片或節(jié)點(diǎn)返回的數(shù)據(jù)整合后返回。該節(jié)點(diǎn)不會(huì)被選作主節(jié)點(diǎn),也不會(huì)存儲(chǔ)任何索引數(shù)據(jù)。該服務(wù)器主要用于查詢(xún)負(fù)載均衡。在查詢(xún)的時(shí)候,通常會(huì)涉及到從多個(gè) node 服務(wù)器上查詢(xún)數(shù)據(jù),并將請(qǐng)求分發(fā)到多個(gè)指定的 node 服務(wù)器,并對(duì)各個(gè) node 服務(wù)器返回的結(jié)果進(jìn)行一個(gè)匯總處理,最終返回給客戶(hù)端。在 ES 集群中,所有的節(jié)點(diǎn)都有可能是協(xié)調(diào)節(jié)點(diǎn),但是,可以通過(guò)設(shè)置 node.master、node.data、node.ingest 都為 false 來(lái)設(shè)置專(zhuān)門(mén)的協(xié)調(diào)節(jié)點(diǎn)。需要較好的 CPU 和較高的內(nèi)存。

  • node.master:false和node.data:true,該node服務(wù)器只作為一個(gè)數(shù)據(jù)節(jié)點(diǎn),只用于存儲(chǔ)索引數(shù)據(jù),使該node服務(wù)器功能單一,只用于數(shù)據(jù)存儲(chǔ)和數(shù)據(jù)查詢(xún),降低其資源消耗率。
  • node.master:true和node.data:false,該node服務(wù)器只作為一個(gè)主節(jié)點(diǎn),但不存儲(chǔ)任何索引數(shù)據(jù),該node服務(wù)器將使用自身空閑的資源,來(lái)協(xié)調(diào)各種創(chuàng)建索引請(qǐng)求或者查詢(xún)請(qǐng)求,并將這些請(qǐng)求合理分發(fā)到相關(guān)的node服務(wù)器上。
  • node.master:false和node.data:false,該node服務(wù)器即不會(huì)被選作主節(jié)點(diǎn),也不會(huì)存儲(chǔ)任何索引數(shù)據(jù)。該服務(wù)器主要用于查詢(xún)負(fù)載均衡。在查詢(xún)的時(shí)候,通常會(huì)涉及到從多個(gè)node服務(wù)器上查詢(xún)數(shù)據(jù),并將請(qǐng)求分發(fā)到多個(gè)指定的node服務(wù)器,并對(duì)各個(gè)node服務(wù)器返回的結(jié)果進(jìn)行一個(gè)匯總處理,最終返回給客戶(hù)端。

關(guān)閉 data 節(jié)點(diǎn)服務(wù)器中的 http 功能

針對(duì) Elasticsearch 集群中的所有數(shù)據(jù)節(jié)點(diǎn),不用開(kāi)啟 http 服務(wù)。將其中的配置參數(shù)這樣設(shè)置,http.enabled:false,同時(shí)也不要安裝 head, bigdesk, marvel 等監(jiān)控插件,這樣保證 data 節(jié)點(diǎn)服務(wù)器只需處理創(chuàng)建/更新/刪除/查詢(xún)索引數(shù)據(jù)等操作。

http 功能可以在非數(shù)據(jù)節(jié)點(diǎn)服務(wù)器上開(kāi)啟,上述相關(guān)的監(jiān)控插件也安裝到這些服務(wù)器上,用于監(jiān)控 Elasticsearch 集群狀態(tài)等數(shù)據(jù)信息。這樣做一來(lái)出于數(shù)據(jù)安全考慮,二來(lái)出于服務(wù)性能考慮。

一臺(tái)服務(wù)器上最好只部署一個(gè) node

一臺(tái)物理服務(wù)器上可以啟動(dòng)多個(gè) node 服務(wù)器節(jié)點(diǎn)(通過(guò)設(shè)置不同的啟動(dòng) port),但一臺(tái)服務(wù)器上的 CPU、內(nèi)存、硬盤(pán)等資源畢竟有限,從服務(wù)器性能考慮,不建議一臺(tái)服務(wù)器上啟動(dòng)多個(gè) node 節(jié)點(diǎn)。

集群分片設(shè)置

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

控制每個(gè)分片占用的硬盤(pán)容量不超過(guò) ES 的最大 JVM 的堆空間設(shè)置(一般設(shè)置不超過(guò) 32 G,參考上面的 JVM 內(nèi)存設(shè)置原則),因此,如果索引的總?cè)萘吭?500 G 左右,那分片大小在 16 個(gè)左右即可;當(dāng)然,最好同時(shí)考慮原則 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 倍。

責(zé)任編輯:武曉燕 來(lái)源: 程序員wayn
相關(guān)推薦

2010-03-02 09:53:14

MySQL性能優(yōu)化

2009-09-22 17:25:41

優(yōu)化Hibernate

2011-06-20 14:27:57

Qt Embedded

2019-05-21 09:40:47

Elasticsear高性能 API

2024-11-21 08:00:00

向量搜索人工智能

2023-07-10 16:18:18

性能優(yōu)化開(kāi)發(fā)

2010-06-04 11:00:27

hadoop性能優(yōu)化

2023-11-15 16:35:31

SQL數(shù)據(jù)庫(kù)

2023-10-11 08:36:42

復(fù)合查詢(xún)腳本查詢(xún)

2020-06-04 16:57:07

移動(dòng)開(kāi)發(fā)互聯(lián)網(wǎng)實(shí)踐

2010-04-22 17:27:22

Oracle性能

2021-07-27 20:51:02

AndroidDNS網(wǎng)絡(luò)

2017-05-04 10:33:25

Elasticsearelasticsear安裝

2009-04-08 10:51:59

SQL優(yōu)化經(jīng)驗(yàn)

2025-06-03 00:00:06

性能優(yōu)化性能指標(biāo)響應(yīng)時(shí)間

2009-02-26 09:34:16

性能優(yōu)化DB2數(shù)據(jù)庫(kù)

2023-08-31 08:36:52

.NET性能測(cè)試開(kāi)源

2014-12-10 10:12:02

Web

2022-06-08 10:01:23

性能優(yōu)化慢查詢(xún)

2009-09-08 09:45:23

App Engine性
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩www| 欧美一级二级三级视频 | 久久亚洲国产精品日日av夜夜 | 欧美日韩国产精品一区二区 | 一本岛道一二三不卡区 | 午夜码电影 | 亚洲黄色一级毛片 | 精品亚洲一区二区三区 | 久久伊人操 | 欧美激情综合 | 国产成人精品a视频一区www | 免费的av | 99色在线| 亚洲一区国产 | 亚洲v日韩v综合v精品v | 91aiai| 国产成人精品久久二区二区91 | 日日天天 | 国产精品美女久久久av超清 | 亚洲精品久久久久久久久久久久久 | 久久久久国产精品一区二区 | 亚洲国产成人av好男人在线观看 | 日本黄色免费片 | 网站国产| 中文字幕在线观看一区二区 | 成人在线视频免费看 | 美女久久| 国产精品中文 | 九九久久久 | 欧美午夜一区二区三区免费大片 | 91精品国产91久久综合桃花 | 秋霞电影一区二区三区 | 成人国产精品久久久 | 国产精品地址 | 久久久久久久久久爱 | 在线观看中文字幕 | 伊人热久久 | 精品欧美激情在线观看 | 日韩av成人在线观看 | 日韩国产高清在线观看 | 久久亚洲视频网 |