[翻译]Elasticsearch重要文章之四:监控每一个节点(jvm部分)

http://zhaoyanblog.com/archives/753.htmlhtml

 

操做系统和进程部分java

操做系统和进程部分的含义是很清楚的,这里不会描述的很详细。他们列出了基本的资源统计,例如CPU和负载。操做系统部分描述了整个操做系统的状况,进程部分只是描述了Elasticsearch的JVM进程的使用状况。node

这显然是颇有用的统计, 可是每每会被忽视,一些统计包括以下部分:程序员

>CPU
>负载
>内存使用状况
>swap使用状况
>打开文件句柄数算法

JVM部分
jvm部分包含一些有关于运行elasticsearch的jvm进程的关键信息。最重要的是,它包含了垃圾回收方面的细节,这对你的elasticsearch的集群的稳定性有很大影响。服务器

>垃圾收集(GC)入门网络

在咱们描述这个以前,颇有必要先介绍下GC以及它对elasticsearch的影响。若是你对jvm中的GC很熟悉,能够跳过这一章。app

java是一个本身进行垃圾回收的语言,也就是说程序员不须要主动管理内存的分配和释放。程序员只要专心写本身的代码,java虚拟机会管理根据须要分配内存的过程,而后当内存再也不使用的时候,它本身会去释放。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日志,记录在日志里。

相关文章
相关标签/搜索