1

Can cache be shared among services via Redis/Hazelcast?

I have a few microservices A, B, C etc. The Microservice C is mainly for helping other services. Service C periodically updates cache - so that Service A and B can read from the cache - if cache is not present, then they use some default values.

I feel like - designs like this are used by companies like Twitter for their timeline services. At the same time, I also think it is like going back to single DB for all services.

Can you share some best practices around this?

1 Answer 1

2

While it can, it certainly doesn't mean it should. It really depends on your use case. Generally, a cache shouldn't be a single point of failure (or any failure) for that matter, and apps that "depend" on it should be able to transparently handle if the cache is down.

Rules of Thumb👍

Generally:

  • Each microservice should be as independent from others as possible and communicate with others only via clear/defined APIs
  • Microservices shouldn't be sharing resources/databases with each other. That's generally considered an antipattern.
  • Each database/resource should be written by (and read by) ONE microservice only

What you have now

I think what you are having right now is something like this:

enter image description here

What you should aim for

enter image description here

Is the variant where

  • Service C is the only one writing to the cache
  • Services A and B ASK service C for the current state of the cache but don't directly read from it

The benefit is that now B and C would work against an API rather than a shared data model, and you'd be able to reason more easily about C and also make changes to the underlying data model, data store, without worrying that it might affect A and B. Generally with a microservice, if you find that changing the database model affects other services, it's probably not really a microservice.

Take all this with a grain of salt 🧂

There are some architectures where this might not be the best choice, it all depends. The negatives of the proposed approach are:

  • Adding another layer of indirection can be expensive in terms of performance. It's ALWAYS faster (in terms of performance) to make one call to the cache with service A than ask C and then wait for C's answer. HTTP/Rest calls do often come with extra overhead in terms of response size compared to raw calls to a database.
  • If a single client HTTP call goes to so many layers before getting a response e.g A -> B -> C -> D -> Redis, then something is probably wrong in the total architecture. Having so many layers before a client request is "completed" incurs tremendous penalties in terms of performance, SLA, availabilities, and just pure reasoning. When response time is critical, aim the decision to be made with as little "hops" as possible.
  • When we are not dealing with a response time but rather storage/analytics, more layers are okay
  • A and B really need to be able to tolerate the absence/downtime of service C. Strategies like Circuit Breaking, retries (don't assume the network is stable), local caching, etc can go a long way in keeping your SLA up.

I recommend these very amusing talks:

4
  • What do you think of this ? Here the cache seems to be shared - aws.amazon.com/blogs/architecture/….
    – RamPrakash
    Feb 20, 2022 at 19:11
  • If C exposes REST API, then I do not see why we need A or B. The client can directly use C anyway. Thanks for your time and answer.
    – RamPrakash
    Feb 20, 2022 at 19:16
  • C can be an internal service handling specific domain concerns. it's a very common practice. For example, A is a service for handling payments, B is the admin portal, and both A and B rely on C which is the authentication service. You generally don't want to allow A and B CRUD to the underlying database of C as you want C to be the only service which manages the authentication concerns. in the example you shared there is only one service and 1 cache (or 3 services, 3 caches, depends how you look at it), Bottom line is the cache is usable only by 1 service at the time.
    – baba
    Feb 20, 2022 at 23:51
  • My question for sharing a cache comes from sharing 'logged in user sessions' between microservices, or if you use JWTs, sharing 'revoked tokens'. It's an anti-pattern to share a database, so what is the best practice here?
    – nl-x
    Jun 21, 2023 at 7:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.