11 ms·
Why Are People into Event Sourcing?
- impostervt 10y agoI was looking into Event sourcing for a system I built recently, and the tooling just doesn't seem to be that widespread yet. How do you read out of the entire event stream to figure out the current state? While there are tols, they seem to be .net focused. Just didn't seem to be a "standard" answer yet. We ended up going with microservices that pub/sub events into Kafka, but maintain their own databases. There's another microservice that lets you query past events for statistics.
- rreppel 10y agoWe find that a simple in-memory synchronous message bus + event logging to files goes a long way. See e.g. https://github.com/robertreppel/hist https://github.com/robertreppel/hist for an in-memory bus + file system (and DynamoDB ...) helloworld which isn't .net. Scaling that up by adding asynchronicity and more ambitious plumbing when needed seems reasonably straightforward. For something more out-of-the-box, see https://geteventstore.com/ https://geteventstore.com/ . It has clients in a variety of languages. Comes with a nice HTTP API too. I wouldn't normally read the entire event stream; usually, only the state of a particular object (aggregate, in Domain Driven Design speak) is of interest, E.g. the customer with id 12345. Events contain the aggregate ID, so the query to whatever event store you use would be "give me all events with aggregate ID 12345".
- burnout1540 10y agoAre you using DynamoDB Streams at all? I've been toying the idea of using DynamoDB as an event store and having other services listen to a table's stream, allowing them to update caches/views (the read-side of CQRS), report analytics, perform asynchronous tasks, etc.
- parsnips 10y ago>Just didn't seem to be a "standard" answer yet. This article was extremely helpful to me for understanding some solutions in this space. http://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/ http://www.confluent.io/blog/turning-the-database-inside-out...
- samidalouche 10y agoYou basically consider the event log as a big collection,and you "fold over" the events in order to incrementally build your state/projection, the same way you would do with finite collections in a Functional language (scala, haskell, ...). GetEventStore documentation has some examples of how you can create projections (https://geteventstore.com/blog/20130212/projections-1-theory/ https://geteventstore.com/blog/20130212/projections-1-theory...), which you can use as inspiration to build your own projections.
- UK-AL 10y agoEither you have fast queries and indexes, or you have a microservice that monitors for certain events, and keeps up to date state in a cache.
- barrkel 10y agoArchitecting around events has several ramifications. For building up a picture of the world, it's pretty good. It's very nice to be able to replay a log of events and recreate a view of the way things are expected to be; if there's a bug in your code, you can fix it and repeat the replay to get back into a good state (with caveats, sometimes later actions creating events may be dependent on an invalid intermediate state). Whereas mutating updates erase history, perhaps with some ad-hoc logging on the side that is more often than not worthless for machine consumption. For decoupled related action, it's not too bad. If you have some subsystem that needs to twiddle some bits or trigger an action when it sees an event go by, it just needs to plug into the event stream, appropriately filtered. For coordinated action OTOH, e.g. a high-level application business-logic algorithm, you need to start thinking in terms of explicit state machines and, in the worst case, COMEFROM-oriented programming[1]. Depending on how the events are represented, published and subscribed to, navigating control flow involves repeated whole-repo text searching. It's best if your application logic is not very complicated and inherently suitable to loose coupling, IMO. [1] https://en.wikipedia.org/wiki/COMEFROM https://en.wikipedia.org/wiki/COMEFROM
- kazagistar 10y agoI've tried working out how to move to an event sourcing system, but I always struggle with locking behavior. Do you just have to invent your own locking mechanisms on top of event sourcing?
- jessaustin 10y agoISTM event sourcing actually avoids many locking problems, since it's essentially "write-only". Of course every event write should be atomic, but that seems easier than making updates atomic?
- kazagistar 10y agoWhen a certain set of events occurs (the files arrive etc) I want to kick off one and only one batch processor task. This is accomplished with a transaction and a write lock in an sql database, but when trying to use event sourcing it ends up requiring a 2 step "intent to run" event before running or some out of band synchronization.
- jnbiche 10y agoI'm not sure you can achieve good event sourcing performance using a regular database engine. Better to view it like writing logs. If you really must expose an SQL API, perhaps you could read the journal on another thread or process and then make changes to the db based on the incoming "diffs" that the threads determines from the journal?
- karmajunkie 10y agoThis isn't something I would handle with event sourcing. Using ES throughout an application is an antipattern. For something like this my batch processor is implemented as you're probably used to—files get a CRUD model associated with them, schedule a background job to handle it, let locking get handled there. Once inside the batch processor you can use the same domain services and commands that you'd use from your application layer and commit events on a command basis, or on something like a row in the file (which may generate several commands and dozens of events depending on your model), or on a file level (all or nothing.) The thing I see people do frequently (and sadly, have done myself on occasion!) that makes their lives harder is trying to shoehorn everything into ES without doing the design work to establish a domain, its boundaries, and what events make sense within it.
- GundersenM 10y agoHaving been part of a project to rewrite a monolith e-commerce site into an event-sourced, domain driven, CQRS system, let me tell you in which situation that is not possible: when you already have data. Remember that in a DDD, ES, CQRS system, the event store is the single source of truth. If you already have data in a relational database, then the existing data is the source of truth. You can't have two sources of truth, that completely defeats the purpose. So it's not actually possible to migrate to an event sourced system, you can only create one from scratch, with no existing data.
- UK-AL 10y agoWell you can, you need to create some events for each entity to get into the existing state. You won't have any history though.
- dragonwriter 10y agoConceptually, that's not really true: you just transform the pre-ES state into one or more events (in an basic accounting system, which is pretty much the simplest ES system, long-predating the name for the model, this is just creating "starting balance" entries as transactions.) In practice, that can be challenging, but it doesn't seem fundamentally more challenging than any other legacy data conversion effort.
- GundersenM 10y agoSure, if the existing DB is simple, that is straight forward, but remember that likely this is a monolith that is so bad that even management have agreed that it needs to be rewritten. Likely there are lots of DB tables with foreign keys and relations (sometimes documented and enforced, most often not). This means you can't really convert the entire database into an event sourced system, as that means converting all of the tables in one single go, instead of a gradual change. And believe me, in a system like this you want slow gradual changes! Also, even of you got it into events, what happened to the domains? There are so many relations between the different events sources (because you didn't put everything into just one event source, right? What happened to bounding contexts?) that you are no better off. And this means you have to prevent anything else from using the database anymore, and in a legacy system where you can just join across any two or three tables to extract whatever information you want, you can be certain there are some analysis engines that are just feeding directly on the sql data. And there might be other systems writing to the database too! So the first step is to disentangle all the data and encapsulate it, trying to prevent others from using it, so you have full control over it. This includes tracking down any other system using this data, and ensuring they too go through the database. And you have to do this for one subsystem at a time, often in several iterations.
- taeric 10y agoAs someone that has fallen for the "event sourcing" promise before, the article does a decent job explaining the promise. Not sure if it will be the next article, but the actual task of delivering on this work is where things break. Hard. The vast majority of the things you will ever program are pretty much guaranteed from one statement to the next. Hard boundaries, where things can fail, are often decently understood and actually quite visible in the code. Moving everything to be an event completely throws this out the window. You can take a naive view, where you pretend from one event to the next is safe to happen. However, to start building up the system to cope when this is not the case starts to build a complicated system. In areas that are decidedly not related to your business domain. (Well, for most of us.) Maybe some day there will be a system that helps with this. Until then, my main advice is to make sure you have solved your system with a naive solution before you move on.
- samidalouche 10y agoDo you have specific examples of where things break hard? We are currently using ES end to end for a distributed application including a wearable device, iOS app and scala backend, and up to now, the things that broke hard in the system are the naive/non ES parts. For information, on the server-side, we are currently experimenting with GetEventStore (https://geteventstore.com/ https://geteventstore.com/), which seems to be working well for us.
- taeric 10y agoI'm curious what has broken that was not directly related to the hard split between the wearable and the backend. This is a particular case where you are by definition doing a distributed system, so any attempts to hide that will be problematic. My main thoughts are anywhere you are trying to hide that distributed nature, things will go awry. Add to that, anywhere you have introduced the potential for things to be distributed. The sibling post about keeping it simple as you build up your eventing system is pretty accurate. Remember you are trying to solve an actual customer problem. Keep pointed on that and do not get distracted by any neat engineering problems that come along the way. (This is not to say you will not have to solve some... but if you are solving a neat problem that was not needed for the customer's problem, you are going to have trouble.)
- btown 10y agoEvent sourcing isn't nearly as common knowledge among new programmers as the CRUD-one-row-per-entity pattern, and it really should be. I liken it to introducing version control for your data; when immutable updates are your canonical source, no matter how much the system behind them changes, or the business requirements change, and no matter how many teams are deriving different things from them in parallel, they can all work off of the same data and "merge" their efforts together. The one downside is that shifting your business logic to read-time means that you need to have very efficient ways of accessing and memoizing derived data. For some applications, this can be as simple as having the correct database indices over your WhateverUpdates tables, fetching all updates into memory and merging on each request. For others, you'll need to have a real-time stream processing pipeline to preemptively get your derived data into the right shape into a cache. And those are more moving parts than your typical monolith app, but the One benefit to actually using event sourcing with a stream processing system is that, in many cases, it can be the most effective way to scale both traffic capacity and organizational bandwidth, much in the same way that individually scalable microservices can (and fully compatible with that approach!). Martin Kleppman at Confluent (a LinkedIn spinoff creating and consulting on stream processing systems) writes some great and highly-approachable articles about this. Highly recommended reading. http://www.confluent.io/blog/making-sense-of-stream-processing/ http://www.confluent.io/blog/making-sense-of-stream-processi... http://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/ http://www.confluent.io/blog/turning-the-database-inside-out...
- blowski 10y agoThe CRUD one-row-per-pattern is common because it's enough for most projects. It works well with ORMs so you can build quickly and securely. And most of the time, performance isn't an issue and having a history of an entity is unnecessary. I'm worried that event sourcing is going to become this year's over-applied design pattern with libraries in every language for every database with blog posts that recommend it be used on every project. It's a good idea, very useful - in the right hands on the right projects. But it makes sense that junior devs normally use CRUD because that's normally the right solution. At least until better tools come along.
- 10y ago
- sanderjd 10y agoFYI in case the author reads this, since this seems to be intended as an intro for people who aren't already familiar with this stuff: I didn't see "CQRS" defined anywhere in this article or in the two or three links I followed from it; they all begin with an assumption that you know the acronym, and delve straight into details. It might be good to define some terms in the front matter (unless I've misunderstood the target audience).
- rreppel 10y agoAlways a problem with techie - acronymania. :) Thanks, noted. I'll do an edit.
- tofflos 10y agoAxon Framework http://www.axonframework.org http://www.axonframework.org is a great place to start if you're into Java and want to get a feeling for how event sourcing works. There's also a great presentation by the developer, Allard Buijze, at https://www.youtube.com/watch?v=s2zH7BsqtAk https://www.youtube.com/watch?v=s2zH7BsqtAk.
- grandalf 10y agoThere is a lot that could be done to make event sourcing easier to work with... Imagine tooling that allowed an event stream to be used to create state for testing modules, crudlike helpers to allow crud-familiar developers to think that way at first, and workflows based on snapshots, rewind, etc. I think a model that used events that correlated to graph deltas rather than crud deltas would be the cat's ass, and many queries about the near-current state could be handled efficiently using ephemeral subgraphs as indexes located at the network's edges. If anyone wants to discuss and possibly build some of this stuff, let me know :)
- jsprogrammer 10y agoOnly issue with building it is that it probably already exists somewhere (though, we may not be able to access it).
- karmajunkie 10y ago> Imagine tooling that allowed an event stream to be used to create state for testing modules, crudlike helpers to allow crud-familiar developers to think that way at first, and workflows based on snapshots, rewind, etc. i know where you're going with this, and i honestly believe its a terrible idea (not to be discouraging or rude—just experienced.) if your event streams contain mostly CRUD (possibly ANY) then you're most likely applying it incorrectly. Its not just a version history of your data. The event type itself is data, which provides context and semantics over and above the notion of writes and deletes. If you're falling back to crud events all you're doing is creating a lot more work for yourself and deriving almost no benefit from the use of ES—in that case, you should just use CRUD and the ORM of your choice.
- porker 10y ago> if your event streams contain mostly CRUD (possibly ANY) then you're most likely applying it incorrectly. Its not just a version history of your data. Thanks for that. I'd made that mistake: I have a system which now needs to become distributed (a copy of it goes offline for a couple of weeks, and has to merge back into the main datastore) and keep a history of changes. It's currently CRUD backed by MySQL, and I'd latched onto event sourcing as what I'd need. > The event type itself is data, which provides context and semantics over and above the notion of writes and deletes. OK, going to have to get my head around that :)
- willvarfar 10y agoVery curious: if you have multiple datastores, how do you ensure they are consistent? If you scale sideways, how do you ensure nothing gets lost if there's a partition? Etc?
- PallarelCoedr 10y agoEmbrace eventual consistency. A good deal of collaborative domains (things involving human decisions) are naturally eventually consistent. Meat computers appear to be particularly good at resolving conflicts and compensating.
- zarkov99 10y agoI have been working with this sort of patterns for a while but I have yet to find good texts exploring the topic. Does anyone have book or paper recommendations for event sourcing? The stuff I have seen is mostly programmers reporting on something that worked on their particular domain. I am, looking for something more rigorous and comprehensive.
- karmajunkie 10y agoLurk on the CQRS/DDD list [1], lots of good info there. I'm not aware of any textbooks on ES per se but there are a few good books on areas that overlap. [2] [3] [4] [1] https://groups.google.com/forum/#!forum/dddcqrs https://groups.google.com/forum/#!forum/dddcqrs [2] https://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683/ref=sr_1_1?ie=UTF8&qid=1475563462&sr=8-1&keywords=patterns+of+enterprise+integration https://www.amazon.com/Enterprise-Integration-Patterns-Desig... [3] https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577/ref=sr_1_sc_3?ie=UTF8&qid=1475563596&sr=8-3-spell&keywords=vaugn+vernor https://www.amazon.com/Implementing-Domain-Driven-Design-Vau... [4] https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=pd_bxgy_14_2?ie=UTF8&psc=1&refRID=0HVKJD3MP0QACV5SJK6F https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
- SEJeff 10y agoTwo must-read documents for those who want to learn more about this method of building reactive applications: https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying https://engineering.linkedin.com/distributed-systems/log-wha... http://martinfowler.com/eaaDev/EventSourcing.html http://martinfowler.com/eaaDev/EventSourcing.html Note that Martin's blog is what inspired the event bus in https://home-assistant.io https://home-assistant.io, an open source home automation project I occasionally contribute to.
- EdSharkey 10y agoHere's the term I wish was unfashionable with the kids: reshaping. Did you spot all those command-to-query-to-event-to-log-to-storage data type conversions in those pretty diagrams? That's a whole bunch of needless reshaping of data as it flows through the system. For each one of those data transformations to be successful, there has to be accurate communications between people and bug free code written in the data conversion and routing of messages through the system. All those moving parts make changing the system extremely painful, lotsa ripple effects - and every time you have to make a change to your events, you'd have a data migration project for any running event streams. Naming things is hard too, and there's a lot more naming of entities needed in a CQRS-ES system. I like all the promised benefits of a CQRS and ES, but I can't imagine a case where I'd take the risk of attempting it on anything but a toy project. Perhaps if I was on the version 5 rewrite project for an insanely profitable system where the requirements and design are completely understood up-front. I would need to grok some canonical example of a large, well-architected, well-implemented representative system before I would ever attempt to implement one. Are there any non-toy examples of successful CQRS-ES with open source available to read? Did those projects go over-budget, and by how much? Would the authors of those examples still recommend the architecture now that they've gone through the experience?
- deleted 10y ago[deleted]
- rreppel 10y agoOpen sourced ones? The largest example I'm aware of is https://github.com/MicrosoftArchive/cqrs-journey https://github.com/MicrosoftArchive/cqrs-journey. There's a pretty extensive write-up of their experiences too. https://msdn.microsoft.com/en-us/library/jj554200.aspx https://msdn.microsoft.com/en-us/library/jj554200.aspx
- EdSharkey 10y agoI can't tell if this is a toy experiment or not.
- kasey_junk 10y ago
- freditup 10y agoAs an interesting comparison, some people see the Redux/Flux pattern as a front-end parallel to event sourcing. [0]: https://github.com/reactjs/redux/issues/891#issuecomment-158693484 https://github.com/reactjs/redux/issues/891#issuecomment-158...
- avodonosov 10y agoHow strange, just today I've heard the Event Sourcing name and thought I don't know what it is. (Turns out it is this old idea I knew under various different names). And at the same day I hear about Event Sourcing on HN. What's the buzz?
- karmajunkie 10y agoIts been slowly building steam (under that name) for about ten years, first in .Net and now filtering out to other ecosystems. I think its kind of inevitable given the recent popularity of functional programming models.
- mamcx 10y agoI for some months now have tried to build a small test-case for a invoice app. I wish to have a good syn strategy and the use of ES sound good. However, I have find how replicate the functionality of a normal app with this: For example, what to do for avoid duplicates and in general pre-saving validations. Also, I need to anyway to use RDBMS tables for hold current-data and RDBMS have not a good history for stream back results.