Live data from Hacker News

What they don’t tell you about event sourcing

medium.com

11–20 of 81 posts

Re: What they don’t tell you about event sourcing

#11
Is it just me or the article never presented a solution to the posited problem: ”Since each entity is represented by a stream of events there is no way to reliable query the data. I have yet to meet an application that doesn’t require some sort of querying.”

The solution is said to be CQRS, and nothing in the article shows how you solve that.

If you unwind the unnecessarily winded florid poetic waxing, it all comes down to “dump it to a database, and query that”.

Re: What they don’t tell you about event sourcing

#12
post #8

Regarding eventual consistency, a CQRS\ES system can also be synchronous, or partially. You could have listeners for events that need to supply a strongly consistent model and others events that feed parts of the system that don't need strong consistency. "However the events in a event store are immutable and can’t be deleted, to undo an action means sending the command with the opposite action" Well they don't have…

The author has explained the problem with eventual consistency and the CAP theorem, but he is trying to blame the problem at least partly on CQRS/ES - the problem will exist independently of what pattern you use if your system is distributed.

CQRS/ES is a pattern and doesn't need to be shoe-horned into every solution.

I work at Transport for London and we have a CQRS/ES system for managing the data driven design data. It is synchronous and is incredibly useful for ensuring it has both strong business logic and a fast readable side, while providing auditing for free.

We still have problems with EC and CAP, and they are not due to CQRS/ES. Make the system distributed and you will have to handle all the new scenarios. Those are the trade-offs.

Re: What they don’t tell you about event sourcing

#14
I've worked with event sourced systems quite a bit in production and at scale, and have written a book on Akka and another one on related topics. While I have been an advocate of the approach, My experiences are guiding me away from implementing Event Sourcing in many use cases (especially where the entities are long lived). While CQRS is more complex, I'm more likely to implement CQRS without event sourcing, where an entity is responsible for its own persistence using whatever mechanism we deem suitable, and emits events that can be used for the view (or the data can be viewed as read only.) Ultimately a bounded context is there, and you send it commands and get out events. You have to evaluate the recovery and persistence mechanism based on your needs. Exactly once delivery is a pipedream so it doesn't matter how you're persisting the event and delivering it, evaluating line by line, crashing somewhere it's going to be possible to emit an event twice somewhere (eg if the outbound projection emits the event but doesn't persist its offset.) You need to deduplicate somewhere to get exactly once processing semantics. There _are_ simpler approaches to persistence that work just fine with the same delivery guarantees that work fine in the place of Event Sourcing. Nobody talks about any alternatives though - everyone defaults to event sourcing. My intuition guides me to look at other options having been burned one too many times, watching organizations collapse around 100% event sourced applications, etc.

I'm still working on event/message driven systems (today with Elixir mostly) but I've started to make architectural compromises to move away from especially event sourcing. Event Sourcing + CQRS may be prescriptive but it's very hard for new developers to pick up and understand the layers of abstraction underneath eg Akka + the Persistence Journal. And I'm not sure I can trust many of the open source libraries outside of Akka to be honest. I've had to dig into the depths of postgres journal implementations and apply windowing to journal queries for example because they weren't burned in at the scale I was working with (partially because I inherited an application with a single entity in a context which had many million line long journals - this highlights a design error though but hopefully you can see my point.)

You don't _need_ to use these patterns but you can still apply DDD and event/message based abstractions, and publish events. An entity can write its state to a record and then apply the state in memory as well without using a journal given you handle exactly once processing semantics correctly. This means there are knobs and dials. The problem with event sourcing in the greater picture is that it's descriptive of an approach, and there aren't many clear alternatives that people are talking about that work in similar system designs. If you have very long lived entities, or only a few of them, it gets especially difficult to keep the system alive over time, but for those use cases it doesn't mean you should stop receiving commands and emitting events.

You always here about the idea of the approach, never the reality of maintaining these systems, or the inappropriate use. In one implementation, there is one entity that receives thousands of events a day, and lives forever. How do you maintain the journal while changing the code, keep it alive over time? I've watched event sourcing and CQRS sink projects and teams. I've watched well paid contractors unable to figure out how to cluster and scale these systems. The barrier to entry for people to become effective can be high and you should understand the long view in terms of people required and cost over time and validate the approach for your use case very carefully. Again, the fact that everyone talks about event sourcing and no closely related alternatives makes it seem like the gold standard or the only option but there are other (simpler) ways to deal with your persistence in an overall similar architectural approach.

