SlideShare a Scribd company logo
1 of 128
Download to read offline
Event Sourcing
what could possibly go wrong?
Andrzej Ludwikowski
About me
➔
➔ ludwikowski.info
➔ github.com/aludwiko
➔ @aludwikowski
➔ academy.softwaremill.com
SoftwareMill
SoftwareMill
SoftwareMill
SoftwareMill
JVM
BLOGGERS
SoftwareMill
● Hibernate Envers
● Alpakka Kafka
● Sttp
● Scala Clippy
● Quicklens
● MacWire
What is Event Sourcing?
DB
Order {
items=[itemA, itemB]
}
What is Event Sourcing?
DB
DB
Order {
items=[itemA, itemB]
}
ItemAdded(itemA)
ItemAdded(itemC)
ItemRemoved(itemC)
ItemAdded(itemB)
What is Event Sourcing?
DB
DB
Order {
items=[itemA, itemB]
}
ItemAdded(itemA)
ItemAdded(itemC)
ItemRemoved(itemC)
ItemAdded(itemB)
History
● 9000 BC, Mesopotamian Clay Tablets,
e.g. for market transactions
History
● 2005, Event Sourcing
“Enterprise applications that use Event Sourcing
are rarer, but I have seen a few applications (or
parts of applications) that use it.”
Why Event Sourcing?
● complete log of every state change
● debugging
● performance
● scalability
● microservices integration pattern
ES and CQRS
Client
Query Service
Data access
Queries
Read
model
Read
model
Read
models
Command Service
Domain
Events
Commands
ES and CQRS level 1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Transaction
Command Service
Domain
Events
Commands
ES and CQRS level 1
● Entry-level, synchronous & transactional event sourcing
● Implementing event sourcing using a relational database
● slick-eventsourcing
ES and CQRS level 1
+ easy to implement
+ easy to reason about
+ 0 eventual consistency
- performance
- scalability
ES and CQRS level 2
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
Transaction
Command Service
Domain
Events
Commands
ES and CQRS level 2
+/- performance
+/- scalability
- eventual consistency
- increased events DB load ?
- lags
ES and CQRS level 3
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
Transaction
event
bus
Command Service
Domain
Events
Commands
ES and CQRS level 3.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
Command Service
Domain
Events
Commands
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
Command Service
Domain
Events
Commands
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
At-least-once delivery
Command Service
Domain
Events
Commands
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
?
ES and CQRS level 3.2
Events
Client
Query Service
Data access
Commands
Queries
Read
model
Read
model
Read
models
Projector
event
bus
Command Service
Domain
Command Service
Domain
Command Service
Domain
Transaction
`
Sharded
Cluster
ES and CQRS level 3.x
+ performance
+ scalability
- eventual consistency
- complex implementation
- locking vs Single Writer
ES and CQRS alternatives
● Change Capture Data (CDC) logging instead of event bus?
● event bus instead of DB?
Not covered but worth to check
● Command Sourcing
● Event Collaboration
ES implementation?
● custom
● library
● framework
ES from domain perspective
● commands, events, state
● 2 methods on state
○ process(command: Command): List[Event]
○ apply(event: Event): State
ES from application perspective
● snapshotting
● fail-over
● recover
● debugging
● sharding
● serialization & schema evolution
● concurrency access
● etc.
import javax.persistence.*;
import java.util.List;
@Entity
public class Issue {
@EmbeddedId
private IssueId id;
private String name;
private IssueStatus status;
@OneToMany(cascade = CascadeType.MERGE)
private List<IssueComment> comments;
...
public void changeStatusTo(IssueStatus newStatus) {
if (this.status == IssueStatus.DONE
&& newStatus == IssueStatus.NEW || this.status == IssueStatus.NEW
&& newStatus == IssueStatus.DONE) {
throw new RuntimeException(String.format("Cannot change issue status from %s to %s",
this.status, newStatus));
}
this.status = newStatus;
}
...
}
import javax.persistence.*;
import java.util.List;
@Entity
public class Issue {
@EmbeddedId
private IssueId id;
private String name;
private IssueStatus status;
@OneToMany(cascade = CascadeType.MERGE)
private List<IssueComment> comments;
...
public void changeStatusTo(IssueStatus newStatus) {
if (this.status == IssueStatus.DONE
&& newStatus == IssueStatus.NEW || this.status == IssueStatus.NEW
&& newStatus == IssueStatus.DONE) {
throw new RuntimeException(String.format("Cannot change issue status from %s to %s",
this.status, newStatus));
}
this.status = newStatus;
}
...
}
import org.axonframework.commandhandling.*
import org.axonframework.eventsourcing.*
@Aggregate(repository = "userAggregateRepository")
public class User {
@AggregateIdentifier
private UserId userId;
private String passwordHash;
@CommandHandler
public boolean handle(AuthenticateUserCommand cmd) {
boolean success = this.passwordHash.equals(hashOf(cmd.getPassword()));
if (success) {
apply(new UserAuthenticatedEvent(userId));
}
return success;
}
@EventSourcingHandler
public void on(UserCreatedEvent event) {
this.userId = event.getUserId();
this.passwordHash = event.getPassword();
}
private String hashOf(char[] password) {
return DigestUtils.sha1(String.valueOf(password));
}
}
import akka.Done
import com.lightbend.lagom.scaladsl.*
import play.api.libs.json.{Format, Json}
import com.example.auction.utils.JsonFormats._
class UserEntity extends PersistentEntity {
override def initialState = None
override def behavior: Behavior = {
case Some(user) => Actions().onReadOnlyCommand[GetUser.type, Option[User]] {
case (GetUser, ctx, state) => ctx.reply(state)
}.onReadOnlyCommand[CreateUser, Done] {
case (CreateUser(name), ctx, state) => ctx.invalidCommand("User already exists")
}
case None => Actions().onReadOnlyCommand[GetUser.type, Option[User]] {
case (GetUser, ctx, state) => ctx.reply(state)
}.onCommand[CreateUser, Done] {
case (CreateUser(name), ctx, state) => ctx.thenPersist(UserCreated(name))(_ => ctx.reply(Done))
}.onEvent {
case (UserCreated(name), state) => Some(User(name))
}
}
}
ES packaging
● github.com/aludwiko/event-sourcing-akka-persistence
import java.time.Instant
import info.ludwikowski.es.user.domain.UserCommand.*
import info.ludwikowski.es.user.domain.UserEvent.*
import scala.util.{Failure, Success, Try}
case class User (userId: UserId, name: String, email: Email, funds: Funds) {
def process(command: UserCommand): Either[List[UserEvent]] = command match {
case c: UpdateEmail => updateEmail(c)
case c: DepositFunds => deposit(c)
case c: WithdrawFunds => withdraw(c)
...
}
def apply(event: UserEvent): User = ??? //pattern matching
}
ES packaging
● snapshotting
● fail-over
● recover
● debugging
● sharding
● serialization & schema evolution
● concurrency access
● etc.
ES packaging
● domain logic
● domain validation
● 0 ES framework imports
library vs. framework
● Akka Persistence vs. Lagom
● Akka Persistence Typed
Event storage
● file
● RDBMS
● Event Store
● MongoDB
● Kafka
● Cassandra
Event storage for Akka Persistence
● file
● RDBMS
● Event Store
● MongoDB
● Kafka
● Cassandra
akka-persistence-jdbc trap
val theTag = s"%$tag%"
sql"""
SELECT "#$ordering", "#$deleted", "#$persistenceId", "#$sequenceNumber",
"#$message", "#$tags"
FROM (
SELECT * FROM #$theTableName
WHERE "#$tags" LIKE $theTag
AND "#$ordering" > $theOffset
AND "#$ordering" <= $maxOffset
ORDER BY "#$ordering"
)
WHERE rownum <= $max"""
akka-persistence-jdbc trap
SELECT * FROM events_journal
WHERE tags LIKE ‘%some_tag%’;
Cassandra perfect for ES?
● partitioning by design
● replication by design
● leaderless (no single point of failure)
● optimised for writes (2 nodes = 100 000 tx/s)
● near-linear horizontal scaling
ScyllaDB ?
● Cassandra without JVM
○ same protocol, SSTable compatibility
● C++ and Seastar lib
● up to 1,000,000 IOPS/node
● not fully supported by Akka Persistence
Event serialization
● plain text
○ JSON
○ XML
○ YAML
● binary
○ java serialization
○ Avro
○ Protocol Buffers (Protobuf)
○ Thrift
○ Kryo
Plain text Binary
human-readable deserialization required
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
storage consumption compress
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
storage consumption compress
slow fast
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
storage consumption compress
slow fast
poor schema evolution support full schema evolution support
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Multi-language support
● Avro
○ C, C++, C#, Go, Haskell, Java, Perl, PHP, Python, Ruby, Scala
● Protocol Buffers (Protobuf)
○ even more than Avro
Speed
https://code.google.com/archive/p/thrift-protobuf-compare/wikis/Benchmarking.wiki
Size
https://code.google.com/archive/p/thrift-protobuf-compare/wikis/Benchmarking.wiki
● backward - V2 can read V1
Full compatibility
Application
Events
V1
V2
● forward - V2 can read V3
Full compatibility
Application
Events
V1, V2
V2
Application
Application
V2
V3
● forward - V2 can read V3
Full compatibility
Events
Read
model
Read
model
Read
models
Projector
V2
V3
Schema evolution - full compatibility
Protocol Buffers Avro
Add field + (optional) + (default value)
Remove field + + (default value)
Rename field + + (aliases)
https://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
Protobuf schema management
//user-events.proto
message UserCreatedEvent {
string user_id = 1;
string operation_id = 2;
int64 created_at = 3;
string name = 4;
string email = 5;
}
package user.application
UserCreatedEvent(
userId: String,
operationId: String,
createdAt: Long,
name: String,
email: String
)
Protobuf schema management
package user.domain
UserCreated(
userId: UserId,
operationId: OperationId,
createdAt: Instant,
name: String,
email: Email
) extends UserEvent
package user.application
UserCreatedEvent(
userId: String,
operationId: String,
createdAt: Long,
name: String,
email: String
)
Protobuf schema management
● def toDomain(event: UserCreatedEvent): UserEvent.UserCreated
● def toSerializable(event: UserEvent.UserCreated): UserCreatedEvent
Protobuf schema management
+ clean domain
- a lot of boilerplate code
Avro schema management
package user.domain
UserCreated(
userId: UserId,
operationId: OperationId,
createdAt: Instant,
name: String,
email: Email
) extends UserEvent
{
"type" : "record",
"name" : "UserCreated",
"namespace" :
"info.ludwikowski.es.user.domain",
"fields" : [ {
"name" : "userId",
"type" : "string" }, {
"name" : "operationId",
"type" : "string" }, {
"name" : "createdAt",
"type" : "long" }, {
"name" : "name",
"type" : "string" }, {
"name" : "email",
"type" : "string"
} ]
}
Avro deserialization
Bytes Deserialization Object
Reader Schema
Writer Schema
Avro writer schema source
● add schema to the payload
● custom solution
○ schema in /resources
○ schema in external storage (must be fault-tolerant)
○ Darwin project
● Schema Registry
Avro schema management
package user.domain
UserCreated(
userId: UserId,
operationId: OperationId,
createdAt: Instant,
name: String,
email: Email
) extends UserEvent
{
"type" : "record",
"name" : "UserCreated",
"namespace" :
"info.ludwikowski.es.user.domain",
"fields" : [ {
"name" : "userId",
"type" : "string" }, {
"name" : "operationId",
"type" : "string" }, {
"name" : "createdAt",
"type" : "long" }, {
"name" : "name",
"type" : "string" }, {
"name" : "email",
"type" : "string"
} ]
}
Protocol Buffers vs. Avro
{
"type" : "record",
"name" : "UserCreated",
"namespace" :
"info.ludwikowski.es.user.domain",
"fields" : [ {
"name" : "userId",
"type" : "string" }, {
"name" : "operationId",
"type" : "string" }, {
"name" : "createdAt",
"type" : "long" }, {
"name" : "name",
"type" : "string" }, {
"name" : "email",
"type" : "string"
} ]
}
message UserCreatedEvent {
string user_id = 1;
string operation_id = 2;
int64 created_at = 3;
string name = 4;
string email = 5;
}
Avro schema management
+ less boilerplate code
+/- clean domain
- reader & writer schema distribution
Avro
+ less boilerplate code
+/- clean domain
- reader & writer schema distribution
Protobuf
+ clean domain
- a lot of boilerplate code
Avro vs. Protocol Buffers
● The best serialization strategy for Event Sourcing
Event payload
● delta event
● rich event (event enrichment)
● + metadata
○ seq_num
○ created_at
○ event_id
○ command_id
○ correlation_id
State replay time
● snapshotting
● write-through cache
Memory consumption
Immutable vs. mutable state?
● add/remove ImmutableList 17.496 ops/s
● add/remove TreeMap 2201.731 ops/s
Fixing state
● healing command
Updating all aggregates
User(id)
Command(user_id) Event(user_id)
Event(user_id)
Event(user_id)
Handling duplicates
Events
Read
model
Read
model
Read
models
Projector
event
bus
At-least-once delivery
https://www.seriouspuzzles.com/unicorns-in-fairy-land-500pc-jigsaw-puzzle-by-eurographics/
Handling duplicates
Events
Read
model
Read
model
Read
models
Projector
event
bus
At-least-once delivery
Events
Handling duplicates
Events
Read
model
Read
model
Read
models
Projector
event
bus
idempotent updates
Events
Event + seq_no
Event + seq_no
Handling duplicates
Events
Read
model
Read
model
Read
models
Projector
event
bus
Event + seq_no
read model update +
seq_no
Events
Broken read model
Events
ad model
ead model
Read
models
Projector
event
bus
Events
Broken read model
Events
ad model
ead model
Read
models
Projector
event
bus
read model update + offset
(manual offset management)
Events
Multi aggregate transactional update
● rethink aggregates boundaries
● compensating action
○ optimistic
○ pessimistic
Pessimistic compensation action
User account
Cinema show
Pessimistic compensation action
User account
Cinema show
charged
Pessimistic compensation action
User account
Cinema show
charged
booked
Pessimistic compensation action
User account
Cinema show
charged
booked sold out
Pessimistic compensation action
User account
Cinema show
charged
booked
booked sold out
Pessimistic compensation action
User account
Cinema show
charged
booked
booked sold out
Pessimistic compensation action
User account
Cinema show
charged
booked
booked sold out
refund
Optimistic compensation action
User account
Cinema show
charged
booked sold out
Optimistic compensation action
User account
Cinema show booked
booked sold out
overbooked
Optimistic compensation action
User account
Cinema show
charged
booked
booked sold out
overbooked
?
Saga
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Updater
event
bus
Transaction
Saga - choreography
Command Service
Domain
Events
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
Saga - orchestration
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
model
Read
model
Read
models
Projector
event
bus
Transaction
Command Service
Domain
Events
Commands
Saga
● should be persistable
● events order should be irrelevant
● time window limitation
● compensating action must be commutative
Saga
● Sagas with ES
● DDD, Saga & Event-sourcing
● Applying Saga Pattern
● Microservice Patterns
ES with RODO/GDPR
● “right to forget” with:
○ data shredding (and/or deleting)
■ events, state, views, read models
○ retention policy
■ message brokers, backups, logs
○ data before RODO migration
ES and CQRS level 3.2
Events
Client
Query Service
Data access
Commands
Queries
Read
model
Read
model
Read
models
Projector
event
bus
Command Service
Domain
Command Service
Domain
Command Service
Domain
Transaction
Sharding
Clustering
Cluster = split brain
1
5 4
3
Load balancer
2
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Command(1)
Cluster = split brain
1
5 4
3
Load balancer
2
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Command(1)
User(1)
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Command(1)
User(1)
Command(1)
Cluster best practises
● remember about the split brain
● very good monitoring & alerting
● a lot of failover tests
● cluster also on dev/staging
● keep it as small as possible (code base, number of nodes, etc.)
Summary
● carefully choose ES lib/framework
● there is no perfect database for event sourcing
● understand event/command/state schema evolution
● eventual consistency is your friend
● scaling is complex
● database inside-out
● log-based processing mindset
Want to learn more?
● Reactive Event Sourcing with Akka (Java/Scala)
● Akka Typed Fundamentals (Java/Scala)
● Akka Cluster
● Performance tests with Gatling
Rate me please :)
Thank you and Q&A
➔
➔ ludwikowski.info
➔ github.com/aludwiko
➔ @aludwikowski
WE
WANT
YOU
Thank you and Q&A
➔
➔ ludwikowski.info
➔ github.com/aludwiko
➔ @aludwikowski

More Related Content

What's hot

카프카, 산전수전 노하우
카프카, 산전수전 노하우카프카, 산전수전 노하우
카프카, 산전수전 노하우if kakao
 
Storage Capacity Management on Multi-tenant Kafka Cluster with Nurettin Omeroglu
Storage Capacity Management on Multi-tenant Kafka Cluster with Nurettin OmerogluStorage Capacity Management on Multi-tenant Kafka Cluster with Nurettin Omeroglu
Storage Capacity Management on Multi-tenant Kafka Cluster with Nurettin OmerogluHostedbyConfluent
 
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14AMD Developer Central
 
Apache Kafka Fundamentals for Architects, Admins and Developers
Apache Kafka Fundamentals for Architects, Admins and DevelopersApache Kafka Fundamentals for Architects, Admins and Developers
Apache Kafka Fundamentals for Architects, Admins and Developersconfluent
 
How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...
How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...
How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...StreamNative
 
Kafka High Availability in multi data center setup with floating Observers wi...
Kafka High Availability in multi data center setup with floating Observers wi...Kafka High Availability in multi data center setup with floating Observers wi...
Kafka High Availability in multi data center setup with floating Observers wi...HostedbyConfluent
 
Eventually, Scylla Chooses Consistency
Eventually, Scylla Chooses ConsistencyEventually, Scylla Chooses Consistency
Eventually, Scylla Chooses ConsistencyScyllaDB
 
Thrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased ComparisonThrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased ComparisonIgor Anishchenko
 
Introduction to Apache Kafka
Introduction to Apache KafkaIntroduction to Apache Kafka
Introduction to Apache KafkaJeff Holoman
 
Apache Kafka Introduction
Apache Kafka IntroductionApache Kafka Introduction
Apache Kafka IntroductionAmita Mirajkar
 
Akka-intro-training-public.pdf
Akka-intro-training-public.pdfAkka-intro-training-public.pdf
Akka-intro-training-public.pdfBernardDeffarges
 
Zero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with NettyZero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with NettyDaniel Bimschas
 
Trend Micro Big Data Platform and Apache Bigtop
Trend Micro Big Data Platform and Apache BigtopTrend Micro Big Data Platform and Apache Bigtop
Trend Micro Big Data Platform and Apache BigtopEvans Ye
 
Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...
Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...
Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...DataStax
 
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014Chen-en Lu
 
NATS Streaming - an alternative to Apache Kafka?
NATS Streaming - an alternative to Apache Kafka?NATS Streaming - an alternative to Apache Kafka?
NATS Streaming - an alternative to Apache Kafka?Anton Zadorozhniy
 

What's hot (20)

카프카, 산전수전 노하우
카프카, 산전수전 노하우카프카, 산전수전 노하우
카프카, 산전수전 노하우
 
Storage Capacity Management on Multi-tenant Kafka Cluster with Nurettin Omeroglu
Storage Capacity Management on Multi-tenant Kafka Cluster with Nurettin OmerogluStorage Capacity Management on Multi-tenant Kafka Cluster with Nurettin Omeroglu
Storage Capacity Management on Multi-tenant Kafka Cluster with Nurettin Omeroglu
 
The google MapReduce
The google MapReduceThe google MapReduce
The google MapReduce
 
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
 
Apache Kafka Fundamentals for Architects, Admins and Developers
Apache Kafka Fundamentals for Architects, Admins and DevelopersApache Kafka Fundamentals for Architects, Admins and Developers
Apache Kafka Fundamentals for Architects, Admins and Developers
 
How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...
How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...
How Pulsar Enables Netdata to Offer Unlimited Infrastructure Monitoring for F...
 
Kafka High Availability in multi data center setup with floating Observers wi...
Kafka High Availability in multi data center setup with floating Observers wi...Kafka High Availability in multi data center setup with floating Observers wi...
Kafka High Availability in multi data center setup with floating Observers wi...
 
Linux PV on HVM
Linux PV on HVMLinux PV on HVM
Linux PV on HVM
 
Eventually, Scylla Chooses Consistency
Eventually, Scylla Chooses ConsistencyEventually, Scylla Chooses Consistency
Eventually, Scylla Chooses Consistency
 
Building Paragon in UE4
Building Paragon in UE4Building Paragon in UE4
Building Paragon in UE4
 
Thrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased ComparisonThrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased Comparison
 
Introduction to Apache Kafka
Introduction to Apache KafkaIntroduction to Apache Kafka
Introduction to Apache Kafka
 
Apache Kafka Introduction
Apache Kafka IntroductionApache Kafka Introduction
Apache Kafka Introduction
 
Akka-intro-training-public.pdf
Akka-intro-training-public.pdfAkka-intro-training-public.pdf
Akka-intro-training-public.pdf
 
Zero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with NettyZero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with Netty
 
Trend Micro Big Data Platform and Apache Bigtop
Trend Micro Big Data Platform and Apache BigtopTrend Micro Big Data Platform and Apache Bigtop
Trend Micro Big Data Platform and Apache Bigtop
 
Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...
Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...
Apache Cassandra Multi-Datacenter Essentials (Julien Anguenot, iLand Internet...
 
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
Apache Kafka: A high-throughput distributed messaging system @ JCConf 2014
 
kafka
kafkakafka
kafka
 
NATS Streaming - an alternative to Apache Kafka?
NATS Streaming - an alternative to Apache Kafka?NATS Streaming - an alternative to Apache Kafka?
NATS Streaming - an alternative to Apache Kafka?
 

Similar to Event sourcing - what could possibly go wrong ? Devoxx PL 2021

Event Sourcing - what could go wrong - Jfokus 2022
Event Sourcing - what could go wrong - Jfokus 2022Event Sourcing - what could go wrong - Jfokus 2022
Event Sourcing - what could go wrong - Jfokus 2022Andrzej Ludwikowski
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEAndrzej Ludwikowski
 
Andrzej Ludwikowski - Event Sourcing - co może pójść nie tak?
Andrzej Ludwikowski -  Event Sourcing - co może pójść nie tak?Andrzej Ludwikowski -  Event Sourcing - co może pójść nie tak?
Andrzej Ludwikowski - Event Sourcing - co może pójść nie tak?SegFaultConf
 
Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?Andrzej Ludwikowski
 
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...Codemotion
 
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Anton Kirillov
 
Docker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionDocker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionBrennan Saeta
 
Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkLuciano Mammino
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive AppsJorge Ortiz
 
Immutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS LambdaImmutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS LambdaAOE
 
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...Zhenzhong Xu
 
Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...Docker, Inc.
 
GTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wildGTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wildOmer Iqbal
 
Lightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just RightLightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just Rightmircodotta
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Fabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkFabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkShashank Gautam
 
Anatomy of an action
Anatomy of an actionAnatomy of an action
Anatomy of an actionGordon Chung
 

Similar to Event sourcing - what could possibly go wrong ? Devoxx PL 2021 (20)

Event Sourcing - what could go wrong - Jfokus 2022
Event Sourcing - what could go wrong - Jfokus 2022Event Sourcing - what could go wrong - Jfokus 2022
Event Sourcing - what could go wrong - Jfokus 2022
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BE
 
Andrzej Ludwikowski - Event Sourcing - co może pójść nie tak?
Andrzej Ludwikowski -  Event Sourcing - co może pójść nie tak?Andrzej Ludwikowski -  Event Sourcing - co może pójść nie tak?
Andrzej Ludwikowski - Event Sourcing - co może pójść nie tak?
 
Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?
 
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
 
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
 
Docker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionDocker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline Execution
 
Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless framework
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive Apps
 
Immutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS LambdaImmutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS Lambda
 
Big Data Tools in AWS
Big Data Tools in AWSBig Data Tools in AWS
Big Data Tools in AWS
 
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
 
Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...
 
GTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wildGTS Episode 1: Reactive programming in the wild
GTS Episode 1: Reactive programming in the wild
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
 
Lightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just RightLightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just Right
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Fabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkFabric - Realtime stream processing framework
Fabric - Realtime stream processing framework
 
Anatomy of an action
Anatomy of an actionAnatomy of an action
Anatomy of an action
 

More from Andrzej Ludwikowski

Cassandra lesson learned - extended
Cassandra   lesson learned  - extendedCassandra   lesson learned  - extended
Cassandra lesson learned - extendedAndrzej Ludwikowski
 
Performance tests with Gatling (extended)
Performance tests with Gatling (extended)Performance tests with Gatling (extended)
Performance tests with Gatling (extended)Andrzej Ludwikowski
 
Stress test your backend with Gatling
Stress test your backend with GatlingStress test your backend with Gatling
Stress test your backend with GatlingAndrzej Ludwikowski
 

More from Andrzej Ludwikowski (7)

Performance tests - it's a trap
Performance tests - it's a trapPerformance tests - it's a trap
Performance tests - it's a trap
 
Cassandra lesson learned - extended
Cassandra   lesson learned  - extendedCassandra   lesson learned  - extended
Cassandra lesson learned - extended
 
Performance tests with Gatling (extended)
Performance tests with Gatling (extended)Performance tests with Gatling (extended)
Performance tests with Gatling (extended)
 
Stress test your backend with Gatling
Stress test your backend with GatlingStress test your backend with Gatling
Stress test your backend with Gatling
 
Performance tests with Gatling
Performance tests with GatlingPerformance tests with Gatling
Performance tests with Gatling
 
Cassandra - lesson learned
Cassandra  - lesson learnedCassandra  - lesson learned
Cassandra - lesson learned
 
Annotation processing tool
Annotation processing toolAnnotation processing tool
Annotation processing tool
 

Recently uploaded

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 

Recently uploaded (20)

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 

Event sourcing - what could possibly go wrong ? Devoxx PL 2021

  • 1. Event Sourcing what could possibly go wrong? Andrzej Ludwikowski
  • 2. About me ➔ ➔ ludwikowski.info ➔ github.com/aludwiko ➔ @aludwikowski ➔ academy.softwaremill.com
  • 7. SoftwareMill ● Hibernate Envers ● Alpakka Kafka ● Sttp ● Scala Clippy ● Quicklens ● MacWire
  • 8. What is Event Sourcing? DB Order { items=[itemA, itemB] }
  • 9. What is Event Sourcing? DB DB Order { items=[itemA, itemB] } ItemAdded(itemA) ItemAdded(itemC) ItemRemoved(itemC) ItemAdded(itemB)
  • 10. What is Event Sourcing? DB DB Order { items=[itemA, itemB] } ItemAdded(itemA) ItemAdded(itemC) ItemRemoved(itemC) ItemAdded(itemB)
  • 11. History ● 9000 BC, Mesopotamian Clay Tablets, e.g. for market transactions
  • 12. History ● 2005, Event Sourcing “Enterprise applications that use Event Sourcing are rarer, but I have seen a few applications (or parts of applications) that use it.”
  • 13. Why Event Sourcing? ● complete log of every state change ● debugging ● performance ● scalability ● microservices integration pattern
  • 14. ES and CQRS Client Query Service Data access Queries Read model Read model Read models Command Service Domain Events Commands
  • 15. ES and CQRS level 1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Transaction Command Service Domain Events Commands
  • 16. ES and CQRS level 1 ● Entry-level, synchronous & transactional event sourcing ● Implementing event sourcing using a relational database ● slick-eventsourcing
  • 17. ES and CQRS level 1 + easy to implement + easy to reason about + 0 eventual consistency - performance - scalability
  • 18. ES and CQRS level 2 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector Transaction Command Service Domain Events Commands
  • 19. ES and CQRS level 2 +/- performance +/- scalability - eventual consistency - increased events DB load ? - lags
  • 20. ES and CQRS level 3 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector Transaction event bus Command Service Domain Events Commands
  • 21. ES and CQRS level 3.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction Command Service Domain Events Commands
  • 22. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction Command Service Domain Events Commands
  • 23. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction At-least-once delivery Command Service Domain Events Commands
  • 24. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction
  • 25. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction
  • 26. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction
  • 27. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction
  • 28. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction
  • 29. ES and CQRS level 3.1.1 Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction ?
  • 30. ES and CQRS level 3.2 Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Command Service Domain Command Service Domain Command Service Domain Transaction ` Sharded Cluster
  • 31. ES and CQRS level 3.x + performance + scalability - eventual consistency - complex implementation - locking vs Single Writer
  • 32. ES and CQRS alternatives ● Change Capture Data (CDC) logging instead of event bus? ● event bus instead of DB?
  • 33. Not covered but worth to check ● Command Sourcing ● Event Collaboration
  • 34. ES implementation? ● custom ● library ● framework
  • 35. ES from domain perspective ● commands, events, state ● 2 methods on state ○ process(command: Command): List[Event] ○ apply(event: Event): State
  • 36. ES from application perspective ● snapshotting ● fail-over ● recover ● debugging ● sharding ● serialization & schema evolution ● concurrency access ● etc.
  • 37. import javax.persistence.*; import java.util.List; @Entity public class Issue { @EmbeddedId private IssueId id; private String name; private IssueStatus status; @OneToMany(cascade = CascadeType.MERGE) private List<IssueComment> comments; ... public void changeStatusTo(IssueStatus newStatus) { if (this.status == IssueStatus.DONE && newStatus == IssueStatus.NEW || this.status == IssueStatus.NEW && newStatus == IssueStatus.DONE) { throw new RuntimeException(String.format("Cannot change issue status from %s to %s", this.status, newStatus)); } this.status = newStatus; } ... }
  • 38. import javax.persistence.*; import java.util.List; @Entity public class Issue { @EmbeddedId private IssueId id; private String name; private IssueStatus status; @OneToMany(cascade = CascadeType.MERGE) private List<IssueComment> comments; ... public void changeStatusTo(IssueStatus newStatus) { if (this.status == IssueStatus.DONE && newStatus == IssueStatus.NEW || this.status == IssueStatus.NEW && newStatus == IssueStatus.DONE) { throw new RuntimeException(String.format("Cannot change issue status from %s to %s", this.status, newStatus)); } this.status = newStatus; } ... }
  • 39. import org.axonframework.commandhandling.* import org.axonframework.eventsourcing.* @Aggregate(repository = "userAggregateRepository") public class User { @AggregateIdentifier private UserId userId; private String passwordHash; @CommandHandler public boolean handle(AuthenticateUserCommand cmd) { boolean success = this.passwordHash.equals(hashOf(cmd.getPassword())); if (success) { apply(new UserAuthenticatedEvent(userId)); } return success; } @EventSourcingHandler public void on(UserCreatedEvent event) { this.userId = event.getUserId(); this.passwordHash = event.getPassword(); } private String hashOf(char[] password) { return DigestUtils.sha1(String.valueOf(password)); } }
  • 40. import akka.Done import com.lightbend.lagom.scaladsl.* import play.api.libs.json.{Format, Json} import com.example.auction.utils.JsonFormats._ class UserEntity extends PersistentEntity { override def initialState = None override def behavior: Behavior = { case Some(user) => Actions().onReadOnlyCommand[GetUser.type, Option[User]] { case (GetUser, ctx, state) => ctx.reply(state) }.onReadOnlyCommand[CreateUser, Done] { case (CreateUser(name), ctx, state) => ctx.invalidCommand("User already exists") } case None => Actions().onReadOnlyCommand[GetUser.type, Option[User]] { case (GetUser, ctx, state) => ctx.reply(state) }.onCommand[CreateUser, Done] { case (CreateUser(name), ctx, state) => ctx.thenPersist(UserCreated(name))(_ => ctx.reply(Done)) }.onEvent { case (UserCreated(name), state) => Some(User(name)) } } }
  • 42. import java.time.Instant import info.ludwikowski.es.user.domain.UserCommand.* import info.ludwikowski.es.user.domain.UserEvent.* import scala.util.{Failure, Success, Try} case class User (userId: UserId, name: String, email: Email, funds: Funds) { def process(command: UserCommand): Either[List[UserEvent]] = command match { case c: UpdateEmail => updateEmail(c) case c: DepositFunds => deposit(c) case c: WithdrawFunds => withdraw(c) ... } def apply(event: UserEvent): User = ??? //pattern matching }
  • 43. ES packaging ● snapshotting ● fail-over ● recover ● debugging ● sharding ● serialization & schema evolution ● concurrency access ● etc.
  • 44. ES packaging ● domain logic ● domain validation ● 0 ES framework imports
  • 45. library vs. framework ● Akka Persistence vs. Lagom ● Akka Persistence Typed
  • 46. Event storage ● file ● RDBMS ● Event Store ● MongoDB ● Kafka ● Cassandra
  • 47. Event storage for Akka Persistence ● file ● RDBMS ● Event Store ● MongoDB ● Kafka ● Cassandra
  • 48. akka-persistence-jdbc trap val theTag = s"%$tag%" sql""" SELECT "#$ordering", "#$deleted", "#$persistenceId", "#$sequenceNumber", "#$message", "#$tags" FROM ( SELECT * FROM #$theTableName WHERE "#$tags" LIKE $theTag AND "#$ordering" > $theOffset AND "#$ordering" <= $maxOffset ORDER BY "#$ordering" ) WHERE rownum <= $max"""
  • 49. akka-persistence-jdbc trap SELECT * FROM events_journal WHERE tags LIKE ‘%some_tag%’;
  • 50. Cassandra perfect for ES? ● partitioning by design ● replication by design ● leaderless (no single point of failure) ● optimised for writes (2 nodes = 100 000 tx/s) ● near-linear horizontal scaling
  • 51. ScyllaDB ? ● Cassandra without JVM ○ same protocol, SSTable compatibility ● C++ and Seastar lib ● up to 1,000,000 IOPS/node ● not fully supported by Akka Persistence
  • 52. Event serialization ● plain text ○ JSON ○ XML ○ YAML ● binary ○ java serialization ○ Avro ○ Protocol Buffers (Protobuf) ○ Thrift ○ Kryo
  • 53. Plain text Binary human-readable deserialization required
  • 54. Plain text Binary human-readable deserialization required precision issues (JSON IEEE 754, DoS) -
  • 55. Plain text Binary human-readable deserialization required precision issues (JSON IEEE 754, DoS) - storage consumption compress
  • 56. Plain text Binary human-readable deserialization required precision issues (JSON IEEE 754, DoS) - storage consumption compress slow fast
  • 57. Plain text Binary human-readable deserialization required precision issues (JSON IEEE 754, DoS) - storage consumption compress slow fast poor schema evolution support full schema evolution support
  • 58. Binary ● java serialization ● Avro ● Protocol Buffers (Protobuf) ● Thrift ● Kryo
  • 59. Binary ● java serialization ● Avro ● Protocol Buffers (Protobuf) ● Thrift ● Kryo
  • 60. Binary ● java serialization ● Avro ● Protocol Buffers (Protobuf) ● Thrift ● Kryo
  • 61. Binary ● java serialization ● Avro ● Protocol Buffers (Protobuf) ● Thrift ● Kryo
  • 62. Multi-language support ● Avro ○ C, C++, C#, Go, Haskell, Java, Perl, PHP, Python, Ruby, Scala ● Protocol Buffers (Protobuf) ○ even more than Avro
  • 65. ● backward - V2 can read V1 Full compatibility Application Events V1 V2
  • 66. ● forward - V2 can read V3 Full compatibility Application Events V1, V2 V2 Application Application V2 V3
  • 67. ● forward - V2 can read V3 Full compatibility Events Read model Read model Read models Projector V2 V3
  • 68. Schema evolution - full compatibility Protocol Buffers Avro Add field + (optional) + (default value) Remove field + + (default value) Rename field + + (aliases) https://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
  • 69. Protobuf schema management //user-events.proto message UserCreatedEvent { string user_id = 1; string operation_id = 2; int64 created_at = 3; string name = 4; string email = 5; } package user.application UserCreatedEvent( userId: String, operationId: String, createdAt: Long, name: String, email: String )
  • 70. Protobuf schema management package user.domain UserCreated( userId: UserId, operationId: OperationId, createdAt: Instant, name: String, email: Email ) extends UserEvent package user.application UserCreatedEvent( userId: String, operationId: String, createdAt: Long, name: String, email: String )
  • 71. Protobuf schema management ● def toDomain(event: UserCreatedEvent): UserEvent.UserCreated ● def toSerializable(event: UserEvent.UserCreated): UserCreatedEvent
  • 72. Protobuf schema management + clean domain - a lot of boilerplate code
  • 73. Avro schema management package user.domain UserCreated( userId: UserId, operationId: OperationId, createdAt: Instant, name: String, email: Email ) extends UserEvent { "type" : "record", "name" : "UserCreated", "namespace" : "info.ludwikowski.es.user.domain", "fields" : [ { "name" : "userId", "type" : "string" }, { "name" : "operationId", "type" : "string" }, { "name" : "createdAt", "type" : "long" }, { "name" : "name", "type" : "string" }, { "name" : "email", "type" : "string" } ] }
  • 74. Avro deserialization Bytes Deserialization Object Reader Schema Writer Schema
  • 75. Avro writer schema source ● add schema to the payload ● custom solution ○ schema in /resources ○ schema in external storage (must be fault-tolerant) ○ Darwin project ● Schema Registry
  • 76. Avro schema management package user.domain UserCreated( userId: UserId, operationId: OperationId, createdAt: Instant, name: String, email: Email ) extends UserEvent { "type" : "record", "name" : "UserCreated", "namespace" : "info.ludwikowski.es.user.domain", "fields" : [ { "name" : "userId", "type" : "string" }, { "name" : "operationId", "type" : "string" }, { "name" : "createdAt", "type" : "long" }, { "name" : "name", "type" : "string" }, { "name" : "email", "type" : "string" } ] }
  • 77. Protocol Buffers vs. Avro { "type" : "record", "name" : "UserCreated", "namespace" : "info.ludwikowski.es.user.domain", "fields" : [ { "name" : "userId", "type" : "string" }, { "name" : "operationId", "type" : "string" }, { "name" : "createdAt", "type" : "long" }, { "name" : "name", "type" : "string" }, { "name" : "email", "type" : "string" } ] } message UserCreatedEvent { string user_id = 1; string operation_id = 2; int64 created_at = 3; string name = 4; string email = 5; }
  • 78. Avro schema management + less boilerplate code +/- clean domain - reader & writer schema distribution
  • 79. Avro + less boilerplate code +/- clean domain - reader & writer schema distribution Protobuf + clean domain - a lot of boilerplate code
  • 80. Avro vs. Protocol Buffers ● The best serialization strategy for Event Sourcing
  • 81. Event payload ● delta event ● rich event (event enrichment) ● + metadata ○ seq_num ○ created_at ○ event_id ○ command_id ○ correlation_id
  • 82.
  • 83.
  • 84. State replay time ● snapshotting ● write-through cache
  • 86.
  • 87. Immutable vs. mutable state? ● add/remove ImmutableList 17.496 ops/s ● add/remove TreeMap 2201.731 ops/s
  • 89. Updating all aggregates User(id) Command(user_id) Event(user_id) Event(user_id) Event(user_id)
  • 94. Event + seq_no Event + seq_no Handling duplicates Events Read model Read model Read models Projector event bus Event + seq_no read model update + seq_no Events
  • 95. Broken read model Events ad model ead model Read models Projector event bus Events
  • 96. Broken read model Events ad model ead model Read models Projector event bus read model update + offset (manual offset management) Events
  • 97. Multi aggregate transactional update ● rethink aggregates boundaries ● compensating action ○ optimistic ○ pessimistic
  • 99. Pessimistic compensation action User account Cinema show charged
  • 100. Pessimistic compensation action User account Cinema show charged booked
  • 101. Pessimistic compensation action User account Cinema show charged booked sold out
  • 102. Pessimistic compensation action User account Cinema show charged booked booked sold out
  • 103. Pessimistic compensation action User account Cinema show charged booked booked sold out
  • 104. Pessimistic compensation action User account Cinema show charged booked booked sold out refund
  • 105. Optimistic compensation action User account Cinema show charged booked sold out
  • 106. Optimistic compensation action User account Cinema show booked booked sold out overbooked
  • 107. Optimistic compensation action User account Cinema show charged booked booked sold out overbooked ?
  • 108. Saga Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Updater event bus Transaction
  • 109. Saga - choreography Command Service Domain Events Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction
  • 110. Saga - orchestration Command Service Domain Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Transaction Command Service Domain Events Commands
  • 111. Saga ● should be persistable ● events order should be irrelevant ● time window limitation ● compensating action must be commutative
  • 112. Saga ● Sagas with ES ● DDD, Saga & Event-sourcing ● Applying Saga Pattern ● Microservice Patterns
  • 113. ES with RODO/GDPR ● “right to forget” with: ○ data shredding (and/or deleting) ■ events, state, views, read models ○ retention policy ■ message brokers, backups, logs ○ data before RODO migration
  • 114. ES and CQRS level 3.2 Events Client Query Service Data access Commands Queries Read model Read model Read models Projector event bus Command Service Domain Command Service Domain Command Service Domain Transaction Sharding Clustering
  • 115. Cluster = split brain 1 5 4 3 Load balancer 2
  • 116. Cluster = split brain 1 5 4 3 Load balancer 2 User(1) Command(1)
  • 117. Cluster = split brain 1 5 4 3 Load balancer 2
  • 118. Cluster = split brain 1 5 4 3 Load balancer 2 User(1)
  • 119. Cluster = split brain 1 5 4 3 Load balancer 2 User(1) Command(1) User(1)
  • 120. Cluster = split brain 1 5 4 3 Load balancer 2 User(1) Command(1) User(1) Command(1)
  • 121. Cluster best practises ● remember about the split brain ● very good monitoring & alerting ● a lot of failover tests ● cluster also on dev/staging ● keep it as small as possible (code base, number of nodes, etc.)
  • 122. Summary ● carefully choose ES lib/framework ● there is no perfect database for event sourcing ● understand event/command/state schema evolution ● eventual consistency is your friend ● scaling is complex ● database inside-out ● log-based processing mindset
  • 123. Want to learn more? ● Reactive Event Sourcing with Akka (Java/Scala) ● Akka Typed Fundamentals (Java/Scala) ● Akka Cluster ● Performance tests with Gatling
  • 124.
  • 126. Thank you and Q&A ➔ ➔ ludwikowski.info ➔ github.com/aludwiko ➔ @aludwikowski
  • 128. Thank you and Q&A ➔ ➔ ludwikowski.info ➔ github.com/aludwiko ➔ @aludwikowski