Ignite缓存子对象调用ClientCache.remove()删除失败如何解决
Ignite ClientCache 自定义键匹配失效问题解决方案
核心原因
Ignite客户端缓存默认基于对象二进制序列化结果做键匹配,不会直接调用你重写的equals()和hashCode()方法。当你修改子类成员字段、或存在父子类序列化结构差异时,即使两个对象逻辑上是同一个键,二进制序列化结果也会不一致,最终导致remove操作匹配不到对应缓存。
自定义比较器实现步骤
你需要实现Ignite提供的BinaryComparator接口来定义键的匹配规则,具体操作如下:
- 第一步:实现
org.apache.ignite.binary.BinaryComparator接口,基于业务唯一标识字段自定义相等判定和哈希计算逻辑,示例代码如下:
import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryComparator; public class DriveKeyComparator implements BinaryComparator { @Override public int compare(BinaryObject o1, BinaryObject o2) { // 校验类型是否为BaseClass及其子类 boolean o1Valid = o1.type().isAssignableFrom(BaseClass.class); boolean o2Valid = o2.type().isAssignableFrom(BaseClass.class); if (!o1Valid || !o2Valid) { return -1; } // 仅用业务唯一标识字段做比较,不要包含可变非标识字段 Long keyId1 = o1.field("id"); Long keyId2 = o2.field("id"); return keyId1.compareTo(keyId2); } @Override public int hashCode(BinaryObject obj) { if (!obj.type().isAssignableFrom(BaseClass.class)) { return obj.hashCode(); } // 哈希计算逻辑和比较逻辑保持一致,仅用唯一标识字段计算 Long keyId = obj.field("id"); return keyId == null ? 0 : keyId.hashCode(); } }
- 第二步:在缓存配置中注册自定义比较器,创建
ClientCacheConfiguration时添加如下配置:
ClientCacheConfiguration cacheCfg = new ClientCacheConfiguration(); cacheCfg.setName("Baseclass"); // 绑定自定义比较器 cacheCfg.setBinaryComparator(new DriveKeyComparator()); cacheCfg.setKeyConfiguration(new CacheKeyConfiguration(BaseClass.class.getName()));
- 第三步:如果对应缓存已经预先创建,需要销毁原有缓存后重新初始化,或同步更新集群所有节点的缓存配置后重启节点,新配置才会生效。
注意事项
- 比较逻辑仅保留业务唯一标识字段的判定,不要包含会被修改的非核心字段,避免字段更新后键匹配失效
- 必须保证比较逻辑和哈希计算逻辑的一致性:如果两个键判定为相等,两者的哈希值必须完全相同
- 不要在比较器内将
BinaryObject反序列化为Java对象,会大幅降低缓存操作性能,直接通过field()方法读取二进制字段即可
内容的提问来源于stack exchange,提问作者Bishnu
相关产品推荐
相关产品推荐

