Ignite Service Grid — restart

26 lutego odbył się meetup Apache Ignite GreenSource, na którym wystąpili współtwórcy projektu open source. Apache Ignite. Ważnym wydarzeniem w życiu tej społeczności była przebudowa komponentu Ignite Service Grid, który umożliwia wdrażanie użytkowniczych mikroserwisów bezpośrednio w klastrze Ignite. O tym skomplikowanym procesie opowiedział na meet-upie Wjaczesław Daradur, inżynier oprogramowania i od ponad dwóch lat współtwórca Apache Ignite.

Ignite Service Grid — restart

Zacznijmy od tego, czym tak naprawdę jest Apache Ignite. To baza danych, która stanowi rozproszoną pamięć typu Key/Value z obsługą SQL, transakcyjności i pamięci podręcznej. Dodatkowo, Ignite pozwala na wdrażanie użytkowniczych usług bezpośrednio w klastrze Ignite. Deweloperzy mają dostęp do wszystkich narzędzi, które oferuje Ignite — rozproszonych struktur danych, Messaging, Streaming, Compute i Data Grid. Na przykład przy użyciu Data Grid znika problem zarządzania oddzielną infrastrukturą dla przechowywania danych, co eliminuje związane z tym koszty.

Ignite Service Grid — restart

Korzystając z API Service Grid, można wdrożyć usługę, po prostu wskazując w konfiguracji schemat wdrożenia oraz samą usługę.

Zazwyczaj schemat wdrożenia polega na określeniu liczby instancji, które powinny być wdrożone na węzłach klastra. Istnieją dwie standardowe schematy wdrożenia. Pierwsza to Cluster Singleton: w dowolnym momencie w klastrze będzie gwarantowana dostępność jednego egzemplarza usługi użytkownika. Druga to Node Singleton: na każdym węźle klastra wdrożona jest jedna instancja usługi.

Ignite Service Grid — restart

Użytkownik może również określić liczbę instancji usługi w całym klastrze oraz zdefiniować predykat do filtrowania odpowiednich węzłów. W takim scenariuszu Service Grid sam obliczy optymalne rozmieszczenie dla wdrożenia usług.

Ponadto istnieje taka funkcja jak Affinity Service. Affinity to funkcja, która określa powiązanie kluczy z partycjami oraz partycji z węzłami w topologii. Na podstawie klucza można zidentyfikować węzeł primary, na którym przechowywane są dane. W ten sposób można powiązać swój własny serwis z kluczem i pamięcią podręczną funkcji affinity. W przypadku zmiany funkcji affinity następuje automatyczny redeploy. Dzięki temu serwis zawsze będzie usytuowany blisko danych, którymi musi zarządzać, co w konsekwencji zmniejszy koszty dostępu do informacji. Taki schemat można nazwać rodzajem obliczeń kolokacyjnych.

Teraz, gdy omówiliśmy zalety Service Grid, opowiemy o jego historii rozwoju.

Co było wcześniej

Poprzednia implementacja Service Grid opierała się na transakcyjnym replikowanym systemowym cache Ignite. Pod pojęciem "cache" w Ignite rozumie się magazyn. Oznacza to, że nie jest to coś tymczasowego, jak można by pomyśleć. Mimo że cache jest replikowany i każdy węzeł zawiera pełny zestaw danych, w jego wnętrzu cache ma partiowane przedstawienie. Jest to związane z optymalizacją magazynów.

Ignite Service Grid — restart

Co się działo, gdy użytkownik chciał wdrożyć usługę?

  • Wszystkie węzły w klastrze subskrybowały aktualizacje danych w magazynie za pomocą wbudowanego mechanizmu Continuous Query.
  • Węzeł inicjator w ramach transakcji read-committed zapisywał do bazy danych, która zawierała konfigurację usługi, w tym zserializowany egzemplarz.
  • Po otrzymaniu powiadomienia o nowym zapisie, koordynator oceniał rozkład na podstawie konfiguracji. Otrzymany obiekt był zapisywany z powrotem do bazy.
  • Jeśli węzeł był częścią rozkładu, koordynator musiał go wdrożyć.

