操做系統和進程部分java
操做系統和進程部分的含義是很清楚的,這裏不會描述的很詳細。他們列出了基本的資源統計,例如CPU和負載。操做系統部分描述了整個操做系統的狀況,進程部分只是描述了Elasticsearch的JVM進程的使用狀況。node
這顯然是頗有用的統計, 可是每每會被忽視,一些統計包括以下部分:程序員
>CPU
>負載
>內存使用狀況
>swap使用狀況
>打開文件句柄數算法
JVM部分
jvm部分包含一些有關於運行elasticsearch的jvm進程的關鍵信息。最重要的是,它包含了垃圾回收方面的細節,這對你的elasticsearch的集羣的穩定性有很大影響。json
>垃圾收集(GC)入門服務器
在咱們描述這個以前,頗有必要先介紹下GC以及它對elasticsearch的影響。若是你對jvm中的GC很熟悉,能夠跳過這一章。網絡
java是一個本身進行垃圾回收的語言,也就是說程序員不須要主動管理內存的分配和釋放。程序員只要專心寫本身的代碼,java虛擬機會管理根據須要分配內存的過程,而後當內存再也不使用的時候,它本身會去釋放。app
當內存被分配給JVM進程,它會被分配成一個叫堆的大塊區域。JVM會把這個堆分紅兩組,叫作「代」:jvm
年輕代(或者伊甸園)elasticsearch
新實例化的對象就在這裏分配空間,年輕代的空間一般很小,大約100MB-500MB。年輕代包含兩個倖存者區域
老年代
存儲那些老的對象的區域。這些對象是長期存在,而且持續很長時間。老年代一般比年輕代大不少。你能夠看到elasticsearch節點的老年代可能大到30GB
當一個對象被實例化後,它會被放置到年輕代,當年輕代的空間滿了,一個年輕代的垃圾回收就啓動了。那些仍然存活的對象就會被移動到其中一個倖存者區域。而死了的對象就會被清除了。若是一個對象在年輕代中經歷了屢次GC仍然倖存,那它將被晉升到老年代。
相似的過程也發生在老年代,當老年代的空間愈來愈滿了,一個垃圾回收就啓動了,同時死了對象會被清除。
天下沒有免費的午飯,年輕代和老年代的垃圾回收都包含一個「stop-the-world」的階段。在這個時間內,JVM會中止程序的執行,進行對象的標記和收集,在這個stop-the-world的階段,沒有任何事情發生,請求不會被處理,ping不會被會迴應。shards不會再進行遷移。整個世界真的中止了。
對於年輕代這不是一個問題,由於它很小,GC執行的很快。可是對於大一點的老年代,緩慢的GC意味着1s甚至15s的停頓,這對於一個服務器軟件來講是不可接受的。
垃圾回收在JVM是很複雜的算法,爲了減小停頓作了不少的工做。同時Elasticsearch很努力適應GC,好比經過內部對象的重用,利用網絡緩衝區,並挺貴一些特徵值例如文檔的數量。可是GC的頻率和長短是須要你特別留意的信息,由於它是集羣不穩定的頭號元兇。
若是一個集羣常常性的發生長時間GC,那麼你的集羣必定內存不足而且負載特別高。這些長時間GC會致使節點週期性的脫離集羣。這種不穩定會致使分片數據不斷的從新生成,以保證集羣內的平衡以及足夠的分片數量。這會增長網絡貸款和磁盤IO,同時你的集羣還要承擔進行正常的索引數據和查詢。
簡而言之,長時間的GC是很糟糕的,須要儘量的減小。
由於GC對Elasticsearch如此重要,你必須對node stats的API顯示的這個部分特別熟悉才行。
"jvm": { "timestamp": 1408556438203, "uptime_in_millis": 14457, "mem": { "heap_used_in_bytes": 457252160, "heap_used_percent": 44, "heap_committed_in_bytes": 1038876672, "heap_max_in_bytes": 1038876672, "non_heap_used_in_bytes": 38680680, "non_heap_committed_in_bytes": 38993920,
jvm部分首先列出的是有關堆內存使用狀況的通常狀況,你能夠看到多少heap被用到,有多少能夠被使用(已經分配了線程),還有堆內存最大能夠長到多少。理想狀況下heap_committed_in_bytes應該和heap_max_in_bytes相同,若是被分配的堆較小,那JVM將會不得不調整堆的大小,這個過程代價是很高的。若是你的這兩個值是不一樣的,請看《Heap: Sizing and Swapping》章節,確認你配置的是否正確。
heap_used_percent 是你必須盯着看的一個有用的參數。Elasticsearch配置的是當堆使用到75%的時候進行GC,若是你的節點老是大約75%,那你節點正在承受內存方面的壓力,這是一個告警,預示着你不久就會出現慢GC。
若是你的heap使用率一直在85%以上,那你有麻煩了,90-95%的機率會由於10-30s的GC 發生性能問題,這仍是好的,最壞的就是發生內存溢出。
"pools": { "young": { "used_in_bytes": 138467752, "max_in_bytes": 279183360, "peak_used_in_bytes": 279183360, "peak_max_in_bytes": 279183360 }, "survivor": { "used_in_bytes": 34865152, "max_in_bytes": 34865152, "peak_used_in_bytes": 34865152, "peak_max_in_bytes": 34865152 }, "old": { "used_in_bytes": 283919256, "max_in_bytes": 724828160, "peak_used_in_bytes": 283919256, "peak_max_in_bytes": 724828160 } } },
young, survivor, and old sections 顯示了每一個代在GC中的使用狀況,供你分析。這些數據方便你看到他們的相對大小,可是對於你調查問題每每不是很重要。
gc": { "collectors": { "young": { "collection_count": 13, "collection_time_in_millis": 923 }, "old": { "collection_count": 0, "collection_time_in_millis": 0 } } }
gc區域顯示的GC的次數和時間,包括年輕代和老年代。大部分時間,你能夠忽略關於年輕代的手機次數,這個次數每每很大,這是很正常的。
相反,老年代的GC應該少一點,collection_time_in_millis也要小。這是個累計數字,很難給你一個你應該擔憂時候的數字(舉個例子,一個節點運行了一年,可能有不少次GC,可是這個節點卻很健康穩定)。這也是一些工具例如Maverl特別有用的緣由。多長時間內的GC次數是個很重要的考慮因素。
花在GC上的時間也很重要,例如,在索引數據的時候會產生必定量的內存垃圾,這很正常,會讓GC不時的發生。這些GC一般都是很快的,對節點也沒有多少英雄。年輕代只須要一兩毫秒。老年代可能須要幾百毫秒。這和十秒級的GC是很大不一樣的。
咱們最佳的建議是週期性的收集GC的個數和時間(或者使用Marverl) 而且留意頻繁GC,你也能夠打開慢GC日誌,記錄在日誌裏。