You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用亲和键(affinity key)并置时如何保留仅传ID的键值API能力

可行方案

有两种可落地的实现方式,都能同时满足数据并置性能要求、以及仅通过原始数据ID调用KV API的需求,不需要改造现有readthrough逻辑。


方案1:直接使用原始类型作为KV键(最简便)

不需要使用内置的AffinityKey包装类,直接用原始整数类型(Long/Integer等)作为缓存键,仅需在缓存对应的value实体类中,给用于并置的亲和键字段添加@AffinityKeyMapped注解即可。
示例代码:

// 缓存值实体类
public class Order {
    // 实体主键,对应KV调用时传入的原始ID
    private Long orderId;
    // 用于数据并置的亲和键(例如关联的用户ID),添加注解后Ignite会自动基于该字段计算分区位置
    @AffinityKeyMapped
    private Long userId;

    // 其余业务字段、构造方法、getter/setter省略
}

使用时和普通KV操作完全一致,直接调用cache.get(orderId)即可正常触发readthrough逻辑,命中缓存。SQL查询时只要按userId字段做关联匹配,会自动享受数据并置的性能优势,不会产生跨节点分布式查询。


方案2:自定义键类,重写相等判断逻辑

如果需要保留键类封装,可以自定义键类型,不使用内置的AffinityKey:

  • 键类中同时包含实体主键ID、亲和键两个字段
  • 给亲和键字段添加@AffinityKeyMapped注解,告诉Ignite基于该字段做分区并置
  • 重写equals()和hashCode()方法,仅基于实体主键ID做判断,不纳入亲和键字段
    示例代码:
public class OrderKey {
    // 实体主键ID
    private Long orderId;
    // 数据并置用的亲和键
    @AffinityKeyMapped
    private Long userId;

    // 构造方法、getter/setter省略

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        OrderKey that = (OrderKey) o;
        return Objects.equals(orderId, that.orderId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(orderId);
    }
}

这种方式下,即使构造OrderKey时只传入orderId、不填userId,也能正常命中缓存、触发readthrough。等readthrough从数据库加载到全量数据后,把完整的键(带userId)和值写回缓存即可,后续分区路由、SQL并置查询都能正常生效。


内置AffinityKey无法仅用ID匹配的原因

内置AffinityKey类本身的equals()和hashCode()逻辑是同时校验「实体ID」和「亲和键」两个字段的,和KeyCacheObject包装层没有关系。只传ID时,因为缺少亲和键字段值,相等判断必然不通过,自然无法命中缓存。


适配注意事项
  • 使用上述两种方案时,readthrough逻辑不需要做特殊改造:如果用原始类型键,CacheStore的load()方法接收到的参数就是你传入的原始ID,直接查库返回对应实体即可,只要保证返回的实体中@AffinityKeyMapped标记的字段值正确,Ignite会自动完成分区路由。
  • 不要尝试修改内置AffinityKey的相等判断逻辑,会破坏Ignite内部的分区校验规则,可能导致数据路由错误。

内容的提问来源于stack exchange,提问作者ofer.ignite

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 12:09:27