Czy pozyskiwanie zdarzeń jest możliwe tylko wtedy, gdy zapisy są rzadkie?

9

Czytam o pozyskiwaniu wydarzeń i nie mogę przestać zadawać sobie pytania, czy ma to sens tylko w egzotycznych sytuacjach, w których zapisy są bardzo rzadkie lub wymagana jest kontrola na poziomie wojskowym.

Niezwykły system o dowolnym zastosowaniu może generować od setek do tysięcy zapisów dziennie, co przekłada się, powiedzmy, na milion lub 2 zapisy (a więc zdarzenia) rocznie. Scalanie milionów obiektów (zdarzeń) tylko po to, aby uzyskać obecny stan, brzmi jak niedorzeczna propozycja, w porównaniu do zwykłego odczytu z tradycyjnego magazynu. Jednak pozyskiwanie zdarzeń stoi za jednymi z najbardziej wydajnych systemów (pomyśl LMAX).

Więc czego mi brakuje? Czy przywracanie stanu ze strumienia zdarzeń jest nawet często wykonywane? Czy może rzadko trzeba to robić i zamiast tego używać zupełnie innej pamięci do normalnych operacji (tj. Używać pamięci zapytań z CQRS) i przywracać dane ze zdarzeń tylko w wyjątkowych przypadkach (takich jak replikacja, kontrola itp.)?

kaqqao
źródło

Odpowiedzi:

6

Więc czego mi brakuje?

Zgaduję.

Pierwszą rzeczą, której możesz brakować, jest to, że wystarczy przeładować zdarzenia dla stanu, który odbudowujesz. Jeśli możesz dokładnie modelować granice transakcji, każdy obiekt może zapisywać zdarzenia oznaczone własnym identyfikatorem, a następnie odczytywać tylko te zdarzenia. Używając relacyjnej bazy danych do przechowywania zdarzeń, indeksowana kolumna identyfikatora przyspieszyłaby to zapytanie. Za pomocą EventStore każdy obiekt miałby swój własny strumień.

W twoim modelu zachowanie tego wymaga pewnej staranności, ponieważ chcesz mieć pewność, że modyfikujesz tylko jeden obiekt w każdej transakcji, i dlatego musisz zadbać o to, aby prawidłowo izolować każdy niezmiennik, który próbujesz egzekwować.

W przypadkach, gdy nie jest to wystarczająco szybkie, nadal masz możliwość tworzenia migawek swojego stanu (zapamiętywania) i utrzymywania tego w „tradycyjnym magazynie”. Każda migawka jest oznaczana numerem sekwencji ostatniego zdarzenia użytego do zbudowania migawki; po przeładowaniu repozytorium najpierw pobiera tę migawkę, a następnie stosuje do niej nowsze zdarzenia. (To sugeruje jakiś rozsądny sposób na przechwycenie najnowszych migawek - albo zdarzenia są również oznaczone numerem sekwencyjnym, albo masz jakiś skuteczny sposób na odczytanie strumienia zdarzeń wstecz, aż dojdziesz do punktu początkowego.)

Nadal istnieje przewaga nad zwykłym podejściem, ponieważ migawki można budować równolegle do zapisów, a nie łączyć się z nimi: wystarczy umieścić detektor zdarzeń w innym wątku / procesie i pozwolić mu wesoło pisać do sklepu z migawkami według dowolnego harmonogramu, który wydaje się rozsądny. W końcu migawka nie musi być przeprowadzana w odpowiednim czasie - wystarczy, że praca nad ponownym zastosowaniem nowszych zdarzeń nie zniszczy Twojej umowy SLA.

(Migawka komplikuje migrację; wszelkie zmiany serializacji modelu unieważnią pamięć podręczną migawek. Oczywiście można odbudować migawki przy użyciu nowej serializacji jako części migracji, a następnie „nadrobić zaległości”, gdy zmiany zostaną wprowadzone w życie.)

Czy przywracanie stanu ze strumienia zdarzeń jest nawet często wykonywane?

Tak to jest. W przykładach CQRS zwykle pokazano, że warstwa aplikacji, po upewnieniu się, że przesłane polecenie jest poprawnie sformułowane, warstwa aplikacji załaduje obiekt domeny z repozytorium, w którym ładunek jest domyślnym konstruktorem, a następnie odtworzony strumień zdarzeń (lub równoważnie połączenie z fabryką z listą zdarzeń).

Dwie inne sprzeczne myśli.

  1. Za interfejsem repozytorium może znajdować się pamięć podręczna
  2. Unieważnienie pamięci podręcznej jest jednym z dwóch trudnych problemów.
VoiceOfUnreason
źródło