2

I've read a number of conflicting articles as to whether microservices should share a database. How and when should microservices communicate?

Someone posed the example of 2 microservices:

  1. Employee
  2. Department

Suppose the Employee microservice needs information about a department.

  • Should these microservices share a database?
  • Should they communicate over REST?
  • Should they duplicate data in each of their own databases?
4
  • Which approach best meets your specific software requirements? Jan 5, 2021 at 2:43
  • I thought that communicating over REST was the best solution so that the services would remain decoupled. However, this has performance implications which is why I was asking Jan 5, 2021 at 5:51
  • 1
    This might prove enlightening: martinfowler.com/bliki/MicroservicePremium.html Jan 5, 2021 at 12:53
  • In a perfect world. None of the 3. It might interest. Take a look at Messaging
    – Laiv
    Jan 5, 2021 at 14:49

3 Answers 3

5

They should communicate over a communication channel. Of which there are many out there:

  • Web Requests
  • UDP
  • Pipes
  • Semaphores
  • Files
  • ...

Sharing is tricky, micro-services are about ownership.

Straight up a service Owns its own code, and its own data. The only thing it shares is the communication channels, and even then it owns its end of the channel. This allows a service to be redeployed with a different version or even a different implementation, perhaps even with different platform beneath it, without affecting any other service.

This is much more difficult, perhaps impossible when two services attempt to share a resource. Because neither of them own it, thus neither have the ability to update/change it unless both are changed simultaneously, which is temporal coupling. Thus the two services are not independent and are therefore a single service.

As to the literal question: you've probably got something out of order.

  • Employee's don't care about departments except by reference.
  • Departments don't care about employee's except by reference.

If you have an algorithm that requires both pieces of information it probably doesn't sit in either micro-service. Maybe:

  • You don't have a Department and Employee microservices, but a single Employee/Department microservice.
  • You have an XYZ (like a Human Resource service) that sits in front and is responsible for orchestrating contextually larger processes, and interactions requiring information and knowledge from lower tier services.
  • You have a workflow where by the employee service does some work, and hands it over to the Department service for further processing by some communication mechanism. Perhaps the Department service passes it onto other systems for further processing, or passes it back depending on the work.

And yes caching is also an option, but a better example would be of a geolocation service providing verified street address information. The employee service and department service would be served well by caching some/all of this data locally in the services own data storage mechanism. This is due to:

  • its slowly changing nature
  • its easy verifiability
  • it being relatively light weight from both a bulk, and per item perspective.
  • and that addresses are themselves identifiers

If those properties apply to department, then yes caching should be considered, but I doubt they do, otherwise I would be collapsing this into the employee data unless a more compelling reason for keeping them separate exists.

1
1

There is no one-size-fits-all answer here.

It all begins with the realization that microservices are not even necessarily web services. It's definitely the most common scenario, but not the only one. And when you don't have a web component, you'll obviously have to find another way to handle the communication.

Should these microservices share a database?

This is not a great idea, as this infringes on the independence of the microservices. There's two possibilities here: either the microservices share some of the db content, or they share nothing.

If they share something, then your microservices cannot be independently deployed, because any change to the shared data forces a redeployment of both services. In this case, they cease to be "true" microservices.

If they don't share anything, then there's no reason to put it in the same database (additionally, then they don't communicate using the database either). It's better to separate the dbs then, as it means that you can take one db down (or restore it) without affecting the other.

Should they communicate over REST?

If your microservices are not web services, it's obviously not possible.

For web services, you generally use the web component for communication with consumers anyway, so it makes sense to reuse this for communication between web services. That's not necessarily REST, any data transmission format would work here. But REST is the most common.

Should they duplicate data in each of their own databases?

Usually, the point of microservices is that each microservice stores its own data. There's not a lot of duplication going on. You'd expect all of a person's data to be contained in the person service, and the order service only stores a reference to the person ID.

However, it might be the case that you save a historic table of orders which contain personal information that should be kept the same even if the person's data changes in the future. For example, if I change my address today, when I look up an order I made last year, it should still show the address that I used back then.

It may become relevant here to copy the person's data into the order, so that the order service can keep it for historical purposes.
However, if I never change my personal data, that does indeed mean that the same data is found in both the person service and the order service's databases. We can argue that their purpose is different (current information vs historical snapshot, or person data vs order data) but the values are possibly (and likely) the same.

But this is no different than if you were using a monolith application without microservices. The same principle of making historic copies of data would apply. So this isn't really microservices-related in and of itself.

In summary, you tend not to duplicate data between microservices, unless a valid reason to do so exists.

1

Let's look T it section by section

Sharing Database: When I am designing an microservices application, I would nearly almost never choose sharing database because

  • With shared database, when there is a high load on business function (one microservice), it would load the database, and this would affect the performance of the other database
  • It would be very hard to change the schema of the database. When the schema is changed this will cause many microservices (if not all) to be deployed
  • Different types of databases are more suited for different use cases. For example, a relational database or document database would be good for reporting. Where a Event store database would be suitable for banking transactions. When sharing the database, the flexibility is lost

what could be considered I would consider the following mechanism to share data

  • Duplicate the data. And identify a mechanism for resolving conflict
  • Communicate via HTTP (including long, short polling, callbacks)
  • Communicate via RPC such as GRPC
  • Communicate by sending messages or publishing events
  • And many other methods

How to make the decision

  • We don't need to make one decision that has to be followed always
  • Each of the mechanism to communicate has it's own pros and cons
  • The communication mechanism should be chosen based
    • Desired speed of communication
    • Expected rate of data exchange
    • Payload size of each data exchange
    • The desired data consistency level in the application
    • and so on
1

Your Answer

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

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