Co nam się nie podobało

W pewnym momencie doszliśmy do wniosku, że tak nie można pracować z usługami. Powodów było kilka.

Jeśli podczas wdrożenia wystąpił jakiś błąd, można było o nim dowiedzieć się tylko z logów tego węzła, gdzie to się wydarzyło. Istniał tylko asynchroniczny deploy, więc po oddaniu kontroli użytkownikowi przez metodę deploya potrzebny był dodatkowy czas na uruchomienie usługi — w tym czasie użytkownik nie mógł niczego kontrolować. Aby rozwijać Service Grid dalej, dodawać nowe funkcje, przyciągać nowych użytkowników i ułatwiać wszystkim życie, trzeba było coś zmienić.

Podczas projektowania nowej Service Grid, przede wszystkim chcieliśmy zapewnić gwarancję synchronicznego wdrożenia: jak tylko użytkownik odzyska kontrolę od API, natychmiast może korzystać z usług. Chcieliśmy też dać inicjatorowi możliwość obsługi błędów wdrożenia.

Ponadto chcieliśmy uprościć realizację, a konkretnie zrezygnować z transakcji i rebalance’ingu. Mimo że pamięć podręczna jest replikowana i nie ma równoważenia, podczas dużego wdrożenia z wieloma węzłami pojawiały się problemy. Przy zmianie topologii węzły muszą wymieniać informacje, a przy dużym wdrożeniu te dane mogą być bardzo obszerne.

Kiedy topologia była niestabilna, koordynator musiał przeliczyć rozkład usług. Ogólnie rzecz biorąc, gdy konieczne jest działanie z transakcjami w niestabilnej topologii, może to prowadzić do trudno przewidywalnych błędów.

Problemy

Jakie globalne zmiany mogą obyć się bez towarzyszących problemów? Pierwszym z nich była zmiana topologii. Należy zrozumieć, że w każdej chwili, nawet podczas wdrożenia usługi, węzeł może dołączyć do klastra lub z niego wyjść. Co więcej, jeśli w momencie wdrożenia węzeł wejdzie do klastra, konieczne będzie konsekwentne przekazanie całej informacji o usługach do nowego węzła. Nie chodzi tu tylko o to, co już zostało wdrożone, ale także o bieżące i przyszłe wdrożenia.

To tylko jeden z problemów, które można zebrać w osobną listę:

  • Jak wdrożyć statycznie skonfigurowane usługi podczas uruchamiania węzła?
  • Wyjście węzła z klastra – co zrobić, jeśli węzeł hostował usługi?
  • Co zrobić, jeśli zmienił się koordynator?
  • Co zrobić, jeśli klient ponownie połączył się z klastrami?
  • Czy należy obsłużyć zgłoszenia aktywacji/dezaktywacji i jak?
  • A co, jeśli wezwano destrukcję pamięci podręcznej, a mamy uzależnione od niej usługi affinitowe?

I to nie wszystko.

Rozwiązanie

Jako cel wybraliśmy podejście oparte na zdarzeniach z realizacją komunikacji procesów poprzez wiadomości. W Ignite już zaimplementowano dwa komponenty, które umożliwiają węzłom wymianę wiadomości między sobą – communication-spi i discovery-spi.

Ignite Service Grid — restart

Communication-spi pozwala węzłom na bezpośrednią komunikację oraz wysyłanie wiadomości. Jest to dobre rozwiązanie do przesyłania dużej ilości danych. Discovery-spi umożliwia wysłanie wiadomości do wszystkich węzłów w klastrze. W standardowej implementacji odbywa się to w topologii „ring”. Istnieje również integracja z Zookeeperem, w takim przypadku używana jest topologia „gwiazda”. Warto również zaznaczyć, że discovery-spi zapewnia gwarancje, że wiadomość zostanie dostarczona w odpowiedniej kolejności do wszystkich węzłów.

