Java Apache Ignite IGFS不使用非堆空间
我使用的是ApacheIgnite2.6。我使用的是Ignite文件系统,当我一次又一次地将一个大约25 MB的特定文件写入IGFS时,数据不会保存到非堆空间中。取而代之的是,它进入垃圾收集的堆中,速度相对较慢。如何让IGFS将文件保存到分配给它的大堆空间中 高级体系结构—我现在有一个运行在tomcat内部的客户机ignite节点,还有一个服务器ignite节点,我打算在其中存储数据。一旦我按预期工作,就可以进行缩放,但由于前面提到的问题,缩放速度非常慢。当堆空间很快用完时,它也会OOM。问题是,我希望它使用我分配的30G非堆空间 我打算将其作为内存缓存。我正在为JVM分配2G堆空间和30G非堆空间。非堆空间永远不会被使用,因此会耗尽内存。我已经确认,没有使用JMX控制台内存选项卡使用非堆空间。非堆空间保持在100M以下,而堆空间迅速膨胀到2G,然后JVM崩溃 详细信息:首先,我的ignite配置spring xml:Java Apache Ignite IGFS不使用非堆空间,java,performance,ignite,Java,Performance,Ignite,我使用的是ApacheIgnite2.6。我使用的是Ignite文件系统,当我一次又一次地将一个大约25 MB的特定文件写入IGFS时,数据不会保存到非堆空间中。取而代之的是,它进入垃圾收集的堆中,速度相对较慢。如何让IGFS将文件保存到分配给它的大堆空间中 高级体系结构—我现在有一个运行在tomcat内部的客户机ignite节点,还有一个服务器ignite节点,我打算在其中存储数据。一旦我按预期工作,就可以进行缩放,但由于前面提到的问题,缩放速度非常慢。当堆空间很快用完时,它也会OOM。问题是
<?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
}
}