17. Stack Example - communication
● Kafka - distributed pub/sub
● AngularJS - js framework with good
ansychronous mechanisms
● Vert.X - asynchronous web
communication
● RxJava - Reactive view changes
18. Stack Example - db solutions
● any db you need
● Cassandra - extremely fast writes and
pretty fast reads
● MongoDB - fast document store
● Akka Persistence - great
implementation of Event Sourcing
19. Key Takeaways
● As always - “right tool for the job”
● Build your views asynchronously
● Consider what is the best model for
each query and each command
● Consider your consistency and
performance requirements
20. Mandatory Links Slide
● https://cqrs.wordpress.com/ - not updated,
but interesting read
● http://martinfowler.com/bliki/CQRS.html -
Martin Fowler on CQRS
● http://www.axonframework.org/
● http://en.jdon.com/
Witajcie. Jestem Zbyszko. Pracuję w Allegro jako architekt rozwiązań. Chciałbym dziś z Wami porozmawiać o pewnym popularnym wzorcu o nazwie CQRS. Chcę Wam pokazać przykładowy diagram opisującą dość klasyczny przypadek, opowiedzieć trochę o zyskach i problemach związanych z CQRS, a także opisać pokrótce kilka narzędzi ułatwiających pracę z CQRS, także odnosząc się do mojego doświadczenia w temacie. Wzorzec ten może wydać się Wam w wielu miejscach znajomy, mam nadzieje jednak, że moja prezentacja pozwoli Wam uzyskać większą świadomość wykorzystaniu go w pracy codziennej.
CRUDa każdy zna - Create Read Update Delete
CRUD jest łatwy
ale mało elastyczny
nasze dane rzadko od razu wyglądają tak jak chcemy
zwykle bazy dające nam swobodę modelowania nie są szybkie, szybkie nie dają swobody modelowania
Oparta o koncepcję Command–query separation - Bertranda Meyera
Koncepcję rozwinął Greg Young do formy Command Query Responsibility Segregation
Duży wkład w rozpropagowanie idei ma do dziś Martin Fowler
Każda metoda jest albo poleceniem (Command) albo zapytaniem (Query)
Polecenia i zapytania są od siebie fizycznie oddzielone
Zarówno procesy jak i model są oddzielne
Basic assumption - View does not to be 100% accurate 100% of the time (in any case, it rarely is)
Query - Getting data for some purpose (e.g. page rendering)
Command - instruction for data update
Autonomous Component - component seperate from other components in the system
There must be some way to synchronize autonomous components
Query call are most of the times synchronous
Commands don’t have to - but it would be great to handle events about execution
Simple way to synchronize querable components - events
Autonomous components do not share model or backends
Query Model should be optimized for queries - denormalization and lack of typical relations (as in RDBMS) is normal!
Domain model represents the abstraction of our knowledge about the domain and can have completely different performance requirements
QueryDB is not mandatory - can be replaced by a caching solution
CQRS używamy przede wszystkim wtedy, kiedy
model zapytań się różni od modelu domenowego
mamy różne wymagania wydajnościowe wobec zapytań i zapisów
możemy pozwolić sobie na system ostatecznie spójny
Nie jesteśmy ograniczeni ilością w tym modelu - usług widokowych może być więcej, mogą też reprezentować więcej niż jeden model tej samej informacji
Nic nie stoi na przekodzie żeby polecenie miały oddzielne modele poleceń
Nie jest to styl transakcyjny!
Polecenia i zapytania są od siebie fizycznie oddzielone
Zarówno procesy jak i model są oddzielne
Model zapytań może bardzo dokładnie odwzorowywać nasze zapotrzebowanie
system lokalnie może być prostszy, ale globalnie jest bardziej złożony
synchronizacja stanowi narzut jeśli chodzi o globalną złożoność
model odwzorowujący lokalny potrzebę zmniejsza lokalną złożoność
Co daje nam CQRS już mniej więcej opowiedzieliśmy, ale to nie wszystko
Nie tyle zysk co sposób uzyskania CQRS -
Na podstawie eventów odwzorowujemy kształt w naszym systemie
event powinien posiadać nową wartość po update
zwykle są mechanizmy na odzyskanie ich w razie awarii node’a
Rodzaj UI który rozdziela funkcjonalności na pojedynczej stronie na odseparowane od siebie procesy
Przykład - Dokumenty Google’a, Gmail (drafty tworzone są na bieżąco)
Wszystkie polecenia idą asynchronicznie, ale istnieją mechanizmy sprawdzające (i wyświetlające!) czy polecenie się udało (“All changes saved in Drive”)
Oczywiście inne widoki (strony) nie zawsze będą 100% na bieżąco, ale zwykle trwa to na tyle mało czasu, że nie robi to różnicy
Czy istnieją rozwiązania wspomagające?
Istnieją frameworki wspomagające implementację CQRS - Axon czy Jdon
Nie ma potrzeby budowania frameworków CQRS - jest to styl architektoniczny, można go zaimplementować używając tego co akurat potrzebujesz
Kafka - świetna metoda powiadamiania innych komponentów o zmianach
AngularJS ułatwia asynchroniczną komunikację z frontendem (pozwala na to nawet JS, angularJS pozwala to obudować w wygodne struktrury)
Vert.x - jego częścią jest niezły mechanizm komunikacyjny, pozwalający nawet na komunikację z przeglądarków użytkownika za pomocą WebSocketów
RxJava - programowanie reaktywne dobrze wpasowuje się w ideę asynchronicznej komunikacji
Jaką bazę potrzebujesz, taką użyj
Cassandra - świetna baza jeśli musisz naprawdę dużo pisać
Mongo DB - jsonowatość bazy pozwala na dobre odwzorowanie danych widokowych, a także szybką modyfikację jej części
Akka Persisistence - świetny mechanizm do implementacji Event Sourceingu - pozwala nie tylko na zapisywanie zdarzeń do wybranej bazy, ale także tworzenie snapshotów (nawet w kompletnie innej, lepiej nadającej się do celu, bazie)
Używaj właściwego narzędzia - czy jest nim framework, system kolejkowy czy baza danych
Staraj się budować swoje widoki tak, żeby najrzadziej musiały się dobijać do innych komponentów systemu, dostarczając im dane w sposób asynchroniczny
Tak samo jak w pierwszym punkcie - myśl lokalnie o reprezentacji swoich danych - nie ma powodu dla którego model widoku czy poleceń nie może być dokładnie taki jaki potrzebujesz
CQRS nie jest dla każdej sytuacji - weź pod uwagę jakie masz wymagania dotyczące spójności i wydajności dostępu do danych
Rodzaj UI który rozdziela funkcjonalności na pojedynczej stronie na odseparowane od siebie procesy
Przykład - Dokumenty Google’a, Gmail (drafty tworzone są na bieżąco)
Wszystkie polecenia idą asynchronicznie, ale istnieją mechanizmy sprawdzające (i wyświetlające!) czy polecenie się udało (“All changes saved in Drive”)
Oczywiście inne widoki (strony) nie zawsze będą 100% na bieżąco, ale zwykle trwa to na tyle mało czasu, że nie robi to różnicy