Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL

NatanSilnitsky 91 views 74 slides May 29, 2024
Slide 1
Slide 1 of 74
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62
Slide 63
63
Slide 64
64
Slide 65
65
Slide 66
66
Slide 67
67
Slide 68
68
Slide 69
69
Slide 70
70
Slide 71
71
Slide 72
72
Slide 73
73
Slide 74
74

About This Presentation

In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immu...


Slide Content

Beyond Event
Sourcing
May 2024
Embracing CRUD for Wix's High-Growth
Platform

Beyond Event Sourcing
Hi,
I’m Natan
Backend Infra Tech Lead @Wix
Yoga enthusiast
Speaker
Blogger
natansilnitsky
www.natansil.com
@NSilnitsky

Beyond Event Sourcing @NSilnitsky

Beyond Event Sourcing @NSilnitsky
~4B
Daily HTTP
Transactions
4000±
Microservices
in production
~70B
Kafka
messages a day

Beyond Event Sourcing @NSilnitsky
Agenda
Event sourcing & CQRS Framework for CRUD services
Dev velocity1
Scalability


2
Performance3
Resilience4
* stores

Beyond Event Sourcing @NSilnitsky
Event Sourcing & CQRS
Wix Stores Example

Beyond Event Sourcing @NSilnitsky
Add/Update product QueryProduct
Product Catalog

Beyond Event Sourcing @NSilnitsky
WriteProduct
Event sourcing and CQRS
Product 123:
Product Created1
Product Changed (price)2
Product Changed (description)3
Product Changed (stock-level)4
ReadProduct
Name
Price
Description
Stock-level
}
Append-Only
Events
Snapshot

Beyond Event Sourcing @NSilnitsky
Event
Store
CreateProduct:
Catalog Write API
Event sourcing and CQRS
Product Created

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS
Product 123:
Product Created1
Product Changed (price)2
Product Changed (description)3
Product Changed (stock-level)4
Event
Store
CreateProduct:
Catalog Write API
Product Created

Beyond Event Sourcing @NSilnitsky
Replay
GetProduct
Catalog Read API
Event sourcing and CQRS
Replay
events
Product 123:
Product Created1
Product Changed (price)2
Product Changed (description)3
Product Changed (stock-level)4
Event
Store
CreateProduct:
Catalog Write API
Product Created

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS – Advantages
Debug with
“time travel”
GetProduct
Catalog Read API
Replay
events
Product 123:
Product Created1
Product Changed (price)2
Product Changed (description)3
Product Changed (stock-level)4
Event
Store
CreateProduct:
Catalog Write API
Product Created

Beyond Event Sourcing @NSilnitsky
Product 123:
Product Created1
Product Changed (price)2
Product Changed (description)3
Product Changed (stock-level)4
…..5
Product Changed (stock-level)30
Event
Store
Event sourcing and CQRS

Beyond Event Sourcing @NSilnitsky
Product 123:
Product Created1
Product Changed (price)2
Product Changed (description)3
Product Changed (stock-level)4
…..5
Product Changed (stock-level)30
Event
Store
Product 123 Snapshot
Snapshot
Repository
Event sourcing and CQRS

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Advantages
Catalog Read API
Inventory
snapshot
Product
Snapshot
Product Created
Product Changed (price)2
Product Changed (description)3
Product Changed (stock-level)
Product 123:
1
4

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Product
DB
Create/Read Product
Catalog CRUD
Event
Store
CreateProduct:
Catalog Write API
Product Created
Product 123 Snapshot
Snapshot
Repository
Catalog Read API

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Product Created (price 4$)1
Product Changed (price 6$)2
Product 123:
Snapshot
Repository
Delayed
Product snapshot ConsumerCatalog Write API

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Product 123:
Snapshot
Repository
Product Created (price 4$)

1
Product snapshot ConsumerCatalog Write API
Product Changed2
Product Created (price 4$)1
Product Changed (price 6$)2 Delayed

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Product Changed (descriptionA)3
Product Changed (descriptionB)4
Product 123:
Snapshot
Repository
Product Created (price 4$)

