我们在服务器和客户端模式下都使用Ignite 2.7.6:两个服务器和六个客户端。
首先,每个内部带有客户端Ignite的应用程序节点都具有2G堆。每个Ignite服务器节点都有24G堆和2G堆。
在上一次应用程序更新中,我们引入了新功能,该功能需要20个整体(用户组)的2000个缓存。高速缓存条目的内部很小,最大为10个整数。
这些缓存是通过ignite.getOrCreateCache(name)
方法创建的,因此它们具有默认的缓存配置(堆外,分区)。
但是在更新后的一个小时内,我们在服务器节点上收到OOM错误:
[00:59:55,628][SEVERE][sys-#44759][GridDhtPartitionsExchangeFuture] Failed to notify listener: o.a.i.i.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$2@3287dcbd
java.lang.OutOfMemoryError: Java heap space
Ignite服务器节点上的堆现在增加到16G,而应用程序节点上的堆增加到12G。
我们可以看到,所有服务器节点现在的CPU负载都很高,大约为250%(更新前为20%),而较长的G1 Young Gen会暂停最多5毫秒(更新前为300微秒)。
服务器配置为:
<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="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="workDirectory" value="/opt/qwerty/ignite/data"/>
<property name="gridLogger">
<bean class="org.apache.ignite.logger.log4j2.Log4J2Logger">
<constructor-arg type="java.lang.String" value="config/ignite-log4j2.xml"/>
</bean>
</property>
<property name="dataStorageConfiguration">
<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
<property name="defaultDataRegionConfiguration">
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="maxSize" value="#{24L * 1024 * 1024 * 1024}"/>
<property name="pageEvictionMode" value="RANDOM_LRU"/>
</bean>
</property>
</bean>
</property>
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="localAddress" value="host-1.qwerty.srv"/>
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
<property name="addresses">
<list>
<value>host-1.qwerty.srv:47500</value>
<value>host-2.qwerty.srv:47500</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
<property name="communicationSpi">
<bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
<property name="localAddress" value="host-1.qwerty.srv"/>
</bean>
</property>
</bean>
</beans>
在Ignite服务器节点的内存转储中,我们看到大量org.apache.ignite.internal.marshaller.optimized.OptimizedObjectStreamRegistry$StreamHolder
的21Mb
内存泄漏报告显示:
Problem Suspect 1
One instance of "org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager" loaded by "jdk.internal.loader.ClassLoaders$AppClassLoader @ 0x400000100" occupies 529 414 776 (10,39 %) bytes. The memory is accumulated in one instance of "java.util.LinkedList" loaded by "<system class loader>".
Keywords
jdk.internal.loader.ClassLoaders$AppClassLoader @ 0x400000100
java.util.LinkedList
org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager
Problem Suspect 2
384 instances of "org.apache.ignite.thread.IgniteThread", loaded by "jdk.internal.loader.ClassLoaders$AppClassLoader @ 0x400000100" occupy 3 023 380 000 (59,34 %) bytes.
Keywords
org.apache.ignite.thread.IgniteThread
jdk.internal.loader.ClassLoaders$AppClassLoader @ 0x400000100
Problem Suspect 3
1 023 instances of "org.apache.ignite.internal.processors.cache.CacheGroupContext", loaded by "jdk.internal.loader.ClassLoaders$AppClassLoader @ 0x400000100" occupy 905 077 824 (17,76 %) bytes.
Keywords
jdk.internal.loader.ClassLoaders$AppClassLoader @ 0x400000100
org.apache.ignite.internal.processors.cache.CacheGroupContext
问题是我们做错了什么?我们可以调整什么?也许是我们代码中的问题,但是如何确定它在哪里?
答案 0 :(得分:2)
2000个缓存很多。一个缓存可能占用多达40M的数据结构。
对于所有用途和组成相似的缓存,我建议至少使用相同的cacheGroup
,以共享其中一些数据结构。