1
votes

I've read tons of documentation, blog posts and examples about CQRS with EventSource as a useful architecture in a Microservice system.

A popular example is the banking transfer app: banking transfer app

It's clear there are four microservices, but I don't understand becouse the "command side" microservices don't have their own database.

By this image all Microservices are using the same eventStore database, that's should be against the microservice pattern?

And how should be the EventStore db? Single table? One table for each service ?

3
In this diagram, "Event Store" is serving as the book of record (database) for /transfers and /accounts, and also as an event publisher (you see Account View Updater subscribing to it). Only the "Command side" is using the event store database. - VoiceOfUnreason
I see Event Store is serving as /transfers too, that's is part of another microservice (Money Transfer). Then Money Transfer and Accounts are separated microservice that are sharing Event Store. - Adriano Foschi
I think Richardson (author of that image) intends that you recognize two microservices, not four. That said, if you wanted to think of the command side as two independent microservices with their own logical event stores, that happen by configuration to be using the same physical event store, that's fine too. - VoiceOfUnreason
So the microservice that you recognize are AccountQueryUpdateService and "the other" that's include all three controllers - Adriano Foschi

3 Answers

2
votes

Most decisions are about trade-offs, and this is no exception. In the usual definition of microservices, each service would have it's own database for the reasons @thiago-custodio mentions. You get complete separation and encapsulation of your service. This, however, puts more burden on the operational aspects of the business, as you now have N databases to administrate. You also have a new "how do all the things talk to each other" problem to solve. This may or may not be an issue for you.

You could get some of the benefits of service separation and encapsulation from sharing a database but, for example, having separate schemas for each service. You still get some level of isolation at the database level, but reduce your operational complexity. Again, trade-offs.

I view the use of a single event store / message queue as an acceptable trade off to make as a way to enable communication between lots of services.

It's clear there are four microservice,

Not necessarily from just viewing the diagram out of context. There are two controllers that write events to an event store, and a controller that returns a query. This looks like a diagram to explain CQRS rather than microservices. CQRS is not a top-level architecture - you would apply it within a microservice.

but I don't understand becouse the "command side" microservices don't have own database.

The event store is the database. The query side has a separate database that will be optimised for queries.

2
votes

Decided I needed a bigger space to clarify my comments

It's clear there are four microservices,

I don't think that's clear at all.

It happens that this specific image comes from https://github.com/cer/event-sourcing-examples

In the overview, Richardson writes:

One of the neat things about the modular architecture is 
that there are two ways to deploy these four services:

monolithic-service - all services are packaged as a single Spring Boot executable JAR

Microservices - three separate Spring Boot executable JARs
    accounts-command-side-service - command-side accounts
    transactions-command-side-service - command-side money transfers
    accounts-query-side-service - Account View Updater and Account View Reader

Presenting at Scala By the Bay, he calls out the pattern of one microservice publishing into an event store, and a second microservice subscribing to those events and updating a view store.

So I think you can make fair arguments for counting this as one, two, three, or four microservices.

One thing to consider in your counting is that the Account View Adapter needs to have an understanding in common with Accounts, and an understanding in common with Transfers, in order to understand the state information contained within the events to produce the view (the Account View Reader does not need this shared understanding, because it is just copying the data from the view store).

Udi Dahan has some interesting things to say about service boundaries; in particular, that you preserve loose coupling among your services by limiting the amount of data publicly shared by your services.

My application of his guideline to this diagram tells me that the Account View and the two aggregates must be part of the same boundary, because they all have access to the data which is private to this service.

Of course, you could still design these four service components separately, if you are careful to preserve backwards compatible changes to the event schema.

It's clear there are four microservices, but I don't understand becouse the "command side" microservices don't have their own database.

You could view those two microservices as having distinct logical event stores that happen to be the same physical store. There's some potentially headache involved if you decide that one of those logical stores needs to be migrated, but aggregate event streams are isolated from each other, so you don't need to worry to much about coupling between accounts and transfers.

And how should be the EventStore db? Single table? One table for each service ?

A typical relational schema for an event store will treat the event itself as a blob, and expose some of the meta data (the eventId, for instance) so that it can be joined with other tables. So a generic store probably looks like one table to hold the events, and another table to hold event streams. There are some links to discussions of relational schemas in storing events when using event sourcing.

If you wanted to partition/shard the schema that into multiple physical tables, you could do that too.

There are also non-relational stores that you might use. If you look into the details of Event Store (which is open source), you can learn a lot about how to implement a store.

Or you can just treat it as a black box.

0
votes

In my opinion and according to what I've read so far about microservices architecture, the idea of each service having it's own persistence mechanism is to create an independent service that could be entirely rewritten, if needed, without affecting the consumers. (as long as you keep the request/response contract for the client).

This is the Decentralized Data Management. characteristic, and making microservices using the same database, you won't achieve that.

For further read:

http://martinfowler.com/articles/microservices.html