1
Product Changed (descriptionB)2
Catalog Write API
Product Changed (descriptionA)3
Product Created (price 4$)1
Product Changed (price 6$)2 Delayed
Product snapshot Consumer

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Product Changed (descriptionA)3
Product Changed (descriptionB)4
Product 123:
Snapshot
Repository
Product Created (price 4$)1
Product 123 Snapshot
Product Changed (descriptionB)2
Product
4$
DescriptionA
Product Changed (descriptionA)3
Catalog Write API
Product Created (price 4$)1
Product Changed (price 6$)2 Delayed
Product snapshot Consumer

Beyond Event Sourcing @NSilnitsky
Read your own writes
Event sourcing and CQRS - Disadvantages

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Confetti Cannon events:
Product Changed (price -1$)
Read your own writes
Catalog Write API
Event
Store

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Confetti Cannon events:
Snapshot
Repository
Confetti Cannon
Snapshot
Physical Item
3$
DescriptionA
Product Changed (price -1$)
Read your own writes
Catalog Write API
Event
Store

Beyond Event Sourcing @NSilnitsky
Event sourcing and CQRS - Disadvantages
Confetti Cannon events:
Snapshot
Repository
Confetti Cannon
Snapshot
Physical Item
3$
DescriptionA
Product Changed (price -1$)
Read your own writes
Catalog Write API
Event
Store
Product Changed (price -1$)
+

Beyond Event Sourcing @NSilnitsky
Product
DB
Update Product
Catalog CRUD
Event sourcing and CQRS - Disadvantages
Read your own writes

Beyond Event Sourcing @NSilnitsky
Read your own writes
Event sourcing and CQRS - Disadvantages

Beyond Event Sourcing
Event sourcing and
CQRS -
Disadvantages
Complexity
Eventual consistency only
Massive scale
Corrupted snapshot
Read your own writes

Beyond Event Sourcing @NSilnitsky
APIs
+
Standardization

Beyond Event Sourcing @NSilnitsky
RPC
Product Catalog API
Cart
Service
Internal Wix
Developer
Open Platform - API First
* Center 4000, clear,
focused, comprehensive

Beyond Event Sourcing @NSilnitsky
HTTP/SDK
Product Catalog API
Internal Wix
Developer
PoS
App
External App
Developer
Open Platform - API First

Beyond Event Sourcing @NSilnitsky
JavaScript
method
Product Catalog API
Internal Wix
Developer
Custom
Filter
External App
Developer
External Wix Site
Developer (Velo)
Open Platform - API First

Beyond Event Sourcing @NSilnitsky
Product Catalog API
Internal Wix
Developer
External App
Developer
External Wix Site
Developer (Velo)
Open Platform - API First
* CRUD on ES, consistent,
hard in standard way. Users
fast experience

Beyond Event Sourcing @NSilnitsky
Stores
Bookings
Events
Forms
Loyalty
Rewards
Tickets Policies
Checkout
Time
Slots
Schemas
Sub
missions
Guests
Coupons
Calendar
Orders
Waitlist
CartCatalog
Programs
Open Platform - API First
Internal Wix
Developer
External App
Developer
External Wix Site
Developer (Velo)

Beyond Event Sourcing @NSilnitsky
Wix’s Open Platform
CRUD

Event sourcing
Was
Independent
“startups”
Now
Single Open
Platform

Beyond Event Sourcing @NSilnitsky
Wix’s Open Platform
CRUD

Event sourcing
API First
APIs - TDD
+
FE driven
Was
Independent
“startups”
Now
Single Open
Platform

Beyond Event Sourcing
Framework for
CRUD services

Open Platform
API Schema
Validations & Permissions
Scaffold
Persistence + Event publishing
Data projections (Queries)

Beyond Event Sourcing @NSilnitsky
CreateProduct
Product
Document Store
Catalog API
Product Catalog - CRUD
ReadProduct
UpdateProduct
DeleteProduct
Unified!

Beyond Event Sourcing @NSilnitsky
CreateProduct
ReadProduct
UpdateProduct
DeleteProduct
Catalog API
API First - platformized CRUD

Beyond Event Sourcing @NSilnitsky
CreateProduct
ReadProduct
UpdateProduct
DeleteProduct
Catalog API
API First - platformized CRUD

Beyond Event Sourcing @NSilnitsky
CreateProduct
ReadProduct
UpdateProduct
DeleteProduct
Catalog API
service ProductService {
option (service_entity).message = "...v3.Product";

rpc CreateProduct (CreateProductRequest) returns
(CreateProductResponse) ...
rpc GetProduct (GetProductRequest) returns
(GetProductResponse) ...
rpc UpdateProduct (UpdateProduct) returns (UpdateProduct)
...

}

