Apache Ignite非基线节点SQL查询返回空结果问题咨询
Apache Ignite非基线节点查询REPLICATED缓存返回空结果问题
环境信息
- Ignite版本:2.10、2.13、2.14
- JDK:Azul/OpenJDK 11
- 操作系统:RHEL 8/Rocky Linux 8.7
- 集群规模:3节点,开启持久化
缓存配置
集群中存在由厂商产品创建的RELATIONAL_META表,底层为REPLICATED模式缓存,配置信息如下:
[cacheName=SQL_PUBLIC_RELATIONAL_META, cacheId=-252123144, grpName=null, grpId=-252123144, prim=512, mapped=512, mode=REPLICATED, atomicity=ATOMIC, backups=2147483647, affCls=RendezvousAffinityFunction]
观测现象
模拟节点磁盘故障后清空磁盘重启,节点正常加入拓扑但未进入基线(自动调整未完成或关闭自动调整)时:
- 通过JDBC连接该非基线节点查询
RELATIONAL_META,返回空结果但能识别表结构 - 连接其他基线节点查询该表,正常返回12条数据
预期行为
非基线节点应从集群其他节点同步获取自身缺失的分区数据,而非返回空结果,当前行为导致应用连接不同节点时出现数据不一致。
测试补充
- 开启基线自动调整时,节点完成基线加入前仍会返回空结果
- 仅REPLICATED模式缓存存在此问题,PARTITIONED模式缓存无异常
- 仅开启持久化时可复现该问题,关闭持久化无法将节点留在基线外
问题解答
是否为设计预期?
这是Ignite的设计预期行为,核心逻辑如下:
- 开启持久化后,非基线节点处于「非活跃」状态,Ignite默认不会将这类节点纳入REPLICATED缓存的数据同步范围——REPLICATED缓存的全量数据只会同步到基线拓扑内的节点,非基线节点被视为临时节点,不会主动触发数据拉取。
- PARTITIONED缓存无此问题,是因为其查询会自动路由到持有对应分区的基线节点;而REPLICATED缓存默认优先本地读取,非基线节点本地无数据且不会主动同步,因此返回空结果。
规避方案
- 加速节点进入基线
- 开启基线自动调整并缩短延迟:设置
IGNITE_BASELINE_AUTO_ADJUST_ENABLED=true,同时调小IGNITE_BASELINE_AUTO_ADJUST_DELAY(默认10分钟),让节点重启后尽快加入基线触发数据同步。 - 手动基线调整:节点重启完成后,立即执行
ALTER BASELINE ADD NODES [节点ID]命令将其纳入基线。
- 开启基线自动调整并缩短延迟:设置
- 强制查询路由到基线节点
- SQL查询添加hint:
SELECT /*+ ROUTE_TO_NODES('baseline') */ * FROM RELATIONAL_META,强制查询发送到基线节点执行。 - JDBC连接配置:添加
ignite.jdbc.route.baseline.only=true参数,让该连接的所有查询都路由到基线节点。
- SQL查询添加hint:
- 调整缓存加载策略
- 为REPLICATED缓存配置
setLoadPreviousValue(true),让节点在查询缺失数据时主动从集群加载,但此方式可能带来性能开销,需结合业务场景评估。
- 为REPLICATED缓存配置
- 连接池管控
- 通过监控Ignite的JMX指标
BaselineTopology.activeNodes判断节点是否已加入基线,仅将基线节点加入应用连接池,避免应用连接未就绪的非基线节点。
- 通过监控Ignite的JMX指标
内容的提问来源于stack exchange,提问作者Sven Borkert
相关产品推荐
相关产品推荐

