Java Apache Ignite IGFS不使用非堆空间

Java Apache Ignite IGFS不使用非堆空间,java,performance,ignite,Java,Performance,Ignite,我使用的是ApacheIgnite2.6。我使用的是Ignite文件系统,当我一次又一次地将一个大约25 MB的特定文件写入IGFS时,数据不会保存到非堆空间中。取而代之的是,它进入垃圾收集的堆中,速度相对较慢。如何让IGFS将文件保存到分配给它的大堆空间中 高级体系结构—我现在有一个运行在tomcat内部的客户机ignite节点,还有一个服务器ignite节点,我打算在其中存储数据。一旦我按预期工作,就可以进行缩放,但由于前面提到的问题,缩放速度非常慢。当堆空间很快用完时,它也会OOM。问题是

我使用的是ApacheIgnite2.6。我使用的是Ignite文件系统,当我一次又一次地将一个大约25 MB的特定文件写入IGFS时,数据不会保存到非堆空间中。取而代之的是,它进入垃圾收集的堆中,速度相对较慢。如何让IGFS将文件保存到分配给它的大堆空间中

高级体系结构—我现在有一个运行在tomcat内部的客户机ignite节点,还有一个服务器ignite节点,我打算在其中存储数据。一旦我按预期工作,就可以进行缩放,但由于前面提到的问题,缩放速度非常慢。当堆空间很快用完时,它也会OOM。问题是,我希望它使用我分配的30G非堆空间

我打算将其作为内存缓存。我正在为JVM分配2G堆空间和30G非堆空间。非堆空间永远不会被使用,因此会耗尽内存。我已经确认,没有使用JMX控制台内存选项卡使用非堆空间。非堆空间保持在100M以下,而堆空间迅速膨胀到2G,然后JVM崩溃

详细信息:首先,我的ignite配置spring xml:

 <?xml version="1.0" encoding="UTF-8"?>
 <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="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK"/>
    <property name="searchSystemEnvironment" value="true"/>
</bean>
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
    <property name="marshaller">
        <bean class="org.apache.ignite.internal.binary.BinaryMarshaller" />
    </property>

    <property name="fileSystemConfiguration">
        <list>
            <bean class="org.apache.ignite.configuration.FileSystemConfiguration">
                <property name="name" value="igfs"/>
                <property name="blockSize" value="#{128 * 1024}"/>
                <property name="perNodeBatchSize" value="512"/>
                <property name="perNodeParallelBatchCount" value="16"/>
                <property name="prefetchBlocks" value="32"/>
            </bean>
        </list>
    </property>

    <property name="discoverySpi">
        <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
            <property name="ipFinder">
                <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                    <property name="addresses">
                        <list>
                            <value>127.0.0.1:47500..47509</value>
                        </list>
                    </property>
                </bean>
            </property>
        </bean>
    </property>
    <property name="dataStorageConfiguration">
        <bean class="org.apache.ignite.configuration.DataStorageConfiguration" >
            <!-- if I don't set this, the system region runs out of memory almost immediately -->
            <property name="systemRegionMaxSize" value="#{6L * 1024 * 1024 * 1024"} />
            <property name="systemRegionInitialSize" value="#{6L * 1024 * 1024 * 1024"} />
        </bean>

    </property>
</bean>
这是创建我的客户机igfs对象的代码,通过它我可以保存要点燃的文件。他们倾向于偏大

public void init() throws Exception{
    igniteInstanceName = "client-name=" + hostInfo.getLocalHost();
    Ignition.setClientMode(true); 
    // reading in the same config file as the server uses to start up above.  The big difference is the clientMode set to true here. 
    try(InputStream configFileInputStream = new FileInputStream(ResourceUtils.getFile("ignite-media-server.xml"));){
         ignite = IgnitionEx.start(configFileInputStream, igniteInstanceName, null, null);
         igfs = ignite.fileSystem("igfs");

    }
    catch(Throwable t){ /* do log */}

}
以下是一种保存方法,用于将我的文件保存到ignite:

public saveStream(String cachePath, AudioInputStream toCache){
   OutputStream os = null;
   try{
       IgfsPath cacheFile = new IgfsPath(cachePath);
       os = igfs.create(cacheFile, true);
       AudioSystem.write(toCache.getDataStream, AudioFileFormat.TYPE.WAVE, os);
   }
   finally{
      // close streams
   }
}
为什么我的数据不能保存到快速的堆外空间?我错过了什么?我的server.config几乎直接来自igfs提供的示例

在其他混乱情况下,当我使用ignitevisor.cmd检查服务器节点上的内存使用情况时,在一个不会使其崩溃的较短测试之前和之后,我看到以下内容:

查看ignitevisor.cmd中ignite为空时的内存分配。请注意,我的igfs区域显示:

堆内存已初始化:2g 使用的堆内存:56mb 非堆内存已初始化:2mb 使用的非堆内存:49 mb 非堆内存最大值:744mb 在IGFS中创建价值仅为2G的文件,因为从痛苦的经历来看,我知道它很快就会爆炸。使用ignitevisor.cmd查看节点的内存分配。这就是喵喵2分钟前

堆内存已初始化:2gb 使用的堆内存:1gb 使用的非堆内存为64 MB 非堆内存最大值:744mb 为什么非堆中几乎什么都没有?为什么ignitevisor认为非堆最大值是744MB,而它应该是30GB


在其他方面,如果我将堆大小增加到6GB,它的运行时间会更长,但服务器仍然会崩溃,并出现OutOfMemoryError:Java堆空间。有趣的是,即使启用了磁盘持久性,我也可以重现这种情况。检查堆转储文件会发现许多ConcurrentLinkedHashMap条目。条目本身是org.apache.ignite.internal.GridTopic对象。每一个都有一个uuid,大多数都是TOPIC_DATASTREAM类型

数据可以保存到堆外,但您应该注意,IGFS操作中涉及的许多瞬态对象仍然会短暂地保存在堆上,然后进行GCed

JMX控制台内存选项卡非堆空间是错误的度量。我不认为有任何JVM度量用于堆外。但是,Ignite将定期打印堆统计信息


内存不足的原因并不明显。您是否尝试过收集堆转储并对其进行分析?

让我更详细地概述一下测试。1.分配2克堆,30克非堆。不要启用持久性。2.查看ignitevisor.cmd中ignite为空时的内存分配。查看我的igfs区域显示:堆内存已初始化:2g/堆内存已使用:56mb非堆内存已初始化:2mb/非堆内存已使用:49 mb/非堆内存最大值:744mb 2。在IGFS中创建价值仅为2G的文件,因为从痛苦的经历来看,我知道它很快就会爆炸。3.使用ignitevisor.cmd查看节点的内存分配。这就是…测试之后,ignitevisor说:堆内存已初始化:2gb/堆内存已使用:1gb/非堆内存已使用64 MB为什么非堆内存中仍然几乎没有任何内存?为什么ignitevisor认为非堆最大值是744MB,而它应该是30GB呢?我将此注释添加到主记录单的底部,因为以注释格式读取此文本太难了。你在那里读会更容易些。谢谢你和我讨论!正如我已经说过的,你们应该忽略非堆度量,因为它们度量的是完全不同的东西。我应该看什么指标来判断内存分配中发生了什么?每两秒钟生成一次ignite日志,其内容与ignitevisor.cmd大致相同。
public saveStream(String cachePath, AudioInputStream toCache){
   OutputStream os = null;
   try{
       IgfsPath cacheFile = new IgfsPath(cachePath);
       os = igfs.create(cacheFile, true);
       AudioSystem.write(toCache.getDataStream, AudioFileFormat.TYPE.WAVE, os);
   }
   finally{
      // close streams
   }
}