如何解决Ignite性能问题?

时间:2020-09-17 09:16:12

标签: java ignite

我们在服务器和客户端模式下都使用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

问题是我们做错了什么?我们可以调整什么?也许是我们代码中的问题,但是如何确定它在哪里?

1 个答案:

答案 0 :(得分:2)

2000个缓存很多。一个缓存可能占用多达40M的数据结构。

对于所有用途和组成相似的缓存,我建议至少使用相同的cacheGroup,以共享其中一些数据结构。