注意elasticsearch的版本不一樣,此處的描述可能會有稍許誤差html
Elasticsearch是一款用Java編寫的開源分佈式文檔存儲和搜索引擎,能夠用於near real-time存儲和數據檢索。node
在開始探索性能指標以前,讓咱們來看看Elasticsearch的工做原理,在elasticsearch中,集羣由一個或者更多的節點組成,以下圖:
每一個節點是Elasticsearch的單個運行實例,其「elasticsearch.yml」配置文件指定其所屬的集羣(「cluster.name」)以及它能夠是什麼類型的節點。 配置文件中設置的任何屬性(包括集羣名稱)也能夠經過命令行參數指定。 上圖中的集羣由一個專用主節點和五個數據節點組成。 三種最多見的es節點類型有:數據庫
data節點
默認狀況下(不動配置),每一個節點都是數據節點,以shards的形式存儲數據並執行與索引,搜索和聚合數據相關的操做。
在大集羣中,咱們能夠經過設置node.master : false來設置該節點爲專用數據節點。確保這些節點具備足夠的資源來處理與數據相關的請求,而不須要承擔與集羣相關的管理任務類的工做負載。緩存
client 節點
若是將node.master 和node.data都設置爲false。那麼該節點就是一個client節點。該client節點被設計爲負載均衡器的角色,以幫助路由索引和搜索請求。
client節點有助於承擔部分搜索工做量,以便數據和主節點節點能夠專一於其核心任務。client節點並非必須的,由於數據節點可以本身處理請求路由。若是你的search/index workload比較重,能夠在集羣中配一個client節點。bash
在es中,相關聯的數據一般存儲在相同的索引中,每一個索引包含一組JSON格式的相關聯文檔。Elasticsearch的全文搜索祕訣是Lucene的倒排索引。在索引(存入)數據的時候,es會自動爲每一個字段建立一個倒排索引,倒排索引將索引的詞(terms)映射(map)到包含該詞的文檔(document)中。index被存儲在一個或多個主副shard中,每一個shard都是一個完整的Lucenes實例,是一個完整的迷你搜索引擎。
網絡
建立索引時,能夠指定主分片的數量以及每一個主節點的副本數,默認爲五個分片和一個副本。索引建立後,分片數不能被修改。若是要修改可能須要reindex。副本數能夠在後期被修改。 爲了防止數據丟失,主節點的調度機制會確保主副分片不會出如今同一個數據節點上。併發
Elasticsearch提供了大量的Metric,能夠幫助您檢測到問題的跡象,在遇到節點不可用、out-of-memory、long garbage collection times的時候採起相應措施。 一些關鍵的檢測以下:負載均衡
這裏提供了一個metric蒐集和監控的框架 Monitoring 101 series ,全部這些指標均可以經過Elasticsearch的API以及Elasticsearch的Marvel和Datadog等通用監控工具訪問。框架
搜索請求是Elasticsearch中的兩個主要請求類型之一,另外一個是索引請求。 這些請求有時相似於傳統數據庫系統中的讀寫請求。 Elasticsearch提供與搜索過程的兩個主要階段(查詢和獲取)相對應的度量。 下圖顯示了從開始到結束的搜索請求的路徑。curl
step1. 客戶端向Node 2 發送搜索請求
step2. Node 2(此時客串協調角色)將查詢請求發送到索引中的每個分片的副本
節點處理時,由誰分發,就由誰交付
若是您使用Elasticsearch主要用於搜索,或者若是搜索是面向客戶的功能。您應該監視查詢延遲和設定閾值。 監控關於查詢和提取的相關指標很重要,能夠幫助您肯定搜索隨時間的變化。 例如,您可能但願跟蹤查詢請求的尖峯和長期增加,以便您能夠作好準備。
搜索性能指標的要點:
索引請求相似於傳統數據庫系統中的寫入請求,若是es的寫入工做量很重,那麼監控和分析您可以如何有效地使用新數據更新索引很是重要。在瞭解指標以前,讓咱們來探索Elasticsearch更新索引的過程,在新數據被添加進索引、更新或刪除已有數據,索引中的每一個shard都有兩個過程:refresh 和 flush Index fresh 新索引的文檔不能立馬被搜索的。 首先,它們被寫入一個內存中的緩衝區(in-memory buffer),等待下一次索引刷新,默認狀況下每秒一次。刷新是以in-memory buffer爲基礎建立in-memory segment的過程(The refresh process creates a new in-memory segment from the contents of the in-memory buffer )。這樣索引進的文檔才能是可被搜索的,建立完segment後,清空buffer 以下圖:
A special segment on segments
索引由shards構成,shard又由不少segments組成,The core data structure from Lucene, a segment is essentially a change set for the index. 這些segments在每次刷新的時候被建立,隨後會在後臺進行合併,以確保資源的高效利用(每一個segment都要佔file handles、memory、CPU) segments 是mini的倒排索引,這些倒排索引映射了terms到documents。每當搜索索引的時候,每一個主副shards都必須被遍歷。更深一步說shards上的每一個segment會被依次搜索。 segment是不可變的,所以updating a document 意味着以下:
當多個outdated segment合併後纔會被刪除。(意思是不單個刪除,合併後一塊兒刪)。
Index flush
在新索引的document添加到in-memory buffer的同時,它們也會被附加到分片的translog(a persistent, write-ahead transaction log of operations)中。 每隔30分鐘,或者每當translog達到最大大小(默認狀況下爲512MB)時,將觸發flush 。在flush 期間,在in-memory buffer上的documents會被refreshed(存到新的segments上),全部內存中的segments都提交到磁盤,而且translog被清空。 translog有助於防止節點發生故障時的數據丟失。 It is designed to help a shard recover operations that may otherwise have been lost between flushes. 這個translog每5秒將操做信息(索引,刪除,更新或批量請求(以先到者爲準))固化到磁盤上。
Elasticsearch提供了許多指標,可用於評估索引性能並優化更新索引的方式。
索引性能指標的要點:
curl -XPUT <nameofhost>:9200/<name_of_index>/_settings -d '{ "index" : { "refresh_interval" : "-1" } }'
完成索引後,您能夠恢復爲默認值「1s」
在運行Elasticsearch時,內存是您要密切監控的關鍵資源之一。 Elasticsearch和Lucene以兩種方式利用節點上的全部可用RAM:JVM heap和文件系統緩存。 Elasticsearch運行在Java虛擬機(JVM)中,這意味着JVM垃圾回收的持續時間和頻率將成爲其餘重要的監控領域。
JVM heap: A Goldilocks tale
Elasticsearch強調了JVM堆大小的重要性,這是「正確的」 - 不要將其設置太大或過小,緣由以下所述。 通常來講,Elasticsearch的經驗法則是將少於50%的可用RAM分配給JVM堆,而不會超過32 GB。 您分配給Elasticsearch的堆內存越少,Lucene就可使用更多的RAM,這很大程度上依賴於文件系統緩存來快速提供請求。 可是,您也不想將堆大小設置得過小,由於應用程序面臨來自頻繁GC的不間斷暫停,可能會遇到內存不足錯誤或吞吐量下降的問題 Elasticsearch的默認安裝設置了1 GB的JVM heap大小,對於大多數用例來講,過小了。 您能夠將所需的heap大小導出爲環境變量並從新啓動Elasticsearch:
export ES_HEAP_SIZE=10g
如上咱們設置了es heap大小爲10G,經過以下命令進行校驗:
curl -XGET http://:9200/_cat/nodes?h=heap.max
Garbage collection
Elasticsearch依靠垃圾收集過程來釋放heap memory。由於垃圾收集使用資源(爲了釋放資源!),您應該注意其頻率和持續時間,以查看是否須要調整heap大小。設置過大的heap會致使GC時間過長,這些長時間的停頓會讓集羣錯誤的認爲該節點已經脫離。
JVM指標的要點:
雖然Elasticsearch經過API提供了許多特定於應用程序的指標,但您也應該從每一個節點收集和監視幾個主機級別的指標。 Host指標要點:
能夠用任何語言發送請求,但Java將使用RESTful API經過HTTP與Elasticsearch進行通訊。 若是打開的HTTP鏈接總數不斷增長,可能表示您的HTTP客戶端沒有正確創建持久鏈接。 從新創建鏈接會在您的請求響應時間內添加額外的毫秒甚至秒。 確保您的客戶端配置正確,以免對性能形成負面影響,或使用已正確配置HTTP鏈接的官方Elasticsearch客戶端。
指標要點:
es節點使用線程池來管理線程如何消耗內存和CPU。 因爲線程池設置是根據處理器數量自動配置的,因此調整它們一般沒有意義。However, it’s a good idea to keep an eye on queues and rejections to find out if your nodes aren’t able to keep up; 若是沒法跟上,您可能須要添加更多節點來處理全部併發請求。Fielddata和過濾器緩存使用是另外一個要監視的地方,as evictions may point to inefficient queries or signs of memory pressure.
Thread pool queues and rejections
每一個節點維護許多類型的線程池; 您要監視的確切位置將取決於您對es的具體用途,通常來講,監控的最重要的是搜索,索引,merge和bulk,它們與請求類型(搜索,索引,合併和批量操做)相對應。 線程池隊列的大小反應了當前等待的請求數。 隊列容許節點跟蹤並最終服務這些請求,而不是丟棄它們。 一旦超過線程池的maximum queue size,Thread pool rejections就會發生。
指標要點:
Bulk rejections and bulk queues: 批量操做是一次發送許多請求的更有效的方式。 一般,若是要執行許多操做(建立索引或添加,更新或刪除文檔),則應嘗試以批量操做發送請求,而不是發送許多單獨的請求。 bulk rejections 一般與在一個批量請求中嘗試索引太多文檔有關。根據Elasticsearch的文檔,批量rejections並非很須要擔憂的事。However, you should try implementing a linear or exponential backoff strategy to efficiently deal with bulk rejections。
Cache usage metrics: 每一個查詢請求都會發送到索引中的每一個分片的每一個segment中,Elasticsearch caches queries on a per-segment basis to speed up response time。另外一方面,若是您的緩存過多地堆積了這些heap,那麼它們可能會減慢速度,而不是加快速度! 在es中,文檔中的每一個字段能夠以兩種形式存儲:exact value 和 full text。 例如,假設你有一個索引,它包含一個名爲location的type。每一個type的文檔有個字段叫city。which is stored as an analyzed string。你索引了兩個文檔,一個的city字段爲「St. Louis」,另外一個的city字段爲「St. Paul」。在倒排索引中存儲時將變成小寫並忽略掉標點符號,以下表
分詞的好處是你能夠搜索st。結果會搜到兩個。若是將city字段保存爲exact value,那隻能搜「St. Louis」, 或者 「St. Paul」。 Elasticsearch使用兩種主要類型的緩存來更快地響應搜索請求:fielddata和filter。
3.如今反向索引被再反向,從doc中compile 獨立的tokens(st, louis, and paul)。compile這樣的fielddata可能會消耗大量堆內存。特別是大量的documents和terms的狀況下。 全部字段值都將加載到內存中。對於1.3以前的版本,fielddata緩存大小是無限制的。 從1.3版開始,Elasticsearch添加了一個fielddata斷路器,若是查詢嘗試加載須要超過60%的堆的fielddata,則會觸發。
pending task只能由主節點來進行處理,這些任務包括建立索引並將shards分配給節點。任務分優先次序。若是任務的產生比處理速度更快,將會產生堆積。待處理任務的數量是您的羣集運行平穩的良好指標,若是您的主節點很是忙,而且未完成的任務數量不會減小,咱們須要仔細檢查緣由。