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

Infinispan DIST_SYNC分布式缓存跨节点数据不同步问题求助

Infinispan集群节点数据不同步问题排查修复

核心问题出在缓存配置和操作逻辑两个层面,逐个对应调整即可:

1. L1近缓存配置导致本地脏读

你当前在DIST_SYNC模式下开启了L1缓存:.l1().enable()。L1是非数据所有者节点本地存储的只读缓存,默认不会在数据更新时主动同步,只有等本地缓存条目过期才会重新拉取新值,这就是其他节点持续读到旧值的最直接原因。

  • 不需要极致读性能优化的话直接关闭L1:把.l1().enable()改成.l1().disable(),所有读写会自动路由到数据的实际所有者节点,DIST_SYNC模式本身就保证写入同步到所有副本节点,不会出现不一致问题。
  • 必须保留L1的话,补上主动失效配置:.l1().enable().invalidationThreshold(0),保证键更新时立刻广播消息,通知所有节点清理本地存储的旧L1条目。

2. 递减操作逻辑不符合分布式缓存原子要求

如果你是在业务代码里先get值、本地计算减法、再put回缓存,这个流程本身在分布式场景下就不安全:请求打到非所有者节点时,会直接读取本地L1的旧值计算,就算最后put操作同步到了所有者节点,中间窗口期其他节点还是会读到旧值,多节点并发操作还会出现写覆盖问题。

  • 数值类增减操作直接用缓存自带的原子方法:比如cache.decrement(key)、cache.getAndDecrement(key),这类操作会直接下发到数据所有者节点执行,不需要本地读改写流程,天然保证原子性和集群一致性。
  • 你集成了Bucket4j做限流的话,不要手动封装缓存操作,直接用Bucket4j官方的Infinispan集群适配构造器,避免自定义逻辑绕过集群同步机制。

3. 集群连通性补充校验

你贴的JGroups配置本身没有缺项,K8s环境下的节点发现、故障检测、状态传输协议都配置完整。服务启动时可以搜索日志里的集群视图条目,确认所有节点都加入了同一个rate-limiting-cluster集群,视图中包含所有节点的地址,排除节点网络不通、各自组建独立集群的情况。

修正后的核心配置参考

public CacheManager cacheManager() {
    GlobalConfigurationBuilder builder = GlobalConfigurationBuilder.defaultClusteredBuilder();

    builder.serialization().marshaller(new JavaSerializationMarshaller())
            .whiteList().addRegexps("io.github.bucket4j.*", "java.util.*");

    builder.transport()
                .defaultTransport()
                .clusterName("rate-limiting-cluster")
                .addProperty("configurationFile", "default-jgroups-tcp.xml");


    org.infinispan.configuration.cache.Configuration configuration = new ConfigurationBuilder()
            .clustering()
            .cacheMode(CacheMode.DIST_SYNC)
            .hash()
            .numOwners(2)
            .numSegments(256)
            // 关闭L1避免本地脏读
            .l1().disable()
            .locking().lockAcquisitionTimeout(1000)
            .build();

    DefaultCacheManager cacheManager = new DefaultCacheManager(builder.build(), configuration);
    cacheManager.defineConfiguration(RateLimitingType.CACHE_BLOCKED.getValue(), configuration);
    return new SpringEmbeddedCacheManager(cacheManager);
}

改完重启所有节点后可以做简单验证:A节点写入测试key值为10,B节点执行递减操作,回到A节点读取值为9即说明同步逻辑正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:01:10