message Product {
option (entity) = {fqdn: "...v3.product"};
google.protobuf.StringValue id = 1;
google.protobuf.Int64Value revision = 2;
...
repeated Inventory inventory = 25;
...
}


API First - platformized CRUD

Beyond Event Sourcing @NSilnitsky
API First - platformized CRUD
CreateProduct
ReadProduct
UpdateProduct
DeleteProduct
Catalog API
service ProductService {
option (service_entity).message = "...v3.Product";

rpc CreateProduct (CreateProductRequest) returns
(CreateProductResponse) ...
rpc GetProduct (GetProductRequest) returns
(GetProductResponse) ...
rpc UpdateProduct (UpdateProduct) returns (UpdateProduct)
...

}

message Product {
option (entity) = {fqdn: "...v3.product"};
google.protobuf.StringValue id = 1;
google.protobuf.Int64Value revision = 2;
...
repeated Inventory inventory = 25;
...
}

Beyond Event Sourcing @NSilnitsky
API First - platformized CRUD

Beyond Event Sourcing @NSilnitsky
API First - platformized CRUD

Beyond Event Sourcing @NSilnitsky
Event Driven Architecture
Automatic Domain Events FTW

Beyond Event Sourcing @NSilnitsky
EDA - Domain Events
CreateProduct
UpdateProduct
DeleteProduct
Product Created
Product Updated
Product Deleted
Product
Document Store
Catalog Service
* DE describes…

Beyond Event Sourcing @NSilnitsky
EDA - Domain Events
CreateProduct
UpdateProduct
DeleteProduct
Product Created
Product Updated
Product Deleted
Catalog Service
Product
SDL
* SDL is
document based.
no direct SQL

Beyond Event Sourcing @NSilnitsky
EDA - Domain Events
CreateProduct
UpdateProduct
DeleteProduct
Product Created
Product Updated
Product Deleted
Catalog Service
Product
SDL
* SDL is
document based.
no direct SQL

sdl.insert(request.getProduct.mapTo[ProductDomain])

Beyond Event Sourcing @NSilnitsky
EDA - Domain Events
CreateProduct
UpdateProduct
DeleteProduct
Product Created
Product Updated
Product Deleted
Product
SDL
Catalog Service
Product
SDL


sdlBuilder =
_.withDomainEventsEnabled(_.mapTo[Product])

Beyond Event Sourcing @NSilnitsky
EDA - Domain Events
Data
warehouse/Lake
CreateProduct
UpdateProduct
DeleteProduct
Product Created
Product Updated
Product Deleted
Catalog Service
Product
SDL
* debugging
corruption

Beyond Event Sourcing @NSilnitsky
EDA - Domain Events
ebay-bridge Service
CreateProduct
UpdateProduct
DeleteProduct
Catalog Service
Product Created
Product Updated
Product Deleted
Product
SDL

Beyond Event Sourcing @NSilnitsky
EDA - Domain Events
CreateProduct
UpdateProduct
DeleteProduct
Product Created
Product Updated
Product Deleted
Catalog Service
Product
SDL

Beyond Event Sourcing @NSilnitsky
Data consistency in Wix’s EDA
Resilient Producers and consumers

Beyond Event Sourcing @NSilnitsky
Make DB Update & Event Producing Atomic
Catalog
Service
Ebay Bridge
Service
* atomic,
otherwise

Beyond Event Sourcing @NSilnitsky
Produce event to S3
Resilient Producer
Catch Unsent Events
Catalog Service

Beyond Event Sourcing @NSilnitsky
Produce
to Kafka
Poll
Produce event to S3
Resilient Producer
Fallback to S3 and Heal
Catalog Service Healer Service

Beyond Event Sourcing @NSilnitsky
Consumer retries + DLQ
Make DB Update & Event Producing Atomic
Catalog
Service
Ebay Bridge
Service

Beyond Event Sourcing @NSilnitsky
Alternative - use outbox pattern and/or CDC
Transaction
Outbox Table
Insert
Product Table
Insert
Update
Delete
Database
Instant read-your-own-writes
consistency in Catalog service
Write to
database
CDC
Read from
Outbox Table
Kafka
Connect
Debezium
connector
Publishes
messages
to brokers
Kafka
Broker
Eventually consistent data
exchange with Ebay Bridge Service
Catalog
Service
Ebay Bridge Service