Re: What they don’t tell you about event sourcing

#15

Is it just me or the article never presented a solution to the posited problem: ”Since each entity is represented by a stream of events there is no way to reliable query the data. I have yet to meet an application that doesn’t require some sort of querying.” The solution is said to be CQRS, and nothing in the article shows how you solve that. If you unwind the unnecessarily winded florid poetic waxing, it all comes d…

In practice it is typical to maintain a snapshot of the current state in a more-query-able form. In some systems, event writes and their corresponding snapshot updates occur within a transaction.

Re: What they don’t tell you about event sourcing

#16
The last section on Operational Flexibility and the inability to change the event history raises a very good point.

Like most of the issues, the solution requires experience to know when you are at the Goldilocks point (Just Right). This specific issue has a lot in common with managing database migrations in django or any other migration system.

The ideal situation is to create migrations that can always be rolled back, but sometimes this is not possible to do operationally. For example, a schema change that restricts a field from NVARCHAR to INTEGER can only be generically rolled back if all of the unconvertable data is persisted. This can be mitigated by structuring the database to avoid these dead-ends, and that really is only gained by hard-won experience.

The problem with undoing operations via new events is the same thing -- unless you have foreknowledge of this kind of problem, it is very easy to accidentally create events that perform un-undoable actions. A very simple example of a problematic event would be something that modifies a foreign-key relationship -- let's say it's a digital asset in a game and you want the ability to transfer ownership of the item from one player to another.

The simple solution is a event like SetAssetOwner(asset_pk, player_pk). This would set the item's player foreign key field to the player's primary key. Easy. However, you have lost knowledge of where the asset came from and cannot undo this operation. A better solution would be to make an event SwapAssetOwner(asset_pk, owner_pk, recipient_pk). Yes, the owner_pk is technically redundant, but it provides a check against someone trying to steal an item with a maliciously crafted SetAssetOwner event that performs no checking. Even better, this operation can be reverted by sending the same event with the owner and recipient arguments reversed. Since these properties are part of the event message, they will be persisted in the event history and all of the information to undo the event is self-contained.

Re: What they don’t tell you about event sourcing

#17
post #6
post #2

They didn't even tell me what event sourcing is.

Just think of it as double-entry bookkeeping. It's been around for a while. :) The events that we record become our source of truth.

> think of it as double-entry bookkeeping

just think of it as bookkeeping, period. a ledger of all events. absolutely nothing to do with double entry (which for accounting; from wiki: "The double entry has two equal and corresponding sides known as debit and credit.")

Re: What they don’t tell you about event sourcing

#18

I've worked with event sourced systems quite a bit in production and at scale, and have written a book on Akka and another one on related topics. While I have been an advocate of the approach, My experiences are guiding me away from implementing Event Sourcing in many use cases (especially where the entities are long lived). While CQRS is more complex, I'm more likely to implement CQRS without event sourcing, where a…

I've re-read your post a couple of times, but still find it confusing. It reads like you're an early-adopter, and got burnt multiple times by design flaws, and people not being familiar with it.

Suppose ES/CQRS is designed well, and a well-understood mechanism, would you still move away from it? For which scenarios? I can imagine exactly-once delivery not being a problem in all scenarios.

And what is the problem with long-lived entities? Solely the fact it takes longer to reconstruct current state?

Re: What they don’t tell you about event sourcing

#20
post #8

Regarding eventual consistency, a CQRS\ES system can also be synchronous, or partially. You could have listeners for events that need to supply a strongly consistent model and others events that feed parts of the system that don't need strong consistency. "However the events in a event store are immutable and can’t be deleted, to undo an action means sending the command with the opposite action" Well they don't have…

I also share same opinion based on my experience. Events can be modified and deleted but that must be an exceptional situation (GDPR and other compliances, etc.). But even if it's exceptional you have to provide a clear and easy way to do so and that increases complexity of the solution by a lot.

Another thing is strongly consistent models, there may be valid requirements in some problem areas to have a strongly consistent and normalized model and use it for command validation. This helps especially well in the case when all requirements are not known upfront and/or business domain changes very frequently. A small change in business may require to completely redo the aggregate roots and logic if you follow standard approach, this is very expensive. A better decision could be to use a normalized SQL database instead of an aggregate root. Such approach may be more flexible in certain cases and have it's own benefits as well as cost and drawbacks.

Post reply on HN