Services update data model often after locking data. This can cause contention and consequently slow write speed. Event sourcing is an architectural pattern in which instead of storing the current state  of entity, all action events on an entity are stored in an append only store called event store. Current state is determined by replaying sequence of events. Since event store is an append only store , this improves the write speed as there is no need to synchronize the data model. How ever the read speed will be slower as reading the current state of the entity is a fold over all history events of the domain object. CQRS (command query responsibility segregation) pattern separates the read data model and write data model for faster reads is often used in conjunction with event sourcing , where event store is the write data model . Hence fast writes and fast reads both are possible how ever there is consistency problem with CQRS as the read model may not be in synch with write model

Event sourcing

Applications typically maintain the current state of data/entity by updating It. Typically locks are used for isolation to avoid problems like dirty read and lost updates. Additionally the history of transasctions is either lost if not explicitly maitained or will cause futher performance over heads as , in addtion to maintaining current state of entity, history of changes is also maitained. Event sourcing is an architectural pattern in which the state of the appliction is determined by a sequence of events .

In event soucring

  1. The events which lead to state changes in an entity are appeneded in an immutable, authoratative data store called event store. (hence there is no contention during processing of transactions). 
  2. The current state of entity is not maintained, instead the entity is persisted as sequence of events in an event store. (In RDBMS each entity is persisted as rows in a table and entity fields become columns)
  3. Current state of an entity can be determined by replaying the events for the entity. (The code must iterate through each event for the entity in the correct chronological order).
  4. When a service receives a command it converts the command into list of events representing the state changes. It is these events which are persisted in event store and emitted by event store.
  5. When ever entity / domain object state changes event store must publish events usually for 
    1. Transaction/operation completion
    2. CQRS
    3. Materialized views.
  6. As event store act as storage and publish events , they solve the problem of updating local db and emitting event.
    1. From the microservice perspective event store is a hubrid of datastore + message broker as event only has to be pushed to event store.
      1. under the hood event store may be using rdbms + message broker like kafka. (a message relay would pick non published events from eventstore and publish to kafka, note that in case of eventstore transaction outbox will not be there) 
    2. Event store does need transaction outbox. It can use polling approach to determine the unpublished events (based on published column in the events table which tracks if an event is published or not.) and publish them. Note that in case event ids are monotonically increasing, determining unpublished events based on last published event id can run into edge conditions.
  7. As the history of changes are maitained and hence temporal queries are possible.
  8. Consider using version of event schema if the format of events can change. event schema change can often be backward compatible as adding a filed is not likely to impact consumers of event. the consumer will simply ignore unknown fields. Some times the older events may need to to be migrated to the new schema
  9. If the number of events for an entity are large (eg accounts ), snapshots of the aggregate/entity state can be created at specific intervals, so that current state can be created by replaying the events created after the snapshot. ie firs the aggregate instance is created with the help of snapshot and then iterate through events created after snapshot creation. The snapshot can be JSON.
  10. Note that events emitted by cosumers have to be handled by idempotent consumers. If acid datbase is used then event/message id should be put in processed_messages table as part of atomic transaction that inserts into the event table.In case nosql db is used and acid gurantees are not there the message consumer stores the message id in the events that are generated while processing it. Duplicate detection can be done by ensuring none of aggregates events contain the message id. Read more https://clarifyforme.com/posts/5658330156498944/Idempotent-consumer   note that processing of message must necessarily generate event (a dummy if necessary ) so that message id can be stored in the event/dummy event.
  11. Deleting data can be a challenge in event store hence some times encrypting data which is deletable and deleting the encryption key is one way of deleting.Pseudoanomization is another solution.
  12. Some points to remember about events.
    1. Note that the names of the events are formulated in the past tense. The names of the event should be expressive and part of the ubiquitous language of the project (Domain driven design principle) A good example will be orderDeliveredEvent. createOrderEvent would be a bad example as createOrderEvent would be command style syntax.
    2. In domain driven design Aggregate is a logical construct which is collection of entities that is bounded to specific business context. There is a root entity which is responsible for lifecycle of the whole object graph under it. Eg loan application can be root entity and within it income source and many other entities or value objects can be present. Events should be based on aggregates , they should not be too fine grained.
    3. Events are always immutable
    4. Events are not deleted from event store, delete event is another event.
      1. some times based on regulatory complilance may need to be deleted . One option is to anonamize the event.
      2. dump pipes(light weight message brokers) and smart end points is good for event sourcing.
    5. Event are commonly stored as json. Event can also be a row in an RDBMS.

When to use Event sourcing

Disadvantages of event soucing

Event store

As allready mentioned event store is essentially database + event realy + message broker. Event store typically would have 3 tables

CQRS(command query responsibility seggregation)

Typically read and write of data is done through the same layer in n layer architecture. In microservices (with each service obeying the hexagonal architecture also does this) The read and write data model is the same.

Event Sourcing + CQRS challenges

When to avoid CQRS