确保系统持续、稳定的运行是系统管理人员必须具备的基本素质。正常部署ELK日志分析平台,运行一个月后我们正有感于系统带来的方便之时,自动化监控平台发现一台Elasticsearch节点崩溃了。
报错类似如下部分:
[2018-06-29T08:40:07,221][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [node02] fatal error in thread [elasticsearch[node02][bulk][T#2]], exiting
java.lang.OutOfMemoryError: Java heap space
很明显依赖的java堆内存超标了(ES默认配置是2G),查看官网介绍:JVM 堆是有限资源的,应该被合理利用。限制fielddata对堆使用的影响有多套机制,这些限制方式非常重要,因为堆栈的乱用会导致节点不稳定(感谢缓慢的垃圾回收机制),甚至导致节点宕机(通常伴随 OutOfMemory 异常)。
更改配置信息,观察一个月发现问题得到解决。
jvm.options
-Xms4g
-Xmx4g
此处系统内存的50%
elasticsearch.yml
限制fielddata 上限
indices.fielddata.cache.size: 20%
本次问题中有个JVM的概念,我们来温习一下。对操作系统来说JVM是一个的进程,这个进程的基本结构如下,包括:类加载器子系统、运行时数据区、执行引擎和本地方法接口。
操作系统把一个程序在内存中所占的空间分为:方法区、数据区、堆区、栈区,同样,JVM在内存中也有JVM方法区、JVM数据区、堆区和栈区。
代码区 :中存放应用程序的机器代码,运行过程中代码不能被修改,具有只读和固定大小的特点。
数据区: 中存放了应用程序中的全局数据,静态数据和一些常量字符串等,其大小也是固定的。
堆: 是运行时程序动态申请的空间,属于程序运行时直接申请、释放的内存资源。
栈区: 用来存放函数的传入参数、临时变量,以及返回地址等数据。未使用区是分配新内存空间的预备区域。
其中堆内存(Heap memory)的设置是非常重要的,因为java的运行取决于一个合理的堆(heap)大小,如果太小,在许多垃圾回收或是高性能的情况下就会出现OutOfMemory异常,如果堆太大,垃圾回收将需要更大的数据,该算法将要面对更高数量的存活堆,这使操作系统也会面对较大的压力。
所以可以通过监控JVM的使用情况来推算设置一个更优的堆大小数据,比如使用java自带的visualVM工具(JAVA_HOME\bin\目录下的jvisualvm.exe)就可以满足哦,有兴趣的同学可以玩一玩,MAY U HAVA FUN !
相关阅读
参考:
CSDN:JVM的基本结构
ES官网API