Live data from Hacker News

Event Sourcing (2017)

arkwright.github.io

51–60 of 80 posts

Re: Event Sourcing (2017)

#51
post #20

A word of caution for anyone considering an event-sourced architecture. I was on a large government project where the decision was made to use event sourcing, and it was disastrous. It ended up being a big contributor to several years of time and cost overruns. The reason is that for event sourcing to work, you have to have a pretty good idea of your application's requirements up front. It's simply not conducive to a…

A way to deal with it that I've seen to work with Kafka is to make your messages not last very long (say about a week) and make them explicitly idempotent. So an "old" message being run would not affect the app negatively.

And then you make every producer of messages able to reproduce all the messages it knows about.

So if you have a new service and need historical data, you ask all of your dependencies to resend the data, and existing services should not be affected.

Schema evolution is natural - old messages with old schemas don't last very long, and you can slowly migrate services to new schemas as needed.

If you structure your events that each one holds all state of an entity, you could get removal of data easily for free, as any new message would overwrite old state.

Though the whole thing has its own problems though - especially when you go into large amounts of messages/data. Keeping copies of those around if you make a lot of changes can be quite expensive.

So the whole event sourcing thing looks to me as it needs a decade or two to mature so that tools are built and best practices established. It looks to me as basically a way to keep data for a lot of separate services in a fluid eventually consistent way.

Wonder if Clojure's Datomic is already there. Haven't used it myself but have read promising things about it.

Re: Event Sourcing (2017)

#52
post #50

Earlier quoted context omitted.

No, you should not compute the state you need from the event log on every request, this would be absurd. Your authorization service can maintain its own database (a "view" of the current state), or even an in-memory representation computed at startup, and update it whenever a new event pops up. Alternatively, if you are using Kafka, you can use stuff like KTables to do this.

This sounds like working around event sourcing - what value does event sourcing add here, vs simply not using it at all for user accounts?

For this specific case, nothing, however let's say you need to know when the user got a specific scope and from who. You probably can answer this question in SQL if you prepared your database to do it (i.e: a changeset table), however in an event sourcing architecture you would gain this information for free.

However, just because you're using event sourcing doesn't mean you don't have a database with the current state of your entities.

Re: Event Sourcing (2017)

#53
post #14

Earlier quoted context omitted.

Can you describe more precisely how you're defining "soft-delete" here?

data is still stored somewhere but any routing to the data is disabled and the entity is disassociated.

Could you point towards an authoritative source for this claim?

As a consumer, if I request deletion of my data, I expect it to be actually deleted - not just have a "deleted" flag set.

With soft-deletion, the data is still right there, ready to be abused after a breach.

Re: Event Sourcing (2017)

#54
post #51
post #20

A word of caution for anyone considering an event-sourced architecture. I was on a large government project where the decision was made to use event sourcing, and it was disastrous. It ended up being a big contributor to several years of time and cost overruns. The reason is that for event sourcing to work, you have to have a pretty good idea of your application's requirements up front. It's simply not conducive to a…

A way to deal with it that I've seen to work with Kafka is to make your messages not last very long (say about a week) and make them explicitly idempotent. So an "old" message being run would not affect the app negatively. And then you make every producer of messages able to reproduce all the messages it knows about. So if you have a new service and need historical data, you ask all of your dependencies to resend the…

Best practices around this have already been established. Most if not all event stores - which Kafka is not - have a concept called 'position.' You save the position atomically along with whatever you did with the message. Then if you crash, you simply ask for all messages starting from that position. If you have a new service (or a new projection), your position is 0 so you get everything.

Re: Event Sourcing (2017)

#55
post #50

Earlier quoted context omitted.

No, you should not compute the state you need from the event log on every request, this would be absurd. Your authorization service can maintain its own database (a "view" of the current state), or even an in-memory representation computed at startup, and update it whenever a new event pops up. Alternatively, if you are using Kafka, you can use stuff like KTables to do this.

This sounds like working around event sourcing - what value does event sourcing add here, vs simply not using it at all for user accounts?

That's command-query responsibility segregation. The command stream gives you the nice log of everything that happened, while the read database is easy to query (and to reprogram if necessary).

Re: Event Sourcing (2017)