Rozważmy protokół wdrażania. Wszystkie żądania użytkowników dotyczące wdrożenia i wycofania są wysyłane przez discovery-spi. Daje to następujące gwarancje:

  • Żądanie będzie odebrane przez wszystkie węzły w klastrze. Umożliwi to kontynuację przetwarzania żądania przy zmianie koordynatora. Oznacza to również, że każde węzeł otrzyma wszystkie niezbędne metadane dotyczące jednego komunikatu, takie jak konfiguracja usługi oraz jej zserializowany instancja.
  • Ścisła kolejność dostarczania wiadomości pozwala rozwiązywać konflikty konfiguracji oraz konkurencyjnych żądań.
  • Ponieważ wejście węzła do topologii jest również przetwarzane za pośrednictwem discovery-spi, nowy węzeł otrzyma wszystkie dane potrzebne do obsługi usług.

Po otrzymaniu żądania węzły w klastrze walidują je i tworzą zadania do przetworzenia. Te zadania są gromadzone w kolejce, a następnie przetwarzane w innym wątku przez oddzielnego wykonawcę. Zostało to zrealizowane w ten sposób, ponieważ wdrażanie może zająć znaczny czas, co byłoby niedopuszczalne, aby wstrzymywało drogi strumień discovery.

Wszystkie żądania z kolejki są przetwarzane przez menedżera wdrożeń. Ma on specjalnego wykonawcę, który wyciąga zadanie z tej kolejki i inicjalizuje je, aby rozpocząć wdrażanie. Po tym następują następujące czynności:

  1. Każdy węzeł samodzielnie oblicza rozkład dzięki nowej deterministycznej funkcji przydziału.
  2. Węzły formują wiadomość z wynikami wdrażania i wysyłają ją do koordynatora.
  3. Koordynator agreguje wszystkie wiadomości i formuje wynik całego procesu wdrażania, który jest wysyłany przez discovery-spi do wszystkich węzłów w klastrze.
  4. Po otrzymaniu wyniku, proces wdrażania kończy się, po czym zadanie jest usuwane z kolejki.

Ignite Service Grid — restart
Nowy projekt oparty na zdarzeniach: org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java

Jeśli podczas wdrażania wystąpił błąd, węzeł natychmiast włącza ten błąd do wiadomości, którą przesyła koordynatorowi. Po agregacji wiadomości koordynator będzie miał informacje o wszystkich błędach podczas wdrożenia i wysła tę wiadomość przez discovery-spi. Informacje o błędach będą dostępne na każdym węźle w klastrze.

Zgodnie z tym algorytmem przetwarzane są wszystkie istotne zdarzenia w Service Grid. Na przykład zmiana topologii to również wiadomość przez discovery-spi. Ogólnie rzecz biorąc, w porównaniu do tego, co było, protokół stał się dość lekki i niezawodny. Na tyle, by poradzić sobie z każdą sytuacją podczas wdrażania.

Co będzie dalej

Teraz o planach. Każda duża poprawka w projekcie Ignite realizowana jest jako inicjatywa na poprawę Ignite, tzw. IEP. Redesign Service Grid ma również swoje IEP — IEP nr 17 o zabawnym tytule «Wymiana oleju w Service Grid». Ale tak naprawdę nie wymienialiśmy oleju w silniku, lecz cały silnik.

Zadania w IEP podzieliliśmy na 2 fazy. Pierwsza — duża faza, która polega na przeprojektowaniu protokołu wdrażania. Już została włączona do mastera, można wypróbować nowy Service Grid, który pojawi się w wersji 2.8. Druga faza obejmuje wiele innych zadań:

  • Gorące redeploy
  • Wersjonowanie usług
  • Zwiększenie odporności na awarie
  • Cienki klient
  • Narzędzia monitorowania i liczenia różnych metryk

Na koniec możemy polecić wam Service Grid do budowy odpornych systemów o wysokiej dostępności. A także zapraszamy do nas na dev-list i user-list podzielenie się swoim doświadczeniem. Twoje doświadczenie jest naprawdę ważne dla społeczności, pomoże zrozumieć, w którą stronę dalej się rozwijać, jak w przyszłości rozwijać komponent.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster