Wzorzec projektowy Saga pomaga zachować spójność danych w systemach rozproszonych, koordynując transakcje w wielu usługach. Saga to sekwencja transakcji lokalnych, w których każda usługa wykonuje operację i inicjuje następny krok za pośrednictwem zdarzeń lub komunikatów. Jeśli krok w sekwencji zakończy się niepowodzeniem, saga wykonuje transakcje wyrównywujące, aby cofnąć ukończone kroki, zachowując spójność danych.
Kontekst i problem
Transakcja reprezentuje jednostkę pracy, która może obejmować wiele operacji. W ramach transakcji zdarzenie odnosi się do zmiany stanu wpływającej na jednostkę. Polecenie hermetyzuje wszystkie informacje potrzebne do wykonania akcji lub wyzwolenia kolejnego zdarzenia.
Transakcje muszą być zgodne z zasadami niepodzielności, spójności, izolacji i trwałości (ACID).
- niepodzielność: wszystkie operacje kończą się powodzeniem lub żadną operacją.
- spójność: dane przechodzą z jednego prawidłowego stanu na inny.
- izolacja: transakcje współbieżne dają te same wyniki co sekwencyjne.
- trwałość: po zatwierdzeniu zmiany utrzymują się nawet w przypadku awarii.
W jednej usłudze transakcje są zgodne z zasadami ACID, ponieważ działają w ramach pojedynczej bazy danych. Jednak osiągnięcie zgodności ACID w wielu usługach jest bardziej złożone.
Wyzwania związane z architekturami mikrousług
Architektury mikrousług zwykle przypisują dedykowaną bazę danych do każdej mikrousługi, co zapewnia kilka korzyści:
- Każda usługa hermetyzuje własne dane.
- Każda usługa może używać najbardziej odpowiedniej technologii bazy danych i schematu dla określonych potrzeb.
- Niezależne skalowanie baz danych dla każdej usługi.
- Błędy w jednej usłudze są odizolowane od innych.
Pomimo tych zalet ta architektura komplikuje spójność danych między usługami. Tradycyjne gwarancje bazy danych, takie jak ACID, nie mają bezpośredniego zastosowania do wielu niezależnych zarządzanych magazynów danych. Ze względu na te ograniczenia architektury, które opierają się na komunikacji międzyprocesowej (IPC) lub tradycyjnych modelach transakcji, takich jak protokół zatwierdzania dwufazowego (2PC), są często lepiej dostosowane do wzorca saga.
Rozwiązanie
Wzorzec saga zarządza transakcjami, dzieląc je na sekwencję transakcji lokalnych (zobacz rysunek 1).
Rysunek 1. Saga z trzema usługami.
Każda transakcja lokalna:
- Wykonuje swoją pracę niepodzielnie w ramach jednej usługi.
- Aktualizuje bazę danych usługi.
- Inicjuje następną transakcję za pośrednictwem zdarzenia lub komunikatu.
- Jeśli transakcja lokalna nie powiedzie się, saga wykonuje serię transakcji wyrównywujących , aby odwrócić zmiany wprowadzone przez poprzednie transakcje lokalne.
Kluczowe pojęcia w wzorcu Saga
Transakcje compensable: transakcje, które inne transakcje mogą cofnąć lub zrekompensować z przeciwległym skutkiem. Jeśli krok w sagi zakończy się niepowodzeniem, transakcje wyrównywalne cofają zmiany, które dokonały współzadowolenia transakcji.
transakcji przestawnej: transakcja przestawna służy jako "punkt braku zwrotu" w sagi. Gdy transakcja przestawna zakończy się pomyślnie, transakcje możliwe do cofnięcia (które mogą zostać cofnięte) nie są już istotne. Wszystkie kolejne akcje muszą zostać wykonane, aby system osiągnął spójny stan końcowy. Transakcja przestawna może należeć do różnych ról w zależności od przepływu sagi:
nieodwracalne (niekompensowalne): nie można cofnąć ani ponowić próby.
granicę między odwracalnym i zatwierdzonym: Może to być ostatnia niemożliwa do wykonania transakcja (compensable) lub może być pierwszą operacją, która można ponowić próbę w sagi.
transakcji z możliwością ponawiania próby: te transakcje są zgodne z transakcją przestawną. Transakcje możliwe do ponawiania są idempotentne i zapewniają, że saga może osiągnąć swój stan końcowy, nawet jeśli wystąpią tymczasowe awarie. Gwarantuje, że saga ostatecznie osiągnie spójny stan.
Podejścia implementacji saga
Istnieją dwa typowe podejścia implementacji sagi, choreografia i orkiestracja . Każde podejście ma własny zestaw wyzwań i technologii do koordynowania przepływu pracy.
Choreografia
W choreografii usługi wymieniają wydarzenia bez scentralizowanego kontrolera. Za pomocą choreografii każda transakcja lokalna publikuje zdarzenia domeny, które wyzwalają transakcje lokalne w innych usługach (zobacz rysunek 2).
Rysunek 2. Saga wykorzystująca choreografię.
Korzyści z choreografii | Wady choreografii |
---|---|
Dobre dla prostych przepływów pracy z kilkoma usługami i nie wymagają logiki koordynacji. | Przepływ pracy może stać się mylący podczas dodawania nowych kroków. Trudno jest śledzić, którzy uczestnicy sagi słuchają jakich poleceń. |
Żadna inna usługa nie jest wymagana do koordynacji. | Istnieje ryzyko cyklicznej zależności między uczestnikami sagi, ponieważ muszą korzystać ze sobą poleceń. |
Nie wprowadza jednego punktu awarii, ponieważ obowiązki są rozdzielane między uczestników sagi. | Testowanie integracji jest trudne, ponieważ wszystkie usługi muszą być uruchomione, aby symulować transakcję. |
Aranżacji
W aranżacji scentralizowany kontroler (orkiestrator) obsługuje wszystkie transakcje i informuje uczestników, którzy operację wykonać na podstawie zdarzeń. Orkiestrator wykonuje żądania sagi, przechowuje i interpretuje stany każdego zadania oraz obsługuje odzyskiwanie po awarii przy użyciu transakcji wyrównywalnych (zobaczyć rysunek 3).
Rysunek 3. Saga, która używa orkiestracji.
korzyści z orkiestracji | Wady orkiestracji |
---|---|
Lepiej nadaje się do złożonych przepływów pracy lub podczas dodawania nowych usług. | Inna złożoność projektowania wymaga implementacji logiki koordynacji. |
Unika cyklicznych zależności, ponieważ koordynator zarządza przepływem. | Wprowadza punkt awarii, ponieważ koordynator zarządza pełnym przepływem pracy. |
Jasne rozdzielenie obowiązków upraszcza logikę usługi. |
Problemy i zagadnienia
Podczas implementowania wzorca Saga należy wziąć pod uwagę następujące kwestie:
Shift in design thinking: Przyjęcie wzorca Saga wymaga innego podejścia, koncentrując się na koordynowaniu transakcji i zapewnianiu spójności danych w wielu mikrousługach.
Złożoność debugowania sag: debugowanie sag może być złożone, szczególnie w miarę wzrostu liczby uczestniczących usług.
nieodwracalne zmiany lokalnej bazy danych: Nie można wycofać danych, ponieważ uczestnicy sagi zatwierdzają zmiany w odpowiednich bazach danych.
Obsługa błędów przejściowych i idempotencji: system musi efektywnie obsługiwać błędy przejściowe i zapewnić idempotencję, gdzie powtarzanie tej samej operacji nie zmienia wyniku. Aby uzyskać więcej informacji, zobacz idempotentnego przetwarzania komunikatów.
Potrzeba monitorowania i śledzenia sag: Monitorowanie i śledzenie przepływu pracy sagi są niezbędne do utrzymania nadzoru operacyjnego.
ograniczenia transakcji wyrównywczych: Transakcje wyrównywujące mogą nie zawsze zakończyć się powodzeniem, potencjalnie pozostawiając system w stanie niespójnym.
Potencjalne anomalie danych w sagach
Anomalie danych to niespójności, które mogą wystąpić, gdy sagi są wykonywane w wielu usługach. Ponieważ każda usługa zarządza własnymi danymi (danymi uczestnika), nie ma wbudowanej izolacji między usługami. Ta konfiguracja może spowodować niespójności danych lub problemy z trwałością, takie jak częściowo zastosowane aktualizacje lub konflikty między usługami. Typowe problemy obejmują:
Utracone aktualizacje: gdy jedna saga modyfikuje dane bez uwzględniania zmian wprowadzonych przez inną saga, prowadzi do zastąpienia lub braku aktualizacji.
Dirty odczytuje: gdy saga lub transakcja odczytuje dane zmodyfikowane przez inną saga, ale nie została jeszcze ukończona.
rozmyte (niezwiązane) odczytuje: Gdy różne kroki sagi odczytują niespójne dane, ponieważ aktualizacje występują między operacjami odczytu.
Strategie rozwiązywania anomalii danych
Aby zmniejszyć lub zapobiec tym anomaliom, rozważ następujące środki zaradcze:
blokady semantycznej: użyj blokad na poziomie aplikacji, w których transakcja sagowania używa semafora, aby wskazać, że aktualizacja jest w toku.
aktualizacji dojeżdżających do pracy: aktualizacje projektu, aby można je było stosować w dowolnej kolejności, jednocześnie generując ten sam wynik, zmniejszając konflikty między sagami.
pesymistyczny widok: Zmień kolejność sekwencji sagi, aby aktualizacje danych występowały w transakcjach z możliwością ponawiania prób w celu wyeliminowania zanieczyszczonych operacji odczytu. W przeciwnym razie jedna saga może odczytywać brudne dane (niezatwierdzone zmiany), podczas gdy inna saga jednocześnie wykonuje transakcję compensable w celu wycofania aktualizacji.
Ponowne odczytywanie wartości: sprawdź, czy dane pozostają niezmienione przed wprowadzeniem aktualizacji. Jeśli dane się zmienią, przerwij bieżący krok i uruchom ponownie sagę zgodnie z potrzebami.
pliki wersji: zachowaj dziennik wszystkich operacji na rekordzie i upewnij się, że są one wykonywane w odpowiedniej kolejności, aby zapobiec konfliktom.
współbieżność oparta na ryzyku (według wartości): dynamicznie wybiera odpowiedni mechanizm współbieżności na podstawie potencjalnego ryzyka biznesowego. Na przykład używaj sag do aktualizacji o niskim ryzyku i transakcji rozproszonych w przypadku transakcji o wysokim ryzyku.
Kiedy należy używać tego wzorca
Użyj wzorca Saga, jeśli musisz:
- Zapewnij spójność danych w systemie rozproszonym bez ścisłego sprzężenia.
- Wycofaj lub zrekompensuj, jeśli jedna z operacji w sekwencji zakończy się niepowodzeniem.
Deseń Saga jest mniej odpowiedni dla:
- Ściśle powiązane transakcje.
- Transakcje wyrównywujące, które występują we wcześniejszych uczestników.
- Zależności cykliczne.
Następne kroki
- rozproszone dane
- Richardson, Chris. 2018: Wzorce mikrousług. Publikacje manning.
Powiązane zasoby
Następujące wzorce mogą być również przydatne podczas implementowania tego wzorca:
- Choreografia każdy składnik systemu uczestniczy w procesie podejmowania decyzji na temat przepływu pracy transakcji biznesowej, zamiast polegać na centralnym punkcie kontroli.
- transakcje wyrównywujące cofnąć pracę wykonywaną przez serię kroków, a ostatecznie zdefiniuj spójną operację, jeśli co najmniej jeden krok zakończy się niepowodzeniem. Aplikacje hostowane w chmurze, które implementują złożone procesy biznesowe i przepływy pracy, często korzystają z tego modelu spójności ostatecznej.
- Ponawianie próby umożliwia aplikacji obsługę przejściowych błędów podczas próby nawiązania połączenia z usługą lub zasobem sieciowym przez przezroczyste ponawianie próby wykonania operacji, która zakończyła się niepowodzeniem. Ponawianie próby może poprawić stabilność aplikacji.
- wyłącznik obsługuje błędy, które mogą zająć zmienną ilość czasu do odzyskania podczas nawiązywania połączenia z usługą zdalną lub zasobem. Wyłącznik może poprawić stabilność i odporność aplikacji.
- Monitorowanie punktu końcowego kondycji implementuje kontrole funkcjonalne w aplikacji, do których narzędzia zewnętrzne mogą uzyskiwać dostęp za pośrednictwem uwidocznionych punktów końcowych w regularnych odstępach czasu. Monitorowanie punktu końcowego kondycji może pomóc w sprawdzeniu, czy aplikacje i usługi działają prawidłowo.