探索ElasticSearch-无任何索引数据的ElasticSearch状态(八)

523 阅读6分钟

前言

之前做了一些简单的ElasticSearch的基准测试,但是现在看来还是有两个方面的缺点。一个是不够全面,只是简单测试了下3种线程场景,另外一个是可能机器环境,感觉一直没有压上去。之后打算重新搞一下基准测试。今天想来看看一个基本上没有索引数据的ElasticSearch的内存占用和其他相关指标(Segment,Lucene...)的状态。这样做到在最少的环境下心里有个数,感觉还是非常重要的。很多人都忘记了,其实计算机是一种科学。这种应该是控制变量法吧?

通过本文,可以让你得知以下ElasticSearch的状态。

  • 初始JVM占用大小和变化幅度
  • 初始CPU状态
  • 初始Segment大小
  • 改变JVM大小的影响

ElasticSearch

初始环境

目的是想要搭建一个纯粹ElasticSearch的环境。但是,无奈,又想要观测ElasticSearch的各项指标。又想要一个干净的ElasticSearch实在有些强人所难。毕竟在使用Kibana采集ElasticSearch的时候,需要在ElasticSearch上面建立索引。

但是,还好这些索引对ElasticSearch的影响应该是非常小。我们把他们列在下面。

可以看到使用KibanaElasticSearch进行监控的时候,存在4个索引。每个索引存在一个主分片,没有副本。总小大不超过1M。

另外用来监控的索引,也会有少量的查询。大概Search Total2-5左右。Index Total1左右。

把这些都列出来,做到心中有数。

各项指标

JVM占用和GC

然后,我们让ElasticSearch运行一段时间,重点关注初始的JVM的占用。如下图所示。

可以看到在没有任何索引情况下,ElasticSearch启动所需要的内存大小大概在400-500之间。存在100MB左右的浮动。

通过观察GC CountGC Duration可以发现存在100MB左右的波动,看来是存在了Young GC导致的。

我们可以通过jstat命令再深入了解下当前ElasticSearchJVM情况。

通过jstat,我们可以发现当前Eden区占用了273MB,每隔1秒钟会增加10MB多点。所以,我们可以估算大概20次左右就会触发一次Young GC,回收掉Eden区的内存。

但是,观察下图,会发现在5分钟内折线向下的只有大概6次左右。不是说每个20次左右会发生一次Young GC,折线向下的应该会更加密集才对啊。其实这里是因为图像采集的频率是不一样的。所以,导致这里的折线和预估的有差距。估计Kibana应该是10s采集一次JVM内存信息。因为我数了一下1min内,存在大概6,7个点。不过,目前来看修改上面的refresh时间好像不能改变Kibana的采集频率。

所以,我们要学习估计的能力来总体评估JVMGC的状态。

CPU

其实CPU没啥说的。在没有写入和查询的时候,基本不会消耗CPU资源。如下图所示。

CPU使用率基本上都在%0-%1

Segment

Segment Count目前在20左右。考虑到存在用于监控ElasticSearch的4个索引,每个索引含有的1个分片。所以,总共有4个分片。

我们知道ElasticSearch的分片其实都是Lucene的索引。而每个Lucene的索引都由Segment组成。Segment由于不可改变的特性,导致会在索引新数据时,创建新的Segment。当Segment太多时,多个Segment又会merge成为一个大的Segment

所以,我个人觉得在不考虑有索引的情况下,应该会有4个Segment。但是,这里是会存在索引监控数据的情况的。

但是,居然导致了20左右的Segment还是我始料未及的。难道,每个分片都要创建5个左右的Segment

如果和分片数量有关,那么可以在下次增加索引的分片数来看看是否是正相关的。

改变变量-JVM大小

在对照中,我们才能感受到在实验中各个元素的作用。我们尝试改变下JVM大小。

打开jvm.options,修改Java的启动参数为-Xms2g -Xmx2g,也就是扩大了一倍的内存。如下图所示。

对于Segment数量,加大JVM内存基本上没有多大的影响。我们还是重点观察下JVM内存相关的内容。

可以看到整个内存占用的线整体向上移动了。其实,熟悉JVM的同学可以猜测到这是因为分配给Eden区的大小上升了。临时对象需要到达一个更高的点才能够被回收掉。

另外GC Count的值也变小了。毕竟回收后剩余的空间变大了。对象需要更长的时间才能够填满Eden区。

通过jstat查看gc详细情况。注意Eden区的大小和后面使用4gJVM时做一个对比。

再次翻倍JVM大小,查看尽量明显的信息。当前JVM为4G大小。

可以看到当前JVM为4g和2g时,相差也不是很大。很奇怪的是,为什么JVMEden区没有明显地增大呢?

通过jstat可以发现JVM4G时和JVM2G时所分配的Eden区的大小并没有发生变化。因为没有显式修改JVMEden区域的大小。所以,可能是JVM的某一个策略把。

好,最后一个问题是无论是JVM2G还是JVM4G,在Young GC之后,都存在大概350MB左右的内存没有被回收,这些对象是在哪里呢?

其实是存储在老年代、元数据区里面的对象。

留下个疑问

最后还给自己留下一个疑问?看下图。

好像是JVM的内存大小和Doc Values有一定的关系?随着内存的加大Doc Values好像是趋向去稳定?

关于写作

以后这里每天都会写一篇文章,题材不限,内容不限,字数不限。尽量把自己每天的思考都放入其中。

如果这篇文章给你带来了一些帮助,可以动动手指点个赞,顺便关注一波就更好了。

如果上面都没有,那么写下读完之后最想说的话?有效的反馈和你的鼓励是对我最大的帮助。

另外打算把博客给重新捡起来了。欢迎大家来访问吃西瓜

我是shane。今天是2019年9月9日。百天写作计划的第四十六天,47/100。