Search code examples
javaspring-bootcachinghazelcastspring-cache

Distributed Cache Across Microservice Domains


Is managing @CachePut in a different microservice from @Cacheable in a distributed cache environment an anti-pattern?

I'm working on spring boot microservices that are split across two domain categories: data ingestion and UI. The ingestion is separated from the UI services so that bursts of data will not impact response times. Once the data is ingested, we fan it out on kafka to a persistence service for storage and a session service for real-time determinations such as user notifications.

To ensure that I can keep up with the ingestion rate, I want to cache the user notification configuration in my ingestion pipeline after the initial REST lookup. But if a user updates their configuration in the UI (e.g. increase / decrease warning threshold, turn off warnings, change to digest), I want the cache refreshed with that update. Because I will be auto-scaling these services to meet demand, I plan to use distributed cache.

Does splitting @CachePut and @Cacheable across two different microservices in a distributed cache configuration constitute an anti-pattern? Would sending the objects across kafka constitute a better alternative?

My gut tells me to avoid splitting the cache management across microservices like this because I can imagine someone changing the cache keys in one service and forgetting to change them in the second. On the other hand, sending them across kafka to a consumer in the session service would look ugly, something like this:

@CachePut(value = "config", key = "new SimpleKey(#config.userId, #config.applicationId)")
public UserApplicationConfig fakeSave(UserApplicationConfig config) {
  // not actually saving anything, just need somewhere to put my CachePut annotation
  return config;
}

Solution

  • Of course it is an anti pattern since it breaks the service boundaries, data hiding in particular.

    When the user data is updated, you want to update the service clients that have a cached version of your user data. A better design would send an event "User data changes" and let service clients subscribe to it.

    With a distributed cache you introduce possible points of failure, latency and configuration options for consistency, which are not simple.