Beyond Event Sourcing @NSilnitsky
Data Projection &
query optimization
Materializer

Beyond Event Sourcing @NSilnitsky
Query latency - naive
CreateProduct
ReadProduct
DeleteProduct
Catalog Service
Product
SDL
FilterProductWithInventory
Inventory Service
Inventory
SDL
RPC
1
2

Beyond Event Sourcing @NSilnitsky
Multi-step
Query latency - naive
CreateProduct
ReadProduct
DeleteProduct
Catalog Service
Product
SDL
FilterProductWithInventory
Inventory Service
Inventory
SDL
RPC
price < 100 and stock > 4



2



1

Beyond Event Sourcing @NSilnitsky
Query latency - DB join
CreateProduct
ReadProduct
DeleteProduct
Catalog Service
Product
SDL
FilterProductWithInventory
Inventory Service
Inventory
SDL
DB level Join

Beyond Event Sourcing @NSilnitsky
Query Latency - Materializer
Product +
Inventory
Materializer
Inventory
Inventory updated Event
Catalog
Service
Inventory
Service
FilterProductWithInventory

Beyond Event Sourcing @NSilnitsky
Simplicity
Onboarding new team member
Write performance
Read performance
consistency
Audit log/time machine
Projections/queries
Comparing Event sourcing
to Wix’s CRUD based solution
Event Sourcing
CRUD
SDL+Domain Events
Materializer

Beyond Event Sourcing @NSilnitsky
Simplicity
Onboarding new team member
Write performance
Read performance
consistency
Audit log/time machine
Projections/queries
Comparing Event sourcing
to Wix’s CRUD based solution
Event Sourcing
CRUD
SDL+Domain Events
Materializer

Beyond Event Sourcing @NSilnitsky
Simplicity
Onboarding new team member
Write performance
Read performance
consistency
Audit log/time machine
Projections/queries
Comparing Event sourcing
to Wix’s CRUD based solution
Event Sourcing
CRUD
SDL+Domain Events
Materializer

Beyond Event Sourcing @NSilnitsky
Simplicity
Onboarding new team member
Write performance
Read performance
consistency
Audit log/time machine
Projections/queries
Comparing Event sourcing
to Wix’s CRUD based solution
Event Sourcing
CRUD
SDL+Domain Events
Materializer

Beyond Event Sourcing @NSilnitsky
Simplicity
Onboarding new team member
Write performance
Read performance
consistency
Audit log/time machine
Projections/queries
Comparing Event sourcing
to Wix’s CRUD based solution
Event Sourcing
CRUD
SDL+Domain Events
Materializer
* no consistency

Beyond Event Sourcing @NSilnitsky
Simplicity
Onboarding new team member
Write performance
Read performance
consistency
Audit log/time machine
Projections/queries
Comparing Event sourcing
to Wix’s CRUD based solution
Event Sourcing
CRUD
SDL+Domain Events
Materializer

Beyond Event Sourcing @NSilnitsky
Simplicity
Onboarding new team member
Write performance
Read performance
consistency
Audit log/time machine
Projections/queries
Comparing Event sourcing
to Wix’s CRUD based solution
Event Sourcing
CRUD
SDL+Domain Events
Materializer

Beyond Event Sourcing @NSilnitsky
Summary
Wix successfully shifted its vast distributed system entirely to
CRUD-based microservices, moving away from a CRUD/event sourcing
hybrid.

.
.
.

Beyond Event Sourcing @NSilnitsky
Summary
Wix successfully shifted its vast distributed system entirely to
CRUD-based microservices, moving away from a CRUD/event sourcing
hybrid.

This transformation was driven by a commitment to standardization,
managed infrastructure with automated code generation, and a
decoupled architecture.

Beyond Event Sourcing @NSilnitsky
Summary
Advanced tools were also implemented to boost development speed,
ensure system resilience, and optimize for scale and performance.
Domain Events
Resilient Producer Materializer
Simple Data Layer

Beyond Event Sourcing
Q & A
Thank you
natansilnitsky www.natansil.com @NSilnitsky
?????? slideshare.net/NatanSilnitsky

Q & A
www.natansil.com
@NSilnitsky