gpt4 book ai didi

java - Apache Ignite IGFS 不使用非堆空间

转载 作者:行者123 更新时间:2023-12-02 10:02:21 25 4
gpt4 key购买 nike

我正在使用 Apache Ignite 2.6。我正在使用Ignite Filesystem,当我一遍又一遍地将大约25 MB的特定文件写入IGFS时,数据不会保存到非堆空间中。相反,它会进入堆,受到垃圾收集的影响,并且速度相对较慢。如何让 IGFS 将文件保存到我为其分配的大堆空间中?

高级架构——我现在有一个在 tomcat 内部运行的客户端 ignite 节点和一个服务器 ignite 节点,我打算在其上存储这些数据。一旦我按预期工作,就可以进行扩展——但由于上述问题,速度非常慢。当堆空间很快耗尽时,它也会出现 OOM。问题是,我希望它使用我分配的 30G 非堆空间!

我打算将其作为内存缓存。我为 JVM 分配了 2 G 的堆空间和 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>

这是我用来启动 ignite 服务器进程的脚本。它是一个在具有 64 G RAM 和 40 G 磁盘空间的 Linux 机器上运行的 shell 脚本。

IGNITE_HOME=/data/apache-ignite
export IGNITE_HOME
IGNITE_JMX_PORT=1234
export IGNITE_JMX_PORT
$IGNITE_HOME/bin/ignite.sh $IGNITE_HOME/ignite-media-server.xml -J-Xmx2G -J-Xms2G -J-XX::+HeapDumpOnOutOfMemoryError -J-XX:HeapDumpPath=$IGNITE_HOME -J-XX:+PrintGC -J-XX:+PrintGCTimeStamps -J-XX:+PrintGCDateStamps -J-Xloggc:$IGNITE_HOME/gc.log-$(date +%m%d-%H%M%S) -J-XX:+UseG1GC -J-XX:DisableExplicitGC -J-XX:MaxDirectMemorySize=30G

这是创建我的客户端 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 */}

}

这是一个保存方法,可以保存我的文件以供点燃:

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 大小的文件——距离 OOM 还差一点,因为从痛苦的经验来看,我知道它很快就会崩溃。使用ignitevisor.cmd查看节点的内存分配情况。这就是...... – MeowCode 2 分钟前

  • 已初始化堆内存:2GB
  • 使用的堆内存:1GB
  • 使用的非堆内存 64 MB
  • 非堆内存最大值:744mb

为什么非堆中仍然几乎没有任何东西?为什么 ignitevisor 认为非堆最大值是 744 MB,而它应该是 30 GB?

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

最佳答案

数据会保存到堆外,但是您应该注意,IGFS 操作中涉及的许多 transient 对象仍会短暂保留在堆上(之后会被 GC)。

“JMX 控制台内存选项卡 - 非堆空间”是错误的指标。我认为没有任何关于堆外的 JVM 指标。但是,Ignite 将定期打印堆外统计信息。

为什么你会耗尽内存并不明显。您是否尝试过收集堆转储并分析它?

关于java - Apache Ignite IGFS 不使用非堆空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55536778/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com