Re eventual consistency: This is a difficult thing which may end up being a good thing if used as a heuristic to re-evaluate your boundaries
Event sourcing: - Isn't an architectural pattern, but CERTAINLY is an architectural DECISION - Isn't an either\or choice: mix and match polyglot persistance patterns - Streaming is related semantically: events are projected, but misses on key aspects: - The emphasis in streaming is processing vs context in ES - 👆 causes streaming platforms to optimize for throughput over partitioning for isolation - Semantically different - Event sourcing focuses on the domain specific things which happen - While streaming may be collecting signals, like a stream of current temperature from a sensor, even if temperature didn't change - Processing of an event stream _could_ result in a domain event which can be used for ES (along with other uses) - Isn't inherently complex, but does have a steep learning curve & needs the right environment to work
- Bigger risk is distributed monolith, which is FAR worse than normal monoliths. Where ES comes into play is Often this happens because of dependencies, make sure your workflows have direct access to the data and don't depend on other services. It's not just the runtime concerns - It's the domain experts who actually know what's happening. Also: - CRUD events _may_ exist, but they should be the very rare exception - Using the domain experts to create the events leads too more stable contracts... - ... and fewer breaking changes in event versions - Some things need to be immediately consistent. But not a lot. Pushing back on strong consistency isn't going to make things more complicated & if the business asks for immediate consistency ask what they mean immediately: I once had a situation where "immediately" meant before start of next working day! - Replay events so that you can be sure the events make sense, and that there are no bugs in data you store. This is especially important if you're just starting on your journey. - Replay events in write path instead of storing a projection - Events you use for event stream are local to your service - integration events are separate - Establish meaningful service boundaries - Allocate data based on business workflows, _don't_ group by semantics
- For natural keys that don't change => Stream names - Use a separate consistency boundary to enforce uniqueness (also it can be in stream or sql, whatever) - Allow action, observe and take observing actions (sometimes even humans)
Some of: 1. Don't distribute information that doesn't need to be distributed. Focus on identifiable information 2. Put all personal / sensitive information only in one place and anonymize later (delete all past events, add a new one with random data and schedule a scavange soon) 3. Crypto-shredding
When - Cost\risk to maintain external audit log is higher than adopting ES - Probably a must when you have Temporal queries (NOT "simple when was the last change", but "get all actions after X happened", or when you need point-in-time system restore (hey git!)) BUT! for ↑ you _need_ on-demand access to SME's, or at least very regular direct access to them AND design events collaboratively with them - If you have already experience in the team, and access to SME's, Event sourcing is a good default for anything other than generic services.
- In and of itself no, but also: - Since it's append-only, it's really amenable to caching. - It's quite amenable to clustering given the isolation of data across streams - _However_: - introduces eventual consistency across aggregates -> other stronger (but still weak) consistency models can be adopted but with increased complexity - Some aggregates may have a lot of events. Try: - Design that away (smaller boundaries generally will cause fewer changes to be made => fewer events) - Snapshot