SACC2017 - Huodongjia.com · • CQRS • Lagom in a nut shell ... ES + CQRS SACC2017. Lagom SACC2017.
CQRS EventStore
-
Upload
kiev-altnet -
Category
Technology
-
view
2.756 -
download
1
Transcript of CQRS EventStore
![Page 1: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/1.jpg)
CQRS with
JOliver Event Store
v3
![Page 2: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/2.jpg)
Дорога к CQRS
![Page 3: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/3.jpg)
GUIDatabase
accessBusiness
logicGUI
Database accessBusiness
logic
GUI
GUI
Database access
GUIDatabase accessBusiness
logic
GUI
GUI Database access
Business logic
GUI
Business logic
Business logicGUIDatabase access
![Page 4: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/4.jpg)
GUI
Business logic
Data access
![Page 5: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/5.jpg)
M$$SQL
GUI
Domain Model
ORM
Database
![Page 6: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/6.jpg)
M$$SQL
GUI
Domain Model
ORM
Database
Lazy Loading !!! OUCH!
![Page 7: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/7.jpg)
M$$SQL
GUI
Domain Model
ORM
Database
DTO
![Page 8: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/8.jpg)
M$$SQL
GUI
Domain Model
ORM
Database
DTO
Object-To-Object Mapping !!!
OUCH!
![Page 9: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/9.jpg)
RDB
ORM
Отчеты
Domain
8-ми этажный SQL
![Page 10: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/10.jpg)
А ручки то, на что?
![Page 11: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/11.jpg)
RDB
Ручками
Отчеты
N этажный SQL(правда, почище и побыстрее, чем с ORM)
SQL красиво упрятан за фасадом
хранимых процедур
![Page 12: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/12.jpg)
RDB
DTO
Handcrafted SQL
ORM
Application Services
Domain Object
Domain Object
Reporting Services
3NF with optimizations like 1NF
in some places
DTO DTO DTO
Form UI Reports UI
send
request
![Page 13: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/13.jpg)
RDB
DTO
Handcrafted SQLORM
Application Services
Domain Object
Reporting Services
DTO DTO DTO
Form UI Reports UI
Здесьжирненько
![Page 14: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/14.jpg)
И что дальше?
![Page 15: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/15.jpg)
Data Storage
Command
Application Services
Domain Object
Query Services
Client
Domain Object
Query
Data Storage
DTO DTO
CQRS (did you mean “Cars”?)
![Page 16: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/16.jpg)
Domain Model View Model
Как синхронизировать ?
![Page 17: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/17.jpg)
ORMDomain Changeset Denormalizer
View Model
Потеря «сути» изменений
Непрозрачный сгусток данных
![Page 18: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/18.jpg)
CQRS+
Event Sourcing =
LOVE!
![Page 19: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/19.jpg)
ORMDomain
Storage
Текущее состояние
Традиционный подход
![Page 20: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/20.jpg)
Domain InvoiceCreated
InvoiceApproved
Invoice Finalized
Журнал всех изменений
Event Sourcing
![Page 21: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/21.jpg)
Традиционный подход
![Page 22: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/22.jpg)
Event Sourcing
![Page 23: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/23.jpg)
SRP на уровне метода !
Принятие решения о возможности
перехода состояния(бизнес-правила)
Переход состояния(транзитор)
Собственно, изменение состояния(аппликатор)
![Page 24: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/24.jpg)
И как это работает?
Ну и как это всё работает?
![Page 25: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/25.jpg)
Восстановление текущего состояния
InvoiceCreated
InvoiceApproved
Invoice Finalized
Журнал изменений
1
2
3
![Page 26: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/26.jpg)
Сохранение изменений
InvoiceApproved
Invoice Finalized
Буфер
![Page 27: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/27.jpg)
Сохранение изменений
InvoiceApproved
Invoice Finalized
Буфер
InvoiceCreated
Журнал изменений
1append
2Invoice
Approved
Invoice Finalized3
![Page 28: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/28.jpg)
Log.append(id, events)
events = Log.read(id)
Тривиально, неправда ли?
![Page 29: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/29.jpg)
Обеспечение параллельного доступа
![Page 30: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/30.jpg)
Параллельные модификации
InvoiceCreated
InvoiceUpdated
Invoice Finalized
update
Invoice
finalize
![Page 31: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/31.jpg)
Оптимистическая блокировка
InvoiceCreated
Stream [ID:542]
1InvoiceCreated
Invoice[ID:542]
1load Invoice
Created
Invoice[ID:542]
1load
1
![Page 32: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/32.jpg)
Оптимистическая блокировка
InvoiceCreated
Stream [ID:542]
1
2 InvoiceFinalized
load InvoiceCreated
Invoice[ID:542]
1
2 InvoiceFinalized
load
store
1
2
originalRevision = currentRevison
InvoiceCreated
Invoice[ID:542]
1
![Page 33: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/33.jpg)
Оптимистическая блокировка
InvoiceCreated
Stream [ID:542]
1
2 InvoiceFinalized
22InvoiceUpdated
load
store
InvoiceCreated
Invoice[ID:542]
1
2 InvoiceFinalized
load
store
1
2
InvoiceCreated
Invoice[ID:542]
1
originalRevision != currentRevison
![Page 34: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/34.jpg)
Допустимые параллельные модификации
Transaction Posted
Transaction Posted
Transaction Posted
post
General Ledger
post
Трекать ревизию аггрегата
недостаточно
![Page 35: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/35.jpg)
Высокая производительность
![Page 36: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/36.jpg)
Минимальное количество операций записи
E1
Aggregate StreamCommit
E1 E1pack
C1serialize
![Page 37: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/37.jpg)
Минимальное количество операций записи
Commit
E1
Aggregate
E2
E3
E2
E3
Stream
C2
E2
E3
Commit
E1 E1pack
pack
C1serialize
serialize
![Page 38: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/38.jpg)
Гибкие возможности сериализации
• JSON• Binary• Custom (ProtoBuf, .NET, whatever)
• GZip• Криптование
![Page 39: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/39.jpg)
Оптимизация операции восстановления состояния при помощи «снимков»
Аггрегат с очень
длинным жизненным
циклом и кучей ивентов
E1
E2
…
E100500
Snapshot[rev: E100500]
E100501
restore
replay the restof events
![Page 40: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/40.jpg)
Распределенная транзакция
С1 С2 .. Сn
Command Queue
Command Processor
Event Store
dequeue (C1)
store (E1, E2)
MSDTC
![Page 41: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/41.jpg)
Без 2PC
С1 С2 .. Сn
Command Queue
Command Processor
Event Store
0. peek (C1)
1. store (E1, E2)
2. remove (C1) T2
T1
![Page 42: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/42.jpg)
Без 2PC необходима поддержка идемпотентности
С1 С2 .. Сn
Command Queue
Command Processor
Event Store
0. peek (C1)
1. store (С1, [E1, E2]) 2. dup (С1)
4. remove (С1)
Commit
E1
E2
![Page 43: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/43.jpg)
Без 2PC необходима поддержка идемпотентности
С1 С2 .. Сn
Command Queue
Command Processor
Event Store
0. peek (C1)
1. store (С1, [E1, E2]) 2. dup (С1)
4. remove (С1)
Commit
E1
E2
ID : UUID
![Page 44: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/44.jpg)
Без 2PC необходима поддержка идемпотентности
С1 С2 .. Сn
Command Queue
Command Processor
Event Store
0. peek (C1)
1. store (С1, [E1, E2]) 2. dup (С1)
4. remove (С1)
Commit
E1
E2
ID : UUID
Command
ID : UUID
![Page 45: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/45.jpg)
Обработка событий
Event Store
View Model
E1 E2publish update
2PC, опять?
![Page 46: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/46.jpg)
Обработка событий (PULL)
Event Store
View Model
Get new events since (Time)
Запоминать последнее
обработанное событие
![Page 47: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/47.jpg)
Обработка событий (PULL)
Event Store
View Model
Get new events since (Time)
Commit
E1
E2
ID : UUID
![Page 48: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/48.jpg)
Обработка событий (PULL)
Event Store
View Model
Get new events since (Time)
Commit
E1
E2
ID : UUID
Dispatched : bool
![Page 49: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/49.jpg)
Обработка событий (PULL)
Event Store
View Model
Get undispatched events
Commit
E1
E2
ID : UUID
Dispatched : boolmark as
dispatched
![Page 50: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/50.jpg)
Обработка событий (PUSH)
Event Store
View Model
publish (commit)
Commit
E1
E2
ID : UUID
Dispatched : boolИдемпотентность во
View Model хранилище по-
прежнему нужна mark as
dispatched
![Page 51: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/51.jpg)
Встроенный диспетчер событий
BUS
Command Processor
Event Store
cmd
events
commit
Dispatcher
EventPublisher
commit
events
Storage
Your App
commit mark as dispatched
OK
![Page 52: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/52.jpg)
Встроенный диспетчер событий
BUS
Command Processor
Event Store
cmd
events
commit
Dispatcher
EventPublisher
commit
events
Storage
Your App
commit
dispatched = false
FAIL
![Page 53: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/53.jpg)
Архитектура
![Page 54: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/54.jpg)
CommitEvent Store
Persistence Engine
Event Stream Commit
Event MessageDispatche
r
Storage
![Page 55: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/55.jpg)
Поддерживаемые технологии хранилища данных
Relational Databases:
• SQL Server 2005 (or later)• MySQL• Firebird• Oracle (planned)
Embedded Relational Databases:• SQL Server CE 3.5 (or later)• SQLite 3.0 (or later)• MS Access 2000 (or later)
Cloud-based Databases:• MS SQL Azure• Amazon RDS (MySQL)• Azure Tables/Blobs (in progress)
• Amazon SimpleDB/S3 (in progress)
Document Databases• RavenDB r322 (or later)• MongoDB 1.6 (or later)• CouchDB 1.0 (planned)
![Page 56: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/56.jpg)
Расширяемость
![Page 57: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/57.jpg)
Метаданые
Commit
Event Message
Dictionary<string, object>
Dictionary<string, object>
Office, User, PrecedingMessageId
EventId, AggregateType
![Page 58: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/58.jpg)
Хуки
Event Store
Persistence Engine
Commit
Место для “врезки” в конвейер обработки
Hook into:• select• pre-commit• post-commit
![Page 59: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/59.jpg)
Хуки
![Page 60: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/60.jpg)
Диспатчер – это встроенный хук
![Page 61: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/61.jpg)
Механизмы эволюции схемы событий
![Page 62: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/62.jpg)
2 подхода
• Толерантный сериализатор
• Явное версионирование
![Page 63: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/63.jpg)
Свалка аппликаторов в бизнес-аггрегате
![Page 64: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/64.jpg)
Преемственность версий
InvoiceCreated
InvoiceCreated_v2
InvoiceCreated_v3
convert to
convert to
![Page 65: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/65.jpg)
Хук-конвертер в Event Store
![Page 66: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/66.jpg)
Проект CommonDomain
![Page 67: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/67.jpg)
Базовый класс для Аггрегатов
![Page 68: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/68.jpg)
Репозиторий - DAO для Аггрегатов
![Page 69: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/69.jpg)
Обработка конфликтов параллельного доступа
![Page 70: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/70.jpg)
Допустимые параллельные модификации
Transaction Posted
Transaction Posted
Transaction Posted
post
General Ledger
post
![Page 71: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/71.jpg)
Легко создавать специализированные политики определения конфликтов параллельных изменений
![Page 72: CQRS EventStore](https://reader035.fdocuments.net/reader035/viewer/2022062300/55878cdfd8b42a485d8b45c1/html5/thumbnails/72.jpg)
Ссылочки:
• http://cqrs.wordpress.com• https://github.com/joliver/EventStore• https://github.com/joliver/CommonDomain