Elasticsearch是一個開源的分佈式文檔存儲和搜索引擎,能夠近乎實時地存儲和檢索數據結構,它很大程度上依賴於Apache Lucence--一個用Java編寫的全文搜索引擎。node
Elasticsearch以結構化JSON文檔的形式呈現數據,並經過RESTful API和web客戶端爲PHP,Python和Ruby等語言提供全文搜索。Elasticsearch服務是具備彈性的,由於它易於水平擴展--只需添加更多節點便可分配負載。如今有不少企業動用它來動態存儲,搜索和分析大量數據,包括維基百科,eBay,Github和Datadog。ios
在探討性能指標以前,先來看看Elasticsearch的工做方式。在Elasticsearch中,集羣由一個或多個節點組成,以下 web
每一個節點都是單個Elasticsearch實例,其elasticsearch.yml
配置文件制定它屬於哪一個集羣(cluster.name
)以及它是哪一種類型的節點。配置文件中設置的任何屬性(包括集羣名稱)也能夠經過命令行參數指定。上圖中的集羣由一個專用主節點和五個數據節點組成。算法
Elasticsearch中最多見的三種類型的節點是:數據庫
node.data
爲false
),來提升可靠性。在高使用率的環境中,將主節點和數據節點分開有助於確保老是有足夠的資源分配給只有主節點能夠處理的任務。node.master: false
來建立專用數據節點,來確保這些節點有足夠的資源來處理與數據相關的請求,而無需處理集羣相關管理任務的額外工做量。node.master
和node.data
設置爲false
,那麼該節點會成爲一個客戶節點,用做一個負載均衡器,以幫助路有索引和搜索請求。客戶端節點能夠承擔一部分的搜索工做量,以便讓數據節點和主節點能夠專一於核心任務。根據使用狀況,客戶節點可能不是必須的,由於數據節點可以自行處理請求路由。可是,若是搜索|索引的工做負載足夠大,能夠利用客戶節點來幫助路有請求。在Elasticsearch中,相關數據一般存儲在同一個索引中,能夠將其視爲配置邏輯包裝的等價物。每一個索引都包含一組JSON格式的相關文檔。Elasticsearch的全文索引使用的是Lucence的倒排索引。爲文檔建立索引時,Elasticsearch會自動爲每一個字段建立倒排索引;倒排索引將字段映射到包含這些字段的文檔。apache
索引存儲在在主分片(一個或多個)和副本分片(零個或多個)中,每一個分片都是一個Lucence的完整實例,能夠當成一個迷你搜索引擎。緩存
當建立索引時,能夠制定主分片的數量以及每一個主分片的副本數量。默認值爲每一個索引五個主分片,每一個主分片一個副本。在索引被建立後,主分片的數量沒法更改,所以在選擇數量時要謹慎,不然後面可能須要從新創建索引。副本的數量能夠在後面根據需求更新。爲了防止數據丟失,主節點確保每一個副本分片不會和主分片分配到同個節點上。bash
Elasticsearch提供了大量指標,能夠幫助用戶檢測出故障跡象,並在遇到諸如不可靠節點,內存不足和GC時間過長等問題時採起措施。一些須要監控的關鍵指標是:網絡
上面列出的指標均可以經過Elasticsearch的API以及像Elastic的Marvel這樣的工具收集到。數據結構
搜索請求和索引請求是Elasticsearch中的兩個主要請求類型。在某種程度上,這些請求和傳統數據庫系統中的讀取和寫入請求很相似。Elasticsearch提供了與搜索過程的兩個主要階段(查詢和提取)相對應的指標。一次搜索請求從開始到結束的路徑以下
當Elasticsearch主要用於搜索時,有必要監控查詢延遲並在超過闕值時採起措施。監控有關查詢和提取的相關指標很是重要,這些指標能夠幫助肯定在一段時間內的搜索性能。好比,能夠跟蹤查詢請求中的峯值和長期的的增加趨勢,以準備優化配置來得到更好的性能和可靠性。
指標描述 | 指標名 | 指標類型 |
---|---|---|
query總數 | indices.search.query_total | 吞吐量 |
query總耗時 | indices.search.query_time_in_millis | 性能 |
當前在處理的query數量 | indices.search.query_current | 吞吐量 |
fetch總數 | indices.search.fetch_total | 吞吐量 |
fetch總耗時 | indices.search.fetch_time_in_millis | 性能 |
當前在處理的fetch數量 | indices.search_fetch_current | 吞吐量 |
Query 負載:監控當前正在進行的query數量能夠大體瞭解集羣在任何特定時刻處理的請求數量。能夠考慮在出現異常尖峯和驟降時發出警告。
Query延遲:儘管Elastisearch沒有明確提供這個指標,可是能夠用現有指標來推算這個值,算法是按期用查詢總數除以總耗時。
Fetch延遲:搜索的第二階段(fetch階段)一般比query階段耗時要少。若是這個值持續增長,可能意味着磁盤速度慢,或者請求的結果數量過多。
索引請求相似於傳統數據庫系統中的寫請求。若是Elasticsearch集羣主要用於索引,那麼對索引性能的監控是很是有必要的。在討論監控指標前,咱們先看看Elasticsearch處理索引的方式。當在索引中添加新信息或者刪除現有信息時,索引中的每一個分片都會經過兩個步驟更新:refresh和flush。
新加入到索引的文檔不能當即用於搜索,這些文檔會先被寫入內存緩衝區,等待下一次索引刷新,默認狀況下每秒刷新一次。refresh先從以前內存緩衝區中建立新的內存段,讓這些內容可以被搜索到,而後清空緩存區,過程以下
索引的分片由多個段組成。這個Lucene的核心數據結構,一個段實際上索引的變動集。每一個段使用文件,內存和CPU,爲了有效利用這些資源,這些段在每次刷新時建立,隨後合併。
段是微型的倒排索引,能夠將詞映射到包含這些詞的文檔。每次搜索索引時,依次搜索主分片或者副本分片,在分片中搜索每一個分段。
段是不可變的,因此更新文檔會:
當過時段與另外一個段合併時,最終會刪除舊信息。
在將新索引文檔添加到內存緩衝區的同時,這些內容也會添加到分片的translog,translog用於持久記錄操做的日誌。每隔30分鐘,或者當translog大小到達最大時(默認是512MB),會觸發一次flush操做。在flush期間,內存緩衝區的任何文檔都會刷新(存儲在新段中),全部內存中的段都會提交到磁盤,同時translog被清空。
translog有助於防止節點故障時丟失數據。能夠用translog幫助恢復可能在刷新之間丟失的操做。日誌每5秒提交到磁盤;或在索引,刪除,更新或批量請求成功後,日誌提交到磁盤。流程以下
Elasticsearch提供了不少有關索引的指標
指標描述 | 指標名 | 指標類型 |
---|---|---|
索引的文檔總數 | indices.indexing.index_total | 吞吐量 |
索引文檔總耗時 | indices.indexing.index_time_in_millis | 性能 |
當前索引的文檔數 | indices.indexing.index_current | 吞吐量 |
索引refresh總數 | indices.refresh.total | 吞吐量 |
refresh總耗時 | indices.refresh.total_time_in_millis | 吞吐量 |
索引flush到磁盤總數 | indices.flush.total | 吞吐量 |
flush總耗時 | indices.flush.total_time_in_millis | 吞吐量 |
索引延遲:Elasticsearch並不直接提供這個指標,不過能夠根據index_total
和index_time_in_millis
算出來。若是注延遲增長,多是由於一次索引的太多文檔(Elastisearch建議批量索引大小爲5MB-15MB)。
若是計劃索引大量文檔,而且不須要新的信息可當即用於搜索,能夠經過下降刷新頻率來優化索引性能而不是搜索性能,直到完成索引。
Flush延遲:因爲數據在成功完成刷新以前不會持久保存到磁盤,所以跟蹤刷新延遲並在性能開始下潛時採起措施會頗有用。若是看到此指標穩步增長,則可能表示磁盤速度較慢;此問題可能會升級並最終阻止向索引添加新文檔。在這種狀況下,能夠嘗試下降index.translog.flush_threshold_size
,此設置肯定在觸發刷新以前translog大小能夠達到的大小。若是Elasticsearch寫比較重,能夠考慮使用iostat
關注磁盤I/O。
內存是須要監控的關鍵指標之一。Elasticsearch和Lucene以兩種方式利用節點上的全部可用內存:JVM堆和文件系統緩存。Elasticsearch在Java虛擬機(JVM)中運行,這意味着JVM垃圾收集的持續時間和頻率也是須要監控起來的。
使用Elasticsearch須要設置適當的JVM堆大小。通常來講,Elasticsearch的經驗法則是將不到50%的可用RAM分配給JVM堆,永遠不會高於32GB。分配給Elasticsearch的堆內存越小,Lucene可用的內存就越多,而Lucene很大程度上依賴於文件系統緩存來快速響應請求;可是也不能設置的過小,由於可能會遇到內存不足,或者由於頻繁GC致使吞吐量下降。這篇博客有詳細描述。
Elasticsearch默認設置JVM堆大小爲1G,在大多數場景下這個都過小,能夠所須要的堆大小導出爲環境變量,而後從新啓動Elasticsearch。
export ES_HEAP_SIZE=10g
複製代碼
Elasticsearch依賴於垃圾收集(GC)進程來釋放堆內存。須要留意GC的頻率和持續時間。將堆設置得太大會致使垃圾收集時間過長;這些過分暫停是危險的,會致使集羣中其餘節點認爲該節點失去響應。
指標描述 | 指標名 | 指標類型 |
---|---|---|
年輕代垃圾回收總數 | jvm.gc.collectors.young.collection_count | |
年輕代垃圾回收耗時 | jvm.gc.collectors.young.collection_time_in_millis | |
年老代垃圾回收總數 | jvm.gc.collectors.old.collection_count | |
年老代垃圾回收耗時 | jvm.gc.collectors.old.collection_time_in_millis | |
當前JVM堆佔比 | jvm.mem.heap_used_percent | |
已提交的JVM堆量 | jvm.mem.heap_committed_in_bytes |
在使用的JVM堆: Elasticsearch設置爲在JVM堆使用率達到75%時啓動垃圾回收。監視哪些節點表現出高堆使用率並設置警報以查明是否有任何節點始終使用超過85%的堆內存可能頗有用:這代表垃圾收集的速度跟不上垃圾建立的速度。要解決這個問題,能夠增長堆大小,或者經過添加更多節點來擴展羣集。
已使用的堆和已提交的堆:使用的堆內存量一般採用鋸齒模式,當垃圾堆積時會上升,當收集垃圾時會降低。已使用堆和已提交堆比例增長時,意味着垃圾收集的速率跟不上對象建立的速度,這可能致使垃圾收集時間變慢,並最終致使OutOfMemoryErrors。
GC持續時間和頻率:回收年輕代和年老代垃圾回收都會經歷「世界中止」階段,由於JVM中止執行程序來進行回收。在這段時間內,節點沒法完成任何任務。主節點會每隔30秒檢查其餘節點狀體啊,如何任何節點的垃圾回收時間超過30秒,主節點將認爲這個節點已經掛掉。
內存使用率:如上所述,Elasticsearch充分利用了還沒有分配給JVM堆的任何RAM,其依靠操做系統的文件系統緩存來快速可靠地處理請求。有許多變量決定Elasticsearch是否成功從文件系統緩存中讀取。若是段文件最近由Elasticsearch寫入磁盤,則它已在緩存中;可是,若是節點已關閉並從新啓動,則第一次查詢段時,極可能必須從磁盤讀取信息。這是須要爲何確保集羣保持穩定而且節點不會崩潰的重要緣由之一。
I/O:在建立,查詢和合並段時,Elasticsearch會對磁盤進行大量寫入和讀取操做。對於具備持續經歷大量I / O活動的節點的大量集羣,Elasticsearch建議使用SSD來提升性能。
CPU使用率:可視化CPU使用率會頗有用。CPU使用率增長一般是由大量搜索和索引請求致使。
網絡流出/流入字節數:節點之間的通訊是平衡羣集的關鍵。除了Elasticsearch提供有關羣集通訊的傳輸指標,還能夠查看網卡發送和接收的字節速率。
打開文件數:文件描述符用於節點到節點通訊,客戶端鏈接和文件操做。若是此數字達到系統的最大容量,則在舊的鏈接關閉以前,將沒法進行新的鏈接和文件操做。
指標描述 | 指標名 | 指標類型 |
---|---|---|
集羣狀態 | cluster.health.status | |
節點數量 | cluster.health.number_of_nodes | 可用性 |
初始化中的分片數 | cluster.health.initializing_shards | 可用性 |
未分配分片數 | cluster.health.unassigned_shards | 可用性 |
集羣狀態:若是羣集狀態爲黃色,則至少有一個副本分片未分配或丟失。搜索結果仍然完整,但若是更多分片消失,可能會丟失數據。
紅色羣集狀態表示至少缺乏一個主分片,而且數據正在丟失,這意味着搜索將返回部分結果。
初始化中和未分配的分片:首次建立索引或從新啓動節點時,其主機節點嘗試將分片分配給節點時,其分片將在轉換爲「已啓動」或「未分配」狀態以前暫時處於「初始化」狀態。若是發現分片在初始化或未分配狀態下保留的時間過長,則可能表示集羣不穩定。
在這篇文章中,咱們介紹了Elasticsearch的一些最重要的領域,以便在擴展和擴展集羣時對其進行監控。
在監視Elasticsearch指標以及節點級系統指標時,能夠集合具體的使用場景挑選出最重要的指標。