Hi all Igniters,

I am trying to minimize Ignite's memory consumption on my server.

Some background:
My server has 16GB RAM, and is supposed to run applications other than
Ignite.
I use Ignite to store a cache. I use the TRANSACTIONAL_SNAPSHOT mode and I
don't use persistence (configuration file attached). To read and update the
cache I use SQL queries, through ODBC Client in C++ and through an
embedded client-mode node in C#.
My data consists of a table with 5 columns, and I guess around tens of
thousands of rows.
Ignite metrics tell me that my data takes 167MB ("CFGDataRegion region
[used=167MB, free=67.23%, comm=256MB]", This region contains mainly this
one cache).

At the beginning, when I didn't tune the JVM at all, the Apache.Ignite
process consumed around 1.6-1.9GB of RAM.
After I've done some reading and research, I use the following JVM options
which have brought the process to consume around 760MB as of now:
-J-Xms512m
-J-Xmx512m
-J-Xmn64m
-J-XX:+UseG1GC
-J-XX:SurvivorRatio=128
-J-XX:MaxGCPauseMillis=1000
-J-XX:InitiatingHeapOccupancyPercent=40
-J-XX:+DisableExplicitGC
-J-XX:+UseStringDeduplication

Currently Ignite is up for 29 hours on my server. When I only started the
node, the Apache.Ignite process consumed around 600MB (after my data
insertion, which doesn't change much after), and as stated, now it consumes
around 760MB. I've been monitoring it every once in a while and this is not
a sudden rise, it has been rising slowly but steadily ever since the node
has started.
I used DBeaver to look into node metrics system view
<https://apacheignite.readme.io/docs/node_metrics>, and I turned on the
garbage collector logs. The garbage collector log shows that heap is
constantly growing, but I guess this is due to the SQL queries and their
results being stored there. (There are a few queries in a second, the
results normally contain one row but can contain tens or hundreds of rows).
After every garbage collection the heap usage is between 80-220MB. This is
in accordance to what I see under HEAP_MEMORY_USED system view metric.
Also, I can see that NONHEAP_MEMORY_COMITTED is around 102MB and
NONHEAP_MEMORY_USED is around 98MB.

My question is, what could be causing the constant growth in memory usage?
What else consumes memory that doesn't appear in these metrics?

Thanks for your help!
<!--
    Ignite Spring configuration file to startup Ignite cache.
    This file demonstrates how to configure cache using Spring. Provided cache
    will be created on node startup.
    Use this configuration file when running HTTP REST examples (see 'examples/rest' folder).
    When starting a standalone node, you need to execute the following command:
    {IGNITE_HOME}/bin/ignite.{bat|sh} examples/config/example-cache.xml
    When starting Ignite from Java IDE, pass path to this file to Ignition:
    Ignition.start("examples/config/example-cache.xml");
-->
<beans xmlns="http://www.springframework.org/schema/beans";
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd";>
	<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
        <property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.zk.ZookeeperDiscoverySpi">
                <property name="zkConnectionString" value="vmnero:2181"/>
                <property name="sessionTimeout" value="30000"/>
                <property name="zkRootPath" value="/apacheIgnite"/>
                <property name="joinTimeout" value="10000"/>
            </bean>
        </property>
        
		<property name="clientConnectorConfiguration">
			<bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">	
				<property name="host" value="0.0.0.0"/>
				<property name="port" value="11110"/>
				<property name="portRange" value="1"/>
			</bean>
		</property>
        
        <property name="ConnectorConfiguration.jettyPath" value="config\ignite_rest.xml"/>
        
		<property name="dataStorageConfiguration">
			<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
				<property name="dataRegionConfigurations">
					<list>
						<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
							<property name="name" value="CFGDataRegion"/>
							<property name="initialSize" value="#{256L * 1024 * 1024}"/>
							<property name="maxSize" value="#{512L * 1024 * 1024}"/>
							<property name="persistenceEnabled" value="false"/>
							<property name="metricsEnabled" value="true"/>							
						</bean>
					</list>
				</property>
                <!-- define Ignite's default data region's size -->
                <property name="defaultDataRegionConfiguration">
                    <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                        <property name="name" value="Default_Region"/>
                        <property name="initialSize" value="#{32L * 1024 * 1024}"/>
                    </bean>
                </property>
			</bean>
		</property>
		

		<property name="cacheConfiguration">
			<list>
				<bean parent="cfg-cache-template">
					<property name="name" value="CFGCache"/>
				</bean>
                <bean parent="cfg-invalidated-cache-template">
					<property name="name" value="CFGInvalidatedPathsCache"/>
				</bean>
			</list>
		</property>
	</bean>
	

<!-- Template for CFG cache configurations -->
	<bean id="cfg-cache-template" abstract="true" class="org.apache.ignite.configuration.CacheConfiguration">
		<property name="groupName" value="CFGCacheGroup"/>
		<property name="cacheMode" value="REPLICATED"/>
		<property name="dataRegionName" value="CFGDataRegion"/>
		<property name="LoadPreviousValue" value="false"/>
		<property name="ReadFromBackup" value="false"/>
        <property name="atomicityMode" value="TRANSACTIONAL_SNAPSHOT"/>
		<property name="queryEntities">
			<list>
				<bean class="org.apache.ignite.cache.QueryEntity">		
					<property name="keyType" value="java.lang.String"/>  
					<property name="keyFieldName" value="path"/>  
					<property name="valueType" value="Algotec.Cfg.DataGridCache.EntryData.CFG_CacheData"/>		
					<property name="tableName" value="CFGCacheTable"/>
					<property name="fields">
						<map>
							<entry key="path" value="java.lang.String"/>
							<entry key="CfgValue" value="java.lang.String"/>
                            <entry key="IsValid" value="java.lang.Boolean"/>
							<entry key="IsSubTree" value="java.lang.Boolean"/>
							<entry key="lastInvalidationTime" value="java.sql.Timestamp"/>
						</map>
					</property>	
				</bean>
			</list>
		</property>
	</bean>

    <bean id="cfg-invalidated-cache-template" abstract="true" class="org.apache.ignite.configuration.CacheConfiguration">
		<property name="groupName" value="CFGCacheGroup"/>
		<property name="cacheMode" value="REPLICATED"/>
		<property name="dataRegionName" value="CFGDataRegion"/>
		<property name="atomicityMode" value="TRANSACTIONAL_SNAPSHOT"/>
		<property name="LoadPreviousValue" value="false"/>
		<property name="ReadFromBackup" value="false"/>
		
		<property name="queryEntities">
			<list>
				<bean class="org.apache.ignite.cache.QueryEntity">		
					<property name="keyType" value="java.lang.String"/>  
					<property name="keyFieldName" value="path"/>
					<property name="valueType" value="java.lang.String"/>
					<property name="tableName" value="CFGInvalidatedTable"/>	
					<property name="fields">
						<map>
							<entry key="path" value="java.lang.String"/>
						</map>
					</property>
				</bean>
			</list>
		</property>
	</bean>    


 <!-- Template for CFGConnector cache configurations -->
	<bean id="cfg-connector-cache-template" abstract="true" class="org.apache.ignite.configuration.CacheConfiguration">
		<property name="groupName" value="CFGConnectorCacheGroup"/>
		<property name="cacheMode" value="REPLICATED"/>
		<!--
			Defines this cache to run under the CFGConnectorDataRegion
		-->
		<property name="dataRegionName" value="CFGConnectorDataRegion"/>
		<property name="LoadPreviousValue" value="false"/>
		<property name="ReadFromBackup" value="false"/>
		<property name="expiryPolicyFactory">
			<bean class="javax.cache.expiry.TouchedExpiryPolicy" factory-method="factoryOf">
				<constructor-arg>
					<bean class="javax.cache.expiry.Duration">
						<constructor-arg value="MINUTES"/>
						<constructor-arg value="10"/>
					</bean>
				</constructor-arg>
			</bean>
		</property>
	</bean>
</beans>

Reply via email to