#56
post #47
post #20

A word of caution for anyone considering an event-sourced architecture. I was on a large government project where the decision was made to use event sourcing, and it was disastrous. It ended up being a big contributor to several years of time and cost overruns. The reason is that for event sourcing to work, you have to have a pretty good idea of your application's requirements up front. It's simply not conducive to a…

I'm actually quite happy to see that other people are also facing similar problems with event-sourced microservices. The project that I'm on (currently working for a neo-bank) has been trying to use event-sourcing from the get go, and oh god, is it a mess. The project has been going on for awhile and some of the devs thought it a good idea to focus on scalability and all the other metrics that don't matter. As your d…

https://leanpub.com/esversioning/read

Re: Event Sourcing (2017)

#57
post #51

Earlier quoted context omitted.

A way to deal with it that I've seen to work with Kafka is to make your messages not last very long (say about a week) and make them explicitly idempotent. So an "old" message being run would not affect the app negatively. And then you make every producer of messages able to reproduce all the messages it knows about. So if you have a new service and need historical data, you ask all of your dependencies to resend the…

Best practices around this have already been established. Most if not all event stores - which Kafka is not - have a concept called 'position.' You save the position atomically along with whatever you did with the message. Then if you crash, you simply ask for all messages starting from that position. If you have a new service (or a new projection), your position is 0 so you get everything.

That is indeed the case, and this is what Kafka calls unlimited retention topics. This however hampers schema evolution significantly as you're not allowed to make backwards incompatible changes. Or rather if you allow those changes, every service would need to be able to handle every schema throughout time.

If you make the retention to only several days this would mean you can evolve your schema with even breaking changes. Consumers would need to support only schemas that are "active right now". If the retention period is long enough that it is safe to assume all the consumers have acted on all the old messages you can delete those messages. You would need a mechanism to replay them though, if that data is ever needed again, but it would just be in the latest schema.

Re: Event Sourcing (2017)

#58
post #22

Earlier quoted context omitted.

Thank you for this. I've been warning people off Event Sourcing for a while now. The architecture is the most convoluted, pretentious, redundant and downright soul-crushing. If you see Event Sourcing anywhere, run away. Run far, far away.

Some of worlds most useful and powerful data structures are the projection of an event log. The tables of a RDBMS, the balanced writes of a SSD, and even the classic: double-entry book-keeping. Even the data stream of a TCP connection is a projection of events, which is why (and how) we can reconstruct them by replaying captured segments. So just because there are some lousy executions of a general architecture, does…

Just because a tool is powerful doesn’t mean it’s appropriate. There’s a reason most people should just use a DB and not a raw event log. The issue I have with ES proponents is they seem to all pretend there is no additional complexity that comes with it. I think ES is useful but not always and requires weighing the costs and benefits, and we need to be honest about it.

Re: Event Sourcing (2017)

#59
post #50

Earlier quoted context omitted.

This sounds like working around event sourcing - what value does event sourcing add here, vs simply not using it at all for user accounts?

That's command-query responsibility segregation. The command stream gives you the nice log of everything that happened, while the read database is easy to query (and to reprogram if necessary).

Isn't that confusing two different things, CQRS and ES? I use CQRS all the time, but have never built a system using Event Sourcing.

Regarding logs, "traditionally", I'd use an audit/change history table for objects that needed one.

Re: Event Sourcing (2017)

#60
post #50

Earlier quoted context omitted.

No, you should not compute the state you need from the event log on every request, this would be absurd. Your authorization service can maintain its own database (a "view" of the current state), or even an in-memory representation computed at startup, and update it whenever a new event pops up. Alternatively, if you are using Kafka, you can use stuff like KTables to do this.

This sounds like working around event sourcing - what value does event sourcing add here, vs simply not using it at all for user accounts?

The siblings already said it, but event sourcing requires you (at least for practical purposes) to segregate the read model from the write model using "projections". The good thing is that, whenever you create a new service, you can derive the projections that your service will need from the same source of truth. In this way, you create coupling on the data, but not on the concrete service that owns it.

This is not very different from what a relational database does with redo logs. In fact, in a way, using event sourcing resembles composing a system from the fundamental building blocks of a traditional DBMS, in a distributed way.

Post reply on HN