【发布时间】:2020-06-10 17:42:46
【问题描述】:
我的项目中有一个要求,将 900 万个数据从 oracle 数据库缓存到 Hazelcast。但显然 Hazelcast 消耗的堆空间比它应该消耗的要多。我已经为应用程序分配了 8bg 堆空间,但仍然出现内存不足错误。
下面是我的数据加载器类。
public class CustomerProfileLoader implements ApplicationContextAware, MapLoader<Long, CustomerProfile> {
private static CustomerProfileRepository customerProfileRepository;
@Override
public CustomerProfile load(Long key) {
log.info("load({})", key);
return customerProfileRepository.findById(key).get();
}
@Override
public Map<Long, CustomerProfile> loadAll(Collection<Long> keys) {
log.info("load all in loader executed");
Map<Long, CustomerProfile> result = new HashMap<>();
for (Long key : keys) {
CustomerProfile customerProfile = this.load(key);
if (customerProfile != null) {
result.put(key, customerProfile);
}
}
return result;
}
@Override
public Iterable<Long> loadAllKeys() {
log.info("Find all keys in loader executed");
return customerProfileRepository.findAllId();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
customerProfileRepository = applicationContext.getBean(CustomerProfileRepository.class);
}
}
以下是存储库查询。如果我更改以下查询,使其限制为 200 万条数据,那么一切正常。
@Query("SELECT b.id FROM CustomerProfile b ")
Iterable<Long> findAllId();
下面是我在hazelcast.xml 文件中的地图配置。在这里,我将backup count 设为zero,在它为 1 之前,但这并没有什么区别。
<?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)
其他要点:
- 我现在只运行一个 hazelcast 服务器实例,其中
分配的堆空间为 8GB
JAVA_OPTS=-Xmx8192m。在它是 4GB 之前 但是当我得到堆空间错误时,我增加到 8GB,但没有运气。 - 暂时在地图被访问时执行 maploader 第一次。
- 特定表 (customer_profile) 中有 6 列 它没有任何二进制类型。它只有基本的价值观,比如 firstname lastname 之类的。
- 使用的 hazelcast 版本是 3.8
我现在面临的问题是:
当它获取所有数据并将其加载到映射时,我收到堆空间错误(java.lang.OutOfMemoryError: Java heap space)。现在表中有 900 万条数据。
加载数据也需要很多时间,也许我可以通过运行多个 hazelcast 服务器实例来解决这个问题。
我是 hazelcast 的新手,所以任何帮助将不胜感激:)
【问题讨论】:
-
该表中一行的平均大小是多少?
-
@StephenC 大约 100 个字节
-
100 字节代表什么?
-
@StephenC 。你的意思是列的数据类型?
-
@StephenC 我在问题中也添加了数据库表结构。