我正试图将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()
该脚本将800 MB的数据依次写入5个不同的缓存条目。以下快照展示了Ignite堆的增长到达峰值,这一点本身是可理解的,但之后即使在执行垃圾回收后,它仍然保持在约10GB左右:
再次运行相同数据的第二次测试不会导致更大的堆内存消耗,在执行垃圾回收后,这让我相信Ignite在内部为传入的数据分配了对应大小的缓冲区。这种内存消耗太大了,我的机器无法长期处理。
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 特别指出缓存是 off-heap 的
- VisualVM 直方图显示,98% 的实时字节映射到 byte[]
- 好像有 client-connector 和 data-streamer-stripe 线程仍然保持打开状态,每个在缓存中进行 put 操作的线程一个,但我不确定它们需要多少堆内存
- 在 my_cache.put 中提供值提示没有帮助
- cache.clear(),cache.destroy() 没有帮助(而且也不应该,因为缓存是 off-heap)
任何帮助将非常感激!