Ignite近缓存引发堆内存占用过高问题咨询
Ignite Near Cache配置后堆内条目堆积问题分析
问题背景
配置了最大1000条目的Near Cache后,Near Cache条目数能稳定维持在限制内,但ONHEAP统计的条目数远高于该值,甚至接近远程节点总条目数;未单独配置堆内缓存,但堆内条目持续堆积,在内存有限的测试场景中,即使设置1条目的Near Cache,大量写入也会导致JVM OOM。
原因剖析
Ignite的CachePeekMode.ONHEAP统计的是本地节点堆内存储的所有缓存条目,包含两部分:
- 本地节点作为主节点负责存储的分区数据(对应
PRIMARY统计值) - 本地Near Cache中的条目(对应
NEAR统计值)
你的测试采用PARTITIONED缓存模式,两节点无备份,因此每个节点会存储约一半的主数据(测试中99000条主数据时,堆内约51000条,正好是总主数据的一半)。而Near Cache的驱逐策略仅作用于Near Cache本身,不会影响主分区的堆内存储——主分区数据默认不会自动驱逐,这就是堆内条目持续堆积的核心原因。
OOM触发逻辑
当配置极小的Near Cache但持续写入大量数据时,本地主分区的数据会不断累积,由于未为主缓存配置任何驱逐策略,主分区数据会一直占用堆内存,最终耗尽JVM内存导致OOM。
解决方案
若要控制主分区的堆内存占用,需为主缓存单独配置驱逐策略(区别于Near Cache的驱逐策略):
private IgniteCache<Integer, String> createCache() { // Near Cache驱逐策略,控制本地近缓存条目数 LruEvictionPolicyFactory<Integer, String> nearEvictPlcFactory = new LruEvictionPolicyFactory<>(1000); NearCacheConfiguration<Integer, String> nearCfg = new NearCacheConfiguration<Integer, String>() .setNearEvictionPolicyFactory(nearEvictPlcFactory); // 主缓存堆内驱逐策略,控制本地主分区的堆内存占用 LruEvictionPolicyFactory<Integer, String> heapEvictPlcFactory = new LruEvictionPolicyFactory<>(10000); // 根据业务需求设置合理上限 CacheConfiguration<Integer, String> config = new CacheConfiguration<Integer, String>() .setName(CACHE_NAME) .setCacheMode(CacheMode.PARTITIONED) .setAtomicityMode(CacheAtomicityMode.ATOMIC) .setStatisticsEnabled(true) .setBackups(0) .setNearConfiguration(nearCfg) .setEvictionPolicyFactory(heapEvictPlcFactory); // 新增主缓存驱逐策略配置 Ignite ignite = Ignition.ignite(); return ignite.getOrCreateCache(config); }
关键统计项说明
CachePeekMode.PRIMARY:统计本地节点作为主节点存储的条目数量CachePeekMode.NEAR:统计本地Near Cache中的条目数量CachePeekMode.ONHEAP:统计本地节点堆内所有缓存条目(主分区数据 + Near Cache数据)
你的测试输出完全符合这个逻辑:99000条主数据时,本地主节点存储约51000条(总主数据的一半),加上1000条Near Cache条目,总和与ONHEAP统计值一致。
内容的提问来源于stack exchange,提问作者colin
相关产品推荐
相关产品推荐

