Apache Ignite REPLICATED SYNC模式下IgniteCache创建后未填充数据问题
Apache Ignite 复制缓存重平衡后数据迭代问题解决方案
核心原因
你遇到的问题本质是:CACHE_STARTED事件触发时机早于重平衡完成,而iterator()默认只遍历本地已加载的数据,get(key)则会主动从集群拉取缺失数据,导致两者表现不一致。即便配置了SYNC重平衡模式,缓存启动事件也不会等待重平衡彻底完成才触发。
解决方法
1. 监听CACHE_REBALANCE_FINISHED事件
放弃监听CACHE_STARTED,改用EVT_CACHE_REBALANCE_FINISHED事件,这个事件会在重平衡完全结束后触发,是执行后续逻辑的准确时机:
ignite.events().localListen(evt -> { CacheRebalanceFinishedEvent rebalEvt = (CacheRebalanceFinishedEvent) evt; if ("你的缓存名称".equals(rebalEvt.cacheName())) { // 缓存数据已全量同步到本地,执行你的业务逻辑 try (IgniteCache<String, Object> cache = ignite.cache("你的缓存名称")) { cache.forEach((k, v) -> { // 处理键值对 }); } } return true; // 保持监听状态 }, EventType.EVT_CACHE_REBALANCE_FINISHED);
2. 强制全量加载缓存数据
如果事件监听方式不符合你的业务场景,可以直接调用loadCache()方法阻塞等待全量数据加载完成:
IgniteCache<String, Object> cache = ignite.cache("你的缓存名称"); // 传入null表示加载所有数据,方法会阻塞直到加载完成 cache.loadCache(null); // 此时本地已拥有全量数据,可安全迭代 cache.forEach((k, v) -> { // 处理逻辑 });
3. 验证重平衡配置正确性
确保你的缓存配置确实生效,检查以下参数:
CacheConfiguration<String, Object> cacheCfg = new CacheConfiguration<>("你的缓存名称"); cacheCfg.setCacheMode(CacheMode.REPLICATED); cacheCfg.setRebalanceMode(CacheRebalanceMode.SYNC); // 可选:调整重平衡批次大小,加快同步速度 cacheCfg.setRebalanceBatchSize(1024);
同时可以开启Ignite重平衡模块的DEBUG日志,查看重平衡是否正常完成:
<logger name="org.apache.ignite.internal.processors.cache.distributed.rebalancing" level="DEBUG"/>
补充说明
get(key)能获取数据是因为Ignite的读操作会自动从集群其他节点拉取缺失数据到本地;iterator()默认仅遍历本地节点已持久化/加载的数据,不会主动触发跨节点拉取,所以重平衡未完成时无结果。
内容的提问来源于stack exchange,提问作者PentaKon
相关产品推荐
相关产品推荐

