Apache Ignite中可能存在内存泄漏



我正在尝试使用Ignite作为内存中的键值对数据库,其值范围从50MB到800MB。看起来Ignite通过JVM分配堆空间,但它从未清理过,即使缓存项已脱离堆,已清除,没有连接的客户端,也没有运行的操作。我的机器将无法处理这样的内存消耗,因此我正在寻找一种清理内存的方法。

我的测试场景如下:

  • Ignite版本2.9
  • 使用OpenJDK 11运行

我正在使用pyignite瘦客户端通过python脚本本地测试Ignite:

client = Client()
client.connect('localhost', 10800)
my_cache = client.get_or_create_cache('default')
my_cache.clear()
data = createData() #creates 800 000 000 bytes test data
def put(caches):
i = caches
while i > 0:
my_cache.put('my key' + str(i), data)
i -= 1
put(5)
my_cache.remove_all()
my_cache.destroy()
client.close()

该脚本将800MB的数据顺序写入5个不同的缓存条目中。以下快照说明了Ignite的堆是如何增长到其峰值的,这本身是可以理解的,但之后即使在执行GC:后仍保持在10GB左右

点燃堆

使用相同的数据执行第二次测试运行不会导致GC之后更大的堆消耗,这让我相信Ignite在内部为传入数据分配缓冲区,这与数据的大小相对应。这种内存消耗太大了,从长远来看,我的机器将无法处理它。

点火配置非常简单:

<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="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">

<!-- Durable memory configuration. -->
<property name="dataStorageConfiguration">
<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
<property name="dataRegionConfigurations">
<list>
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<!-- Custom region name. -->
<property name="name" value="10GB_Region"/>
<!-- 100 MB initial size. -->
<property name="initialSize" value="#{100L * 1024 * 1024}"/>
<!-- 10GB maximum size. -->
<property name="maxSize" value="#{10096L * 1024 * 1024}"/>
</bean>

</list>
</property>
<!-- Redefining the default region's settings -->
<property name="defaultDataRegionConfiguration">
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="name" value="Default_Region"/>
<property name="maxSize" value="#{5L * 1024 * 1024 * 1024}"/>
</bean>
</property>
</bean>
</property>

<property name="cacheConfiguration">
<list>
<!-- Partitioned cache example configuration (Atomic mode). -->
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="default"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="backups" value="1"/>
<property name="dataRegionName" value="10GB_Region"/>
</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>
</bean>
</beans>
  • ignite visor特别指出缓存是堆外的
  • VisualVM直方图显示98%的活动字节映射到byte[]
  • 似乎有一些客户端连接器和数据流条带线程保持打开状态,缓存中每个put操作一个,但我不确定它们需要多少堆
  • 在my_cache.put中提供值提示没有帮助
  • cache.clear((、cache.dedestroy((没有帮助(也不应该有帮助,因为缓存是堆外的(

如有任何帮助,我们将不胜感激!

  1. Apache Ignite默认情况下不在堆中保存数据,而是在堆外保存数据
  2. Apahce Ignite在删除数据时确实不会释放堆外数据,但在吸收新数据时,它将允许重用所述堆外数据
  3. 目前还不清楚为什么您的工具会报告使用~16G堆,因为Ignite在提供的配置中不应该使用超过几百MB的堆。如果这不仅仅是堆,而是所有的RAM,那么你就可以了。您应该期望分配10G。为什么它在"大小"字段中报告更多尚不清楚

我对长时间的延迟向任何感兴趣的人道歉,但在联系Ignite邮件列表后,我确实得到了问题的答案。显然,Ignite从未打算在一个查询中消耗如此大量的数据。所描述的行为是预期的,并且必须将数据划分为包,并将其发送到其他节点或将其放入持久性中。建议的解决方案是将数据分块成更小的比特。由于目前在我的情况下这是不可能的,我放弃了Ignite,并寻找其他方法来存储我的数据。

最新更新