如何監(jiān)控Elasticsearch

什么是Elasticsearch

Elasticsearch是一個(gè)開源的分布式文檔存儲(chǔ)和搜索引擎,可以近乎實(shí)時(shí)地存儲(chǔ)和檢索數(shù)據(jù)結(jié)構(gòu),它很大程度上依賴于Apache Lucence--一個(gè)用Java編寫的全文搜索引擎。

Elasticsearch以結(jié)構(gòu)化JSON文檔的形式呈現(xiàn)數(shù)據(jù),并通過RESTful API和web客戶端為PHP,Python和Ruby等語言提供全文搜索。Elasticsearch服務(wù)是具有彈性的,因?yàn)樗子谒綌U(kuò)展--只需添加更多節(jié)點(diǎn)即可分配負(fù)載?,F(xiàn)在有很多企業(yè)動(dòng)用它來動(dòng)態(tài)存儲(chǔ),搜索和分析大量數(shù)據(jù),包括維基百科,eBay,Github和Datadog。

工作方式

在探討性能指標(biāo)之前,先來看看Elasticsearch的工作方式。在Elasticsearch中,集群由一個(gè)或多個(gè)節(jié)點(diǎn)組成,如下


每個(gè)節(jié)點(diǎn)都是單個(gè)Elasticsearch實(shí)例,其elasticsearch.yml配置文件制定它屬于哪個(gè)集群(cluster.name)以及它是哪種類型的節(jié)點(diǎn)。配置文件中設(shè)置的任何屬性(包括集群名稱)也可以通過命令行參數(shù)指定。上圖中的集群由一個(gè)專用主節(jié)點(diǎn)和五個(gè)數(shù)據(jù)節(jié)點(diǎn)組成。

Elasticsearch中最常見的三種類型的節(jié)點(diǎn)是:

  • 符合條件的主節(jié)點(diǎn):默認(rèn)情況下,每個(gè)節(jié)點(diǎn)均可作為主節(jié)點(diǎn)。每個(gè)集群都會(huì)自動(dòng)從所有主節(jié)點(diǎn)中選擇一個(gè)主節(jié)點(diǎn)。如果當(dāng)前主節(jié)點(diǎn)發(fā)生故障(例如停電,硬件故障或者內(nèi)存不足),會(huì)從符合條件的節(jié)點(diǎn)中選出一個(gè)主節(jié)點(diǎn)。主節(jié)點(diǎn)負(fù)責(zé)協(xié)調(diào)集群任務(wù),例如跨節(jié)點(diǎn)分發(fā)分片,創(chuàng)建以及刪除索引。符合條件的主節(jié)點(diǎn)也可以充當(dāng)數(shù)據(jù)節(jié)點(diǎn)。不過在較大的集群中,通常啟動(dòng)不存儲(chǔ)任何數(shù)據(jù)的專用主節(jié)點(diǎn)(配置文件中設(shè)置node.datafalse),來提高可靠性。在高使用率的環(huán)境中,將主節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)分開有助于確保總是有足夠的資源分配給只有主節(jié)點(diǎn)可以處理的任務(wù)。
  • 數(shù)據(jù)節(jié)點(diǎn):默認(rèn)情況下,每個(gè)節(jié)點(diǎn)都是以分片形式存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)節(jié)點(diǎn),這些節(jié)點(diǎn)執(zhí)行索引,搜索以及聚合數(shù)據(jù)相關(guān)的操作。在較大的集群中,可通過在配置文件中設(shè)置node.master: false來創(chuàng)建專用數(shù)據(jù)節(jié)點(diǎn),來確保這些節(jié)點(diǎn)有足夠的資源來處理與數(shù)據(jù)相關(guān)的請(qǐng)求,而無需處理集群相關(guān)管理任務(wù)的額外工作量。
  • 客戶節(jié)點(diǎn):如果將node.masternode.data設(shè)置為false,那么該節(jié)點(diǎn)會(huì)成為一個(gè)客戶節(jié)點(diǎn),用作一個(gè)負(fù)載均衡器,以幫助路有索引和搜索請(qǐng)求。客戶端節(jié)點(diǎn)可以承擔(dān)一部分的搜索工作量,以便讓數(shù)據(jù)節(jié)點(diǎn)和主節(jié)點(diǎn)可以專注于核心任務(wù)。根據(jù)使用情況,客戶節(jié)點(diǎn)可能不是必須的,因?yàn)閿?shù)據(jù)節(jié)點(diǎn)能夠自行處理請(qǐng)求路由。但是,如果搜索|索引的工作負(fù)載足夠大,可以利用客戶節(jié)點(diǎn)來幫助路有請(qǐng)求。

數(shù)據(jù)的存儲(chǔ)

在Elasticsearch中,相關(guān)數(shù)據(jù)通常存儲(chǔ)在同一個(gè)索引中,可以將其視為配置邏輯包裝的等價(jià)物。每個(gè)索引都包含一組JSON格式的相關(guān)文檔。Elasticsearch的全文索引使用的是Lucence的倒排索引。為文檔創(chuàng)建索引時(shí),Elasticsearch會(huì)自動(dòng)為每個(gè)字段創(chuàng)建倒排索引;倒排索引將字段映射到包含這些字段的文檔。

索引存儲(chǔ)在在主分片(一個(gè)或多個(gè))和副本分片(零個(gè)或多個(gè))中,每個(gè)分片都是一個(gè)Lucence的完整實(shí)例,可以當(dāng)成一個(gè)迷你搜索引擎。

當(dāng)創(chuàng)建索引時(shí),可以制定主分片的數(shù)量以及每個(gè)主分片的副本數(shù)量。默認(rèn)值為每個(gè)索引五個(gè)主分片,每個(gè)主分片一個(gè)副本。在索引被創(chuàng)建后,主分片的數(shù)量無法更改,因此在選擇數(shù)量時(shí)要謹(jǐn)慎,否則后面可能需要重新建立索引。副本的數(shù)量可以在后面根據(jù)需求更新。為了防止數(shù)據(jù)丟失,主節(jié)點(diǎn)確保每個(gè)副本分片不會(huì)和主分片分配到同個(gè)節(jié)點(diǎn)上。

關(guān)鍵指標(biāo)

Elasticsearch提供了大量指標(biāo),可以幫助用戶檢測(cè)出故障跡象,并在遇到諸如不可靠節(jié)點(diǎn),內(nèi)存不足和GC時(shí)間過長等問題時(shí)采取措施。一些需要監(jiān)控的關(guān)鍵指標(biāo)是:

  • 搜索和索引的性能
  • 內(nèi)存和垃圾回收
  • 主機(jī)和網(wǎng)絡(luò)
  • 集群健康度和節(jié)點(diǎn)可用性
  • 資源飽和和錯(cuò)誤

上面列出的指標(biāo)都可以通過Elasticsearch的API以及像Elastic的Marvel這樣的工具收集到。

搜索性能指標(biāo)

搜索請(qǐng)求和索引請(qǐng)求是Elasticsearch中的兩個(gè)主要請(qǐng)求類型。在某種程度上,這些請(qǐng)求和傳統(tǒng)數(shù)據(jù)庫系統(tǒng)中的讀取和寫入請(qǐng)求很類似。Elasticsearch提供了與搜索過程的兩個(gè)主要階段(查詢和提取)相對(duì)應(yīng)的指標(biāo)。一次搜索請(qǐng)求從開始到結(jié)束的路徑如下

  1. 客戶端向節(jié)點(diǎn)2發(fā)送請(qǐng)求
  2. 節(jié)點(diǎn)2(協(xié)調(diào)節(jié)點(diǎn))將查詢發(fā)送到索引中每個(gè)分片的副本(主副本或分片副本)
  3. 每個(gè)分片在本地執(zhí)行查詢并將結(jié)果傳給節(jié)點(diǎn)2。節(jié)點(diǎn)2將這些結(jié)果排序并編譯為全局優(yōu)先級(jí)隊(duì)列。
  4. 節(jié)點(diǎn)2找出需要提取的文檔,并向相關(guān)分片發(fā)出多個(gè)GET請(qǐng)求
  5. 每個(gè)分片加載文檔,并返回給節(jié)點(diǎn)2
  6. 節(jié)點(diǎn)2將結(jié)果返回給客戶端

當(dāng)Elasticsearch主要用于搜索時(shí),有必要監(jiān)控查詢延遲并在超過闕值時(shí)采取措施。監(jiān)控有關(guān)查詢和提取的相關(guān)指標(biāo)非常重要,這些指標(biāo)可以幫助確定在一段時(shí)間內(nèi)的搜索性能。比如,可以跟蹤查詢請(qǐng)求中的峰值和長期的的增長趨勢(shì),以準(zhǔn)備優(yōu)化配置來獲得更好的性能和可靠性。

指標(biāo)描述 指標(biāo)名 指標(biāo)類型
query總數(shù) indices.search.query_total 吞吐量
query總耗時(shí) indices.search.query_time_in_millis 性能
當(dāng)前在處理的query數(shù)量 indices.search.query_current 吞吐量
fetch總數(shù) indices.search.fetch_total 吞吐量
fetch總耗時(shí) indices.search.fetch_time_in_millis 性能
當(dāng)前在處理的fetch數(shù)量 indices.search_fetch_current 吞吐量

重點(diǎn)指標(biāo)

Query 負(fù)載:監(jiān)控當(dāng)前正在進(jìn)行的query數(shù)量可以大致了解集群在任何特定時(shí)刻處理的請(qǐng)求數(shù)量。可以考慮在出現(xiàn)異常尖峰和驟降時(shí)發(fā)出警告。

Query延遲:盡管Elastisearch沒有明確提供這個(gè)指標(biāo),但是可以用現(xiàn)有指標(biāo)來推算這個(gè)值,算法是定期用查詢總數(shù)除以總耗時(shí)。

Fetch延遲:搜索的第二階段(fetch階段)通常比query階段耗時(shí)要少。如果這個(gè)值持續(xù)增加,可能意味著磁盤速度慢,或者請(qǐng)求的結(jié)果數(shù)量過多。

索引性能指標(biāo)

索引請(qǐng)求類似于傳統(tǒng)數(shù)據(jù)庫系統(tǒng)中的寫請(qǐng)求。如果Elasticsearch集群主要用于索引,那么對(duì)索引性能的監(jiān)控是非常有必要的。在討論監(jiān)控指標(biāo)前,我們先看看Elasticsearch處理索引的方式。當(dāng)在索引中添加新信息或者刪除現(xiàn)有信息時(shí),索引中的每個(gè)分片都會(huì)通過兩個(gè)步驟更新:refresh和flush。

refresh

新加入到索引的文檔不能立即用于搜索,這些文檔會(huì)先被寫入內(nèi)存緩沖區(qū),等待下一次索引刷新,默認(rèn)情況下每秒刷新一次。refresh先從之前內(nèi)存緩沖區(qū)中創(chuàng)建新的內(nèi)存段,讓這些內(nèi)容能夠被搜索到,然后清空緩存區(qū),過程如下

索引的分片由多個(gè)段組成。這個(gè)Lucene的核心數(shù)據(jù)結(jié)構(gòu),一個(gè)段實(shí)際上索引的變更集。每個(gè)段使用文件,內(nèi)存和CPU,為了有效利用這些資源,這些段在每次刷新時(shí)創(chuàng)建,隨后合并。

段是微型的倒排索引,可以將詞映射到包含這些詞的文檔。每次搜索索引時(shí),依次搜索主分片或者副本分片,在分片中搜索每個(gè)分段。

段是不可變的,所以更新文檔會(huì):

  • 在refresh過程中將信息寫入新段
  • 將舊信息標(biāo)記為刪除

當(dāng)過期段與另一個(gè)段合并時(shí),最終會(huì)刪除舊信息。

flush

在將新索引文檔添加到內(nèi)存緩沖區(qū)的同時(shí),這些內(nèi)容也會(huì)添加到分片的translog,translog用于持久記錄操作的日志。每隔30分鐘,或者當(dāng)translog大小到達(dá)最大時(shí)(默認(rèn)是512MB),會(huì)觸發(fā)一次flush操作。在flush期間,內(nèi)存緩沖區(qū)的任何文檔都會(huì)刷新(存儲(chǔ)在新段中),所有內(nèi)存中的段都會(huì)提交到磁盤,同時(shí)translog被清空。

translog有助于防止節(jié)點(diǎn)故障時(shí)丟失數(shù)據(jù)??梢杂胻ranslog幫助恢復(fù)可能在刷新之間丟失的操作。日志每5秒提交到磁盤;或在索引,刪除,更新或批量請(qǐng)求成功后,日志提交到磁盤。流程如下

Elasticsearch提供了很多有關(guān)索引的指標(biāo)

指標(biāo)描述 指標(biāo)名 指標(biāo)類型
索引的文檔總數(shù) indices.indexing.index_total 吞吐量
索引文檔總耗時(shí) indices.indexing.index_time_in_millis 性能
當(dāng)前索引的文檔數(shù) indices.indexing.index_current 吞吐量
索引refresh總數(shù) indices.refresh.total 吞吐量
refresh總耗時(shí) indices.refresh.total_time_in_millis 吞吐量
索引flush到磁盤總數(shù) indices.flush.total 吞吐量
flush總耗時(shí) indices.flush.total_time_in_millis 吞吐量

重點(diǎn)指標(biāo)

