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

分布式系统中Javers缓存机制疑问及自定义缓存咨询

Javers LatestSnapshotCache in Distributed MongoDB Deployments & Custom Cache Replacement

Default LatestSnapshotCache Behavior in Multi-Node Setups

First off, the default LatestSnapshotCache is a local in-memory cache, meaning every application node maintains its own isolated cache instance with no awareness of other nodes. In a multi-node MongoDB deployment, this creates two critical issues:

  • Cache consistency risks: When one node updates data and refreshes its local cache, other nodes will still serve stale snapshot data until their own cache expires or is manually cleared. This can lead to inconsistent audit/version data across your application nodes, which is a big problem for systems relying on Javers for accurate tracking.
  • Wasted resources: Each node duplicates the same GlobalId and CdoSnapshot data in memory. This adds unnecessary overhead, especially as you scale up the number of application nodes.

On top of that, the default cache's expiration rules are controlled locally—there’s no way to trigger global cache invalidation, which only makes consistency issues worse.

Can You Replace It with a Distributed Cache Like Hazelcast?

Absolutely! Javers was built with extensibility in mind, so swapping out the default cache for a distributed alternative like Hazelcast is fully supported. Here’s how to do it:

1. Implement the LatestSnapshotCache Interface

You’ll need to implement Javers’ org.javers.repository.cache.LatestSnapshotCache interface. It has three core methods to handle cache operations:

  • get(GlobalId globalId): Fetch a cached snapshot by its GlobalId
  • put(GlobalId globalId, CdoSnapshot snapshot): Store a snapshot in the cache
  • evict(GlobalId globalId): Clear a specific entry from the cache (optional but highly recommended for proactive invalidation)

Here’s a sample implementation using Hazelcast:

import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.repository.cache.LatestSnapshotCache;
import org.javers.core.json.typeadapter.commit.CdoSnapshot;

public class HazelcastLatestSnapshotCache implements LatestSnapshotCache {
    private final IMap<GlobalId, CdoSnapshot> cacheMap;

    public HazelcastLatestSnapshotCache(HazelcastInstance hazelcastInstance) {
        this.cacheMap = hazelcastInstance.getMap("javers-latest-snapshots");
    }

    @Override
    public CdoSnapshot get(GlobalId globalId) {
        return cacheMap.get(globalId);
    }

    @Override
    public void put(GlobalId globalId, CdoSnapshot snapshot) {
        cacheMap.put(globalId, snapshot);
    }

    @Override
    public void evict(GlobalId globalId) {
        cacheMap.remove(globalId);
    }
}

2. Register Your Custom Cache with Javers

Next, wire your custom cache into the Javers instance using JaversBuilder:

import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.javers.core.Javers;
import org.javers.core.JaversBuilder;

public class JaversConfiguration {
    public Javers buildJaversInstance() {
        HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
        LatestSnapshotCache customCache = new HazelcastLatestSnapshotCache(hazelcastInstance);

        return JaversBuilder.javers()
                .registerJaversRepositoryCustomizer(repository -> 
                    repository.setLatestSnapshotCache(customCache))
                .build();
    }
}

3. Key Additional Considerations

  • Cache expiration & eviction: Configure Hazelcast’s TTL (time-to-live) rules based on your business needs to prevent unbounded cache growth. Make sure to call evict() whenever data is updated to immediately invalidate stale entries.
  • Hazelcast cluster setup: Ensure your Hazelcast cluster is properly connected to all application nodes. This creates a single shared cache space, eliminating consistency issues between nodes.
  • Performance tuning: Adjust Hazelcast settings like backup counts and memory limits to balance performance and reliability based on your traffic patterns.

Final Recommendations

If your application runs on multiple nodes, replacing the default local cache with a distributed solution like Hazelcast is strongly advised. It solves consistency problems, reduces redundant memory usage, and improves overall performance. Just be diligent about handling cache invalidation to keep your Javers snapshot data accurate across all nodes.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:19:44