Before you begin reading this guide, we recommend you try running the Elasticsearch Error Check-Up which can resolve issues that cause many errors.
This guide will help you check for common problems that cause the log ” Gc duration . collections /. total /. memory /. all_pools ” to appear. It’s important to understand the issues related to the log, so to get started, read the general overview on common issues and tips related to the Elasticsearch concepts: memory and monitor.
Advanced users might want to skip right to the common problems section in each concept or try running the Check-Up which analyses ES to pinpoint the cause of many errors and provides suitable actionable recommendations how to resolve them (free tool that requires no installation).
Overview
Memory is one of the most critical resources to monitor in Elasticsearch. Elasticsearch runs on JVM and uses heap memory areas for query cache, request cache, accessing lucene segments and storing fielddata for aggregations and sorting.
Common problems and important points
- The most common error that arises in Elasticsearch is OutOfMemory error. This error comes when the node is not able to cope up with the required heap size space. To avoid this, you need to closely monitor the heap utilization and garbage collector performance.
- As per the most up-to-date best practices you should not allocate more than 50 percent of total RAM to JVM heap size. Starting from Elasticsearch version 5.x onward this can be set using -Xms and -Xmx parameters inside jvm.options configuration file. The defaults are set to 1 GB for both minimum and maximum heap size.
- The heap size should not set more than 31 GB in any case to avoid the poor garbage collection.
Log Context
Log “[gc][{}][{}][{}] duration [{}]; collections [{}]/[{}]; total [{}]/[{}]; memory [{}]->[{}]/[{}]; all_pools {}” classname is JvmMonitorService.java
We extracted the following from Elasticsearch source code for those seeking an in-depth context :
} long avgCollectionTime = collectionTime / collections; if (avgCollectionTime > gcThreshold.warnThreshold) { logger.warn("[gc][{}][{}][{}] duration [{}]; collections [{}]/[{}]; total [{}]/[{}]; memory [{}]->[{}]/[{}]; all_pools {}"; gc.name(); seq; gc.collectionCount(); TimeValue.timeValueMillis(collectionTime); collections; TimeValue.timeValueMillis(currentJvmStats.timestamp() - lastJvmStats.timestamp()); TimeValue.timeValueMillis(collectionTime); gc.collectionTime(); lastJvmStats.mem().heapUsed(); currentJvmStats.mem().heapUsed(); JvmInfo.jvmInfo().mem().heapMax(); buildPools(lastJvmStats; currentJvmStats)); } else if (avgCollectionTime > gcThreshold.infoThreshold) { logger.info("[gc][{}][{}][{}] duration [{}]; collections [{}]/[{}]; total [{}]/[{}]; memory [{}]->[{}]/[{}]; all_pools {}"; gc.name(); seq; gc.collectionCount(); TimeValue.timeValueMillis(collectionTime); collections; TimeValue.timeValueMillis(currentJvmStats.timestamp() - lastJvmStats.timestamp()); TimeValue.timeValueMillis(collectionTime); gc.collectionTime(); lastJvmStats.mem().heapUsed(); currentJvmStats.mem().heapUsed(); JvmInfo.jvmInfo().mem().heapMax(); buildPools(lastJvmStats; currentJvmStats)); } else if (avgCollectionTime > gcThreshold.debugThreshold && logger.isDebugEnabled()) {