Oskar Dudycz

Pragmatycznie o programowaniu

A gdybym Ci powiedział, że bazy relacyjne to tak naprawdę Event Store'y?

2020-06-08 oskar dudyczEvent Sourcing

cover

Cześć!

Wiele osób twierdzi, że Event Sourcing to podejście oderwane od rzeczywistości. Mamy bazy relacyjne, nie ma co kombinować. A co gdybym Ci powiedział, że bazy relacyjne (nosql w sumie też) działają na zasadzie Event Sourcingu?

Przypomnijmy sobie najpierw jak działa Event Sourcing. Źródłem prawdy w nim jest log zdarzeń. Wynikiem każdej operacji biznesowej są zdarzenia. Gdy zostaną zapisane to na ich podstawie możemy odbudować nasze modele odczytu (projekcje, snapshoty itd.). Co więcej dlatego naszym źródłem prawdy są zdarzenia to równie dobrze możemy usunąć te read modele i odbudować go na podstawie zdarzeń.

Bazy relacyjne (i ogólnie bazy danych) mają koncepcję zwaną “Write-Ahead Log” (WAL) (w MSSQL zwaną “Transaction Log”). Co to jest? Jest to struktura danych, która przechowuje wszystkie operacje zachodzące w transakcjach (np. dodaj rekord do tabeli projektów, zaktualizuj rekord zadania, usuń rekord użytkownika). W momencie gdy robimy zapis transakcji to dane są najpierw w nim, potem są aplikowane dopiero na tabele, indeksy itd. Stąd też nazwa “Write-Ahead” - od tego zapisu z wyprzedzeniem. Dlaczego działa to w sposób?

Zejdźmy jeszcze niżej. Dane w bazie danych to nic innego niż fizyczne pliki zapisane na dysku. Różnią się formatem w zależności od rodzaju bazy danych, ale koniec końców muszą zostać fizycznie gdzieś zapisane. Nawet jeśli używamy dockera, kubernetesa, chmury to gdzieś tam daleko jest fizyczny dysk, na którym zostanie to zapisane. Pomiędzy rozpoczęciem commita transakcji, a zapisaniem wszystkich operacji, zaktualizowaniem tabel, indeksów może minąć trochę czasu (bywa, że i liczonym w godzinach). W tym czasie system operacyjny może się zrestartować, może się nie powieść zapis na dysku, czy inny losowy błąd.

W tym właśnie pomaga “Write-Ahead Log”. Jest to struktura zoptymalizowana pod dodawanie. Każda operacja zostaje w nim uszeregowana w czasie i ustawiona jedna po drugiej. Taka kolejka. Z racji, że jest zoptymalizowana pod dodawanie to potrafi dużo szybciej przyjąć i zapisać operacje niż potem właściwe wykonanie ich na tabelach. Jeżeli dodamy operację do WAL to nawet awaria potem przy aplikowaniu tabel, restart serwera nam w tym nie przeszkodzi. Baza po uruchomieniu ponownym będzie w stanie będzie na jego podstawie kontynuować i dokończyć transakcję (lub ją wycofać bezpiecznie).

Dlatego w bazach danych prawda leży w logu - “Write-Ahead Log”. Na jego podstawie odbudowuje się read modele - tabele (czyli dodaje, aktualizuje, usuwa rekordy). Co więcej sama operacja dzieje się też na zasadzie Eventual Consistency, bo od momentu zapisu do WAL do pojawienia się zmian w tabeli mija bliżej nieokreślony czas.

Czyli dokładnie jak w Event Sourcingu.No prawie, bo WAL to raczej “Command Sourcing”. Nie zapisujemy w nim bowiem faktów dokonanych (zdarzeń) tylko intencję wykonania czegoś. Reszta się zgadza.

Daj znać czy Cię zaskoczyłem.

Pozdrawiam serdecznie!

p.s. Jeśli chcesz więcej poczytać o tym to garść linków rozwijających jeszcze temat:

  • © Oskar Dudycz 2019-2020