在我的项目中,我需要将900万个数据从oracle数据库缓存到Hazelcast。但显然Hazelcast消耗的堆空间比预期的要多。我已为该应用程序分配了8bg堆空间,但仍然出现内存不足错误。
下面是我的数据加载器类。
@Query("SELECT b.id FROM CustomerProfile b ")
Iterable<Long> findAllId();
下面是存储库查询。如果我更改以下查询,使其限制为只能说200万个数据,则一切正常。
hazelcast.xml
以下是我在backup count
文件中的地图配置。在这里,我以zero
的形式将<?xml version="1.0" encoding="UTF-8"?>
<hazelcast
xsi:schemaLocation="http://www.hazelcast.com/schema/config
http://www.hazelcast.com/schema/config/hazelcast-config-3.11.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- Use port 5701 and upwards on this machine one for cluster members -->
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="false"/>
<tcp-ip enabled="true">
<interface>127.0.0.1</interface>
</tcp-ip>
</join>
</network>
<map name="com.sample.hazelcast.domain.CustomerProfile">
<indexes>
<!-- custom attribute without an extraction parameter -->
<index ordered="false">postalCode</index>
</indexes>
<backup-count>0</backup-count>
<map-store enabled="true" initial-mode="EAGER">
<class-name>com.sample.hazelcast.CustomerProfileLoader</class-name>
</map-store>
</map>
</hazelcast>
设为ID NOT NULL NUMBER(19)
LOGIN_ID NOT NULL VARCHAR2(32 CHAR)
FIRSTNAME VARCHAR2(50 CHAR)
LASTNAME VARCHAR2(50 CHAR)
ADDRESS_LINE1 VARCHAR2(50 CHAR)
ADDRESS_LINE2 VARCHAR2(50 CHAR)
CITY VARCHAR2(30 CHAR)
postal_code VARCHAR2(20 CHAR)
COUNTRY VARCHAR2(30 CHAR)
CREATION_DATE NOT NULL DATE
UPDATED_DATE NOT NULL DATE
REGISTER_NUM NOT NULL VARCHAR2(10 CHAR)
,但这没什么区别。
JAVA_OPTS=-Xmx8192m
数据库表结构:
// constrain to a discrete range
var calendar = new Calendar(calendarEl, {
defaultView: 'dayGridMonth',
validRange: {
start: '2017-05-01',
end: '2017-06-01'
}
});
// constrain to an open-ended range
var calendar = new Calendar(calendarEl, {
defaultView: 'dayGridMonth',
validRange: {
start: '2017-05-01'
}
});
其他要点:
我现在面临的问题是:
获取所有数据并将其加载到映射时,出现堆空间错误( java.lang.OutOfMemoryError:Java堆空间)。现在表格中有900万个数据。
加载数据也要花费大量时间,也许我可以通过运行多个hazelcast服务器实例来解决此问题。
我是hazelcast中的新手,因此,我们将不胜感激:)
答案 0 :(得分:6)
在我看来,真正的问题是8GB堆中的数据太多了。
您说您平均每行有100个字节的数据表示为字符串数据。
以下是将9,000,000行数据表示为HashMap
所需空间的一些估计值 1 。假设有9个字符串,2个日期和一个int
。
Date
是32字节x 2-> 64字节Integer
)将是24个字节。您可以做到的是,实际数据超过8GB。然后考虑一下Java堆需要大量工作空间这一事实。至少说30%。
获得OOME并不奇怪。我的猜测是您的堆需要大50%...并且假设您估计的每行100字节是准确的。
这完全基于您的loadAll
方法,该方法似乎正在将数据库中的所有行作为常规的HashMap
来实现。它并没有考虑到Hazelcast用于缓存的堆空间或其他内存。
虽然您可以扩展堆,但是我认为更改代码以使其不会实现这样的行更有意义。目前尚不清楚这是否有意义。这将取决于地图的使用方式。
1-我假设您使用的是Java 8。