Hazlecast 5.0版本USED_HEAP_SIZE策略内存驱逐不生效问题求助
Hazelcast 5.0 USED_HEAP_SIZE内存驱逐不生效问题排查与修复
问题根因
- 单位匹配错误:
USED_HEAP_SIZE策略对应的size参数单位为字节,如果传入参数时未做单位换算(比如要限制1G内存仅传入1024),会导致阈值设置远小于预期,永远不会触发驱逐;如果设置的阈值小于单条Entry的内存占用,Hazelcast不会驱逐唯一的存活Entry,也会出现内存持续超标的情况。 - 策略匹配错误:如果实际需求是限制Entry数量,错误使用
USED_HEAP_SIZE策略也会达不到预期效果,此时应当使用PER_NODE策略。 - 内存统计未开启:当Map的内存统计开关关闭时,Eviction逻辑无法获取准确的堆内存占用数据,不会触发驱逐规则。
- 近缓存未配置驱逐:如果客户端开启了Near Cache(近缓存)且未配置驱逐规则,即使服务端Map完成驱逐,客户端近缓存的内存占用仍会持续升高,会被误判为服务端驱逐不生效。
- 清理线程调度延迟:Hazelcast默认采用周期性扫描的方式清理过期/待驱逐Entry,短时间内写入大量数据时,清理线程未及时执行会出现短时间内存超标的情况。
解决建议
- 修正参数单位:按照字节单位换算阈值大小,比如要限制200MB堆内存占用,参数传入
200 * 1024 * 1024,示例调用如下:
// 示例:配置TTL60分钟、堆内存上限200MB的Map MapConfig defaultMapConfig = initializeDefaultMapConfig(60, 200 * 1024 * 1024);
- 显式开启内存统计、修正TTL单位:原代码存在TTL单位未换算的问题,同时新增Entry统计开关确保驱逐逻辑能拿到准确内存数据,修正后的配置代码如下:
private MapConfig initializeDefaultMapConfig(int ttlMinutes,int size) { MapConfig mapConfig = new MapConfig(); EvictionConfig evictionConfig = new EvictionConfig(); evictionConfig.setEvictionPolicy(EvictionPolicy.LRU); evictionConfig.setMaxSizePolicy(MaxSizePolicy.USED_HEAP_SIZE); evictionConfig.setSize(size); mapConfig.setBackupCount(0); mapConfig.setEvictionConfig(evictionConfig); mapConfig.setTimeToLiveSeconds(ttlMinutes * 60); // 修正:分钟转秒的单位换算 mapConfig.setMaxIdleSeconds(ttlMinutes * 60); mapConfig.setPerEntryStatsEnabled(true); // 新增:开启Entry内存统计 return mapConfig; }
- 调整近缓存配置:如果使用近缓存,给近缓存也配置相同规则的Eviction策略,或者临时关闭近缓存验证内存超标是否由近缓存导致。
- 提升驱逐灵敏度:如果是短时间大量写入导致的临时超标,可调整全局配置
hazelcast.eviction.sampling.count到20~30(默认15),提升驱逐采样的准确率,减少内存波动。 - 校验Entry大小:提前计算单条Entry序列化后的内存占用,确保设置的阈值至少为单条Entry大小的3倍以上,避免单条Entry超过阈值导致无法驱逐。
内容的提问来源于stack exchange,提问作者khasim
相关产品推荐
相关产品推荐

