You need to enable JavaScript to run this app. Apache Ignite 2.9开启on-heap缓存后仍观测到off-heap指标的问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

Apache Ignite 2.9开启on-heap缓存后仍观测到off-heap指标的问题咨询

Apache Ignite 2.9 开启On-Heap缓存后的Off-Heap行为说明

1. 开启On-Heap缓存后,是否应完全依托堆内内存承载数据,为何仍能观测到Off-Heap指标

很多人会对这个配置存在认知偏差:以为开了on-heap缓存,所有缓存数据就会全部放到JVM堆里,Off-Heap就完全不参与缓存存储了。
实际上CacheConfiguration.setOnheapCacheEnabled(true)的设计逻辑,是在原来的Off-Heap基础存储之上,叠一层热门数据的快速访问副本——根本不是要把基础存储从堆外挪到堆内。它的初衷是让频繁访问的Key不用每次都走堆外寻址、序列化/反序列化流程,直接拿堆内的对象引用就能访问,从而降低这部分的性能开销。
也就是说,Off-Heap从一开始就是这套架构里的基础存储层,哪怕开了on-heap缓存,Off-Heap的分配、回收、占用这些指标本来就会持续被采集,出现这些指标是完全正常的设计表现,完全不存在“开了on-heap就不该有Off-Heap指标”的预期。

2. 当前配置架构下,会被自动存储到Off-Heap的常见数据类型

在关闭Native Persistence、仅开启on-heap缓存的配置下,以下几类数据会被自动存放在Off-Heap区域,永远不会进入堆内缓存:

  • 所有缓存条目的基础原始数据:不管有没有把这个条目加载到on-heap当副本,写入操作的第一落点永远是配置的默认Off-Heap数据区域。on-heap只是存副本,根本不承担基础存储的职责,这部分数据是Off-Heap的核心占用来源。
  • 大小超过on-heap单条目阈值的缓存条目:Ignite 2.9默认会跳过单条大小超过IgniteConfiguration.getOnheapCacheMaxPayloadSize()(默认值16KB)的条目,哪怕这个条目被访问得再频繁,也只会存在Off-Heap,不会被加载到堆内。
  • Ignite内置的系统组件数据:比如集群元数据、分布式锁信息、计算任务上下文、SQL执行引擎的临时计算上下文、分布式操作的序列化交换块这些系统级数据,从设计上就不纳入on-heap缓存的范围,全部存在Off-Heap。
  • 访问频次很低的冷数据:所有没达到on-heap加载判定条件的冷数据,会一直停留在Off-Heap的基础存储里,不会被挪到堆内。

3. 两层内存的驱逐协同流程(Off-Heap层策略random2Lru,On-Heap层策略LRU)

很多人会以为两层内存是“堆内存满了就把数据挪到堆外,堆外满了再驱逐”的串联流程,实际上不是——两层的驱逐是独立判定、靠一致性事件做同步的,根本不会发生跨层的数据转移,具体流程是这样的:

  1. 容量阈值完全独立判定:Off-Heap层的满触发条件,是看默认数据区域配置的DataRegionConfiguration.setMaxSize()阈值;on-heap层的满触发条件,是看IgniteConfiguration.setOnheapCacheMaxMemorySize()配置的堆内缓存专属内存阈值。两个区域的占用计算、满的判定完全分开,不会把两层的内存加起来算总占用去触发驱逐。
  2. 写入操作永远先走Off-Heap:所有新写的缓存条目,首先会落到Off-Heap的基础存储里。如果写入的时候发现Off-Heap已经到了容量阈值,就先按照random2Lru的策略淘汰一批旧的Off-Heap条目,腾够空间了再把新数据写进去。
  3. 读取操作按需加载On-Heap副本:当某个条目被访问时,系统会判断它是不是符合on-heap的加载条件(没超过单条目大小限制、不在失效名单里),符合的话就把这个条目反序列化之后放到on-heap层当副本,这个过程不会改动Off-Heap里的原始数据。
  4. On-Heap层的驱逐完全独立:当on-heap层的占用到了自己的容量阈值,就按LRU的策略把最近最少访问的堆内副本删掉。这个操作只是清堆里的副本,跟Off-Heap里的原始数据没有任何关系——被删掉的堆内副本如果之后又被访问到,会重新从Off-Heap加载回堆里。
  5. 靠一致性事件做跨层同步:如果Off-Heap层按照random2Lru策略把某个原始条目淘汰了,系统会马上发一致性通知,把所有节点上on-heap层存的这个条目的副本全部删掉。之后再访问这个Key的时候,会直接判定数据不存在,不会继续用已经失效的堆内副本。

核心提醒:On-Heap层本质是Off-Heap之上的只读加速副本,根本没有独立的持久数据,所以不存在“on-heap驱逐的时候把数据挪到Off-Heap”的流程,两层的驱逐只是做状态同步,不发生实际的数据位置迁移。


内容的提问来源于stack exchange,提问作者Mudit bhaintwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 14:45:02