索引延遲:Elasticsearch并不直接提供這個(gè)指標(biāo),不過可以根據(jù)index_totalindex_time_in_millis算出來。如果注延遲增加,可能是因?yàn)橐淮嗡饕奶辔臋n(Elastisearch建議批量索引大小為5MB-15MB)。

如果計(jì)劃索引大量文檔,并且不需要新的信息可立即用于搜索,可以通過降低刷新頻率來優(yōu)化索引性能而不是搜索性能,直到完成索引。

Flush延遲:由于數(shù)據(jù)在成功完成刷新之前不會(huì)持久保存到磁盤,因此跟蹤刷新延遲并在性能開始下潛時(shí)采取措施會(huì)很有用。如果看到此指標(biāo)穩(wěn)步增加,則可能表示磁盤速度較慢;此問題可能會(huì)升級(jí)并最終阻止向索引添加新文檔。在這種情況下,可以嘗試降低index.translog.flush_threshold_size,此設(shè)置確定在觸發(fā)刷新之前translog大小可以達(dá)到的大小。如果Elasticsearch寫比較重,可以考慮使用iostat關(guān)注磁盤I/O。

內(nèi)存和垃圾回收

內(nèi)存是需要監(jiān)控的關(guān)鍵指標(biāo)之一。Elasticsearch和Lucene以兩種方式利用節(jié)點(diǎn)上的所有可用內(nèi)存:JVM堆和文件系統(tǒng)緩存。Elasticsearch在Java虛擬機(jī)(JVM)中運(yùn)行,這意味著JVM垃圾收集的持續(xù)時(shí)間和頻率也是需要監(jiān)控起來的。

JVM堆

使用Elasticsearch需要設(shè)置適當(dāng)?shù)腏VM堆大小。一般來說,Elasticsearch的經(jīng)驗(yàn)法則是將不到50%的可用RAM分配給JVM堆,永遠(yuǎn)不會(huì)高于32GB。分配給Elasticsearch的堆內(nèi)存越小,Lucene可用的內(nèi)存就越多,而Lucene很大程度上依賴于文件系統(tǒng)緩存來快速響應(yīng)請(qǐng)求;但是也不能設(shè)置的太小,因?yàn)榭赡軙?huì)遇到內(nèi)存不足,或者因?yàn)轭l繁GC導(dǎo)致吞吐量降低。這篇博客有詳細(xì)描述。

Elasticsearch默認(rèn)設(shè)置JVM堆大小為1G,在大多數(shù)場景下這個(gè)都太小,可以所需要的堆大小導(dǎo)出為環(huán)境變量,然后重新啟動(dòng)Elasticsearch。

export ES_HEAP_SIZE=10g

垃圾回收

Elasticsearch依賴于垃圾收集(GC)進(jìn)程來釋放堆內(nèi)存。需要留意GC的頻率和持續(xù)時(shí)間。將堆設(shè)置得太大會(huì)導(dǎo)致垃圾收集時(shí)間過長;這些過度暫停是危險(xiǎn)的,會(huì)導(dǎo)致集群中其他節(jié)點(diǎn)認(rèn)為該節(jié)點(diǎn)失去響應(yīng)。

指標(biāo)描述 指標(biāo)名 指標(biāo)類型
年輕代垃圾回收總數(shù) jvm.gc.collectors.young.collection_count
年輕代垃圾回收耗時(shí) jvm.gc.collectors.young.collection_time_in_millis
年老代垃圾回收總數(shù) jvm.gc.collectors.old.collection_count
年老代垃圾回收耗時(shí) jvm.gc.collectors.old.collection_time_in_millis
當(dāng)前JVM堆占比 jvm.mem.heap_used_percent
已提交的JVM堆量 jvm.mem.heap_committed_in_bytes

重點(diǎn)指標(biāo)

在使用的JVM堆: Elasticsearch設(shè)置為在JVM堆使用率達(dá)到75%時(shí)啟動(dòng)垃圾回收。監(jiān)視哪些節(jié)點(diǎn)表現(xiàn)出高堆使用率并設(shè)置警報(bào)以查明是否有任何節(jié)點(diǎn)始終使用超過85%的堆內(nèi)存可能很有用:這表明垃圾收集的速度跟不上垃圾創(chuàng)建的速度。要解決這個(gè)問題,可以增加堆大小,或者通過添加更多節(jié)點(diǎn)來擴(kuò)展群集。

已使用的堆和已提交的堆:使用的堆內(nèi)存量通常采用鋸齒模式,當(dāng)垃圾堆積時(shí)會(huì)上升,當(dāng)收集垃圾時(shí)會(huì)下降。已使用堆和已提交堆比例增加時(shí),意味著垃圾收集的速率跟不上對(duì)象創(chuàng)建的速度,這可能導(dǎo)致垃圾收集時(shí)間變慢,并最終導(dǎo)致OutOfMemoryErrors。

GC持續(xù)時(shí)間和頻率:回收年輕代和年老代垃圾回收都會(huì)經(jīng)歷“世界停止”階段,因?yàn)镴VM停止執(zhí)行程序來進(jìn)行回收。在這段時(shí)間內(nèi),節(jié)點(diǎn)無法完成任何任務(wù)。主節(jié)點(diǎn)會(huì)每隔30秒檢查其他節(jié)點(diǎn)狀體啊,如何任何節(jié)點(diǎn)的垃圾回收時(shí)間超過30秒,主節(jié)點(diǎn)將認(rèn)為這個(gè)節(jié)點(diǎn)已經(jīng)掛掉。

內(nèi)存使用率:如上所述,Elasticsearch充分利用了尚未分配給JVM堆的任何RAM,其依靠操作系統(tǒng)的文件系統(tǒng)緩存來快速可靠地處理請(qǐng)求。有許多變量決定Elasticsearch是否成功從文件系統(tǒng)緩存中讀取。如果段文件最近由Elasticsearch寫入磁盤,則它已在緩存中;但是,如果節(jié)點(diǎn)已關(guān)閉并重新啟動(dòng),則第一次查詢段時(shí),很可能必須從磁盤讀取信息。這是需要為什么確保集群保持穩(wěn)定并且節(jié)點(diǎn)不會(huì)崩潰的重要原因之一。

主機(jī)指標(biāo)

I/O:在創(chuàng)建,查詢和合并段時(shí),Elasticsearch會(huì)對(duì)磁盤進(jìn)行大量寫入和讀取操作。對(duì)于具有持續(xù)經(jīng)歷大量I / O活動(dòng)的節(jié)點(diǎn)的大量集群,Elasticsearch建議使用SSD來提高性能。

CPU使用率:可視化CPU使用率會(huì)很有用。CPU使用率增加通常是由大量搜索和索引請(qǐng)求導(dǎo)致。

網(wǎng)絡(luò)流出/流入字節(jié)數(shù):節(jié)點(diǎn)之間的通信是平衡群集的關(guān)鍵。除了Elasticsearch提供有關(guān)群集通信的傳輸指標(biāo),還可以查看網(wǎng)卡發(fā)送和接收的字節(jié)速率。

打開文件數(shù):文件描述符用于節(jié)點(diǎn)到節(jié)點(diǎn)通信,客戶端連接和文件操作。如果此數(shù)字達(dá)到系統(tǒng)的最大容量,則在舊的連接關(guān)閉之前,將無法進(jìn)行新的連接和文件操作。

集群狀態(tài)和節(jié)點(diǎn)可用性

指標(biāo)描述 指標(biāo)名 指標(biāo)類型
集群狀態(tài) cluster.health.status
節(jié)點(diǎn)數(shù)量 cluster.health.number_of_nodes 可用性
初始化中的分片數(shù) cluster.health.initializing_shards 可用性
未分配分片數(shù) cluster.health.unassigned_shards 可用性

集群狀態(tài):如果群集狀態(tài)為黃色,則至少有一個(gè)副本分片未分配或丟失。搜索結(jié)果仍然完整,但如果更多分片消失,可能會(huì)丟失數(shù)據(jù)。

紅色群集狀態(tài)表示至少缺少一個(gè)主分片,并且數(shù)據(jù)正在丟失,這意味著搜索將返回部分結(jié)果。

初始化中和未分配的分片:首次創(chuàng)建索引或重新啟動(dòng)節(jié)點(diǎn)時(shí),其主機(jī)節(jié)點(diǎn)嘗試將分片分配給節(jié)點(diǎn)時(shí),其分片將在轉(zhuǎn)換為“已啟動(dòng)”或“未分配”狀態(tài)之前暫時(shí)處于“初始化”狀態(tài)。如果發(fā)現(xiàn)分片在初始化或未分配狀態(tài)下保留的時(shí)間過長,則可能表示集群不穩(wěn)定。

結(jié)語

在這篇文章中,我們介紹了Elasticsearch的一些最重要的領(lǐng)域,以便在擴(kuò)展和擴(kuò)展集群時(shí)對(duì)其進(jìn)行監(jiān)控。

在監(jiān)視Elasticsearch指標(biāo)以及節(jié)點(diǎn)級(jí)系統(tǒng)指標(biāo)時(shí),可以集合具體的使用場景挑選出最重要的指標(biāo)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容