Architektura i możliwości Tarantool Data Grid

Architektura i możliwości Tarantool Data Grid

W 2017 roku wygraliśmy przetarg na opracowanie transakcyjnego jądra biznesu inwestycyjnego Alfa-Banku i przystąpiliśmy do pracy (na HighLoad++ 2018 z prezentacją na temat jądra biznesu inwestycyjnego występował Wladimir Drynkin, kierownik działu transakcyjnego jądra biznesu inwestycyjnego Alfa-Banku). System ten miał agregować dane o transakcjach z różnych źródeł w różnych formatach, unifikować dane, przechowywać je i udostępniać.

W trakcie rozwoju system ewoluował i zyskiwał nowe funkcje, a w pewnym momencie zrozumieliśmy, że kształtuje się u nas coś znacznie większego niż tylko aplikacja stworzona do rozwiązania ściśle określonego kręgu zadań: otrzymaliśmy system do budowy rozproszonych aplikacji z trwałym magazynem. Nasze doświadczenie stało się podstawą nowego produktu — Tarantool Data Grid (TDG).

Chcę opowiedzieć o architekturze TDG i rozwiązaniach, do których doszliśmy w trakcie rozwoju, zapoznać Was z głównym funkcjonalnością i pokazać, jak nasz produkt może stać się podstawą do budowy kompleksowych rozwiązań.

Architektonicznie podzieliliśmy system na oddzielne role, z których każda odpowiada za rozwiązanie określonego kręgu zadań. Jedna uruchomiona instancja aplikacji realizuje jeden lub kilka typów ról. W klastrze może być kilka ról tego samego typu:

Architektura i możliwości Tarantool Data Grid

Connector

Connector odpowiada za komunikację ze światem zewnętrznym; jego zadanie polega na przyjęciu zapytania, jego analizie, a jeśli się powiedzie, na wysłaniu danych do przetworzenia przez input processor. Obsługujemy formaty HTTP, SOAP, Kafka, FIX. Architektura pozwala na łatwe dodawanie wsparcia dla nowych formatów, wkrótce pojawi się wsparcie dla IBM MQ. Jeśli analiza zapytania zakończy się błędem, connector zwróci błąd; w przeciwnym razie odpowie, że zapytanie zostało pomyślnie przetworzone, nawet jeśli wystąpił błąd podczas dalszego przetwarzania. Zostało to zaprojektowane specjalnie, aby móc współpracować z systemami, które nie potrafią ponownie wysyłać zapytań — lub odwrotnie, robią to zbyt natarczywie. Aby nie tracić danych, używana jest kolejka naprawcza: obiekt najpierw trafia do niej, a dopiero po pomyślnym przetworzeniu jest z niej usuwany. Administrator może otrzymywać powiadomienia o obiektach, które pozostały w kolejce naprawczej, a po naprawieniu błędu programowego lub usterki sprzętowej może spróbować ponownie.

Input processor

Input processor klasyfikuje otrzymane dane według cech charakterystycznych i wywołuje odpowiednie przetwarzacze. Przetwarzacze to kod w języku Lua, uruchamiany w piaskownicy, w ten sposób nie mogą wpłynąć na funkcjonowanie systemu. Na tym etapie dane można przekształcić w wymagany format, a także w razie potrzeby uruchomić dowolną liczbę zadań, które mogą realizować wymaganą logikę. Na przykład, w produkcie MDM (Master Data Management), zbudowanym na Tarantool Data Grid, podczas dodawania nowego użytkownika, aby nie spowolnić przetwarzania zapytania, tworzenie złotej rekordu uruchamiamy w osobnym zadaniu. Piaskownica obsługuje zapytania do odczytu, modyfikacji i dodawania danych, pozwala na wykonanie pewnej funkcji dla wszystkich ról typu storage i agregację wyników (map/reduce).

Przetwarzacze mogą być opisane w plikach:

sum.lua

local x, y = unpack(...)
return x + y

A następnie zadeklarowane w konfiguracji:

functions:
  sum: { __file: sum.lua }

Dlaczego Lua? Lua to bardzo prosty język. Na podstawie naszego doświadczenia, po kilku godzinach zapoznawania się z nim, ludzie zaczynają pisać kod rozwiązujący ich problemy. I to nie tylko profesjonalni programiści, ale na przykład analitycy. Co więcej, dzięki kompilatorowi just-in-time, Lua działa bardzo szybko.

Pamięć

Przechowywanie zewnętrznych danych. Przed zapisaniem dane są weryfikowane pod kątem zgodności ze schematem danych. Do opisu schematu używamy rozszerzonego formatu Apache Avro. Przykład:

{
    "name": "User",
    "type": "record",
    "logicalType": "Aggregate",
    "fields": [ 
        { "name": "id", "type": "string"}, 
        {"name": "first_name", "type": "string"}, 
        {"name": "last_name", "type": "string"} 
    ], 
    "indexes": ["id"] 
}

Na podstawie tego opisu automatycznie generowany jest DDL (Data Definition Language) dla bazy danych Tarantool oraz GraphQL schemat do dostępu do danych.

Obsługiwana jest asynchroniczna replikacja danych (w planach dodanie synchronizowanej).

Procesor wyjściowy

Czasami konieczne jest powiadomienie zewnętrznych odbiorców o nadejściu nowych danych, w tym celu istnieje rola Procesora wyjściowego. Po zapisaniu dane mogą zostać przekazane do stosownego przetwornika (np. aby przekształcić je do wymaganego przez odbiorcę formatu) — a następnie przesłane do łącznika do wysyłki. Używana jest również kolejka naprawcza: jeśli nikt nie przyjął obiektu, administrator może spróbować później.

Skalowanie

Role łącznika, procesora wejściowego i procesora wyjściowego nie mają stanu, co pozwala nam na poziome skalowanie systemu, po prostu dodając nowe instancje aplikacji z włączoną rolą odpowiedniego typu. Do poziomego skalowania przechowywania używana jest metoda organizacji klastra z wykorzystaniem wirtualnych pojemników. Po dodaniu nowego serwera część pojemników ze starych serwerów w tle przenosi się na nowy serwer; odbywa się to przezroczysto dla użytkowników i nie wpływa na działanie całego systemu.

Właściwości danych

Obiekty mogą być bardzo duże i zawierać inne obiekty. Zapewniamy atomowość przy dodawaniu i aktualizacji danych, zapisując obiekt ze wszystkimi zależnościami w jednym wirtualnym pojemniku. Tak więc, „rozciąganie” obiektu na kilka fizycznych serwerów jest wykluczone.

Obsługiwane jest wersjonowanie: każda aktualizacja obiektu tworzy nową wersję, dzięki czemu zawsze możemy wykonać zrzut czasowy i zobaczyć, jak wyglądał świat wówczas. W przypadku danych, które nie wymagają długiej historii, możemy ograniczyć liczbę wersji lub nawet przechowywać tylko jedną — ostatnią, co w rzeczywistości wyłącza wersjonowanie dla danego typu. Możemy również ograniczyć historię czasowo: na przykład usuwać wszystkie obiekty danego typu starsze niż 1 rok. Obsługiwane jest także archiwizowanie: możemy eksportować obiekty starsze od określonego czasu, uwalniając miejsce w klastrze.

Zadania

Warto wspomnieć o interesujących funkcjach, jak możliwość uruchamiania zadań według harmonogramu, na żądanie użytkownika lub programowo z poziomu piaskownicy:

Architektura i możliwości Tarantool Data Grid

Tutaj widzimy jeszcze jedną rolę — runner. Ta rola nie ma stanu, a w razie potrzeby można dodać dodatkowe instancje aplikacji z tą rolą do klastra. Odpowiedzialnością runnera jest wykonywanie zadań. Jak już wspomniano, z piaskownicy można generować nowe zadania, które są przechowywane w kolejce na storage, a następnie realizowane przez runnera. Ten typ zadań nazywa się Job. Mamy też typ zadań, nazywany Task — to zadania określone przez użytkownika, uruchamiane według harmonogramu (używany jest składnia cron) lub na żądanie. Do uruchamiania i śledzenia takich zadań mamy wygodny menedżer zadań. Aby ta funkcjonalność była dostępna, należy włączyć rolę scheduler; ta rola ma stan, więc nie jest skalowalna, co jednak nie jest wymagane; przy tym jak wszystkie inne role, może mieć replikę, która zaczyna działać, jeśli master nagle zawiedzie.

Logger

Jeszcze jedna rola nazywa się logger. Zbiera logi ze wszystkich członków klastra i udostępnia interfejs do ich eksportu i przeglądania przez interfejs webowy.

Usługi

Warto wspomnieć, że system umożliwia łatwe tworzenie usług. W pliku konfiguracyjnym można określić, jakie zapytania kierować do napisanego przez użytkownika obsługiwacza, wykonywanego w piaskownicy. W tym obsługiwaczu można na przykład wykonać jakieś zapytanie analityczne i zwrócić wynik.

Usługa opisana jest w pliku konfiguracyjnym:

services:
   sum:
      doc: "dodaje dwie liczby"
      function: sum
      return_type: int
      args:
         x: int
         y: int

API GraphQL jest generowany automatycznie, a usługa staje się dostępna do wywołania:

zapytanie {
   suma(x: 1, y: 2) 
}

To spowoduje wywołanie handlera suma, który zwróci wynik:

3

Profilowanie zapytań i metryki

Aby zrozumieć działanie systemu i profilować zapytania, wprowadziliśmy wsparcie dla protokołu OpenTracing. System może na żądanie przesyłać informacje do narzędzi wspierających ten protokół, takich jak Zipkin, co pozwoli zrozumieć, jak było realizowane zapytanie:

Architektura i możliwości Tarantool Data Grid

Oczywiście, system dostarcza wewnętrzne metryki, które można zbierać za pomocą Prometheus i wizualizować w Grafana.

Wdrożenie

Tarantool Data Grid może być wdrożony z pakietów RPM lub archiwum, za pomocą narzędzia w dostawie lub Ansible, a także wspiera Kubernetes (Operator Kubernetes Tarantool).

Aplikacja realizująca logikę biznesową (konfiguracja, handlerzy) jest ładowana do wdrożonego klastra Tarantool Data Grid w postaci archiwum przez interfejs użytkownika lub za pomocą skryptu, przez udostępnione przez nas API.

Przykłady aplikacji

Jakie aplikacje można stworzyć za pomocą Tarantool Data Grid? W rzeczywistości większość zadań biznesowych w jakiś sposób wiąże się z przetwarzaniem strumienia danych, ich przechowywaniem i dostępem do nich. Dlatego, jeśli masz duże strumienie danych, które muszą być niezawodnie przechowywane i musisz mieć do nich dostęp, nasz produkt może zaoszczędzić Ci dużo czasu na rozwój, pozwalając skupić się na logice biznesowej.

Na przykład, chcemy zbierać informacje o rynku nieruchomości, aby w przyszłości mieć informacje o najbardziej korzystnych ofertach. W takim przypadku wyodrębnimy następujące zadania:

  1. Roboty zbierające informacje z otwartych źródeł będą naszymi źródłami danych. To zadanie można rozwiązać, korzystając z gotowych rozwiązań lub pisząc kod w dowolnym języku.
  2. Następnie Tarantool Data Grid przyjmie i zapisze dane. Jeśli format danych z różnych źródeł różni się, można napisać kod w języku Lua, który przekształci je do jednego formatu. Na etapie wstępnego przetwarzania będzie można również, na przykład, filtrować powtarzające się oferty lub dodatkowo aktualizować w bazie danych informacje o agentach działających na rynku.
  3. Teraz macie już skalowalne rozwiązanie w klastrze, które można zapełniać danymi i wykonywać zapytania do danych. Możecie teraz realizować nową funkcjonalność, na przykład napisać serwis, który złoży zapytanie do danych i poda najbardziej korzystną ofertę na dzień — to wymaga kilku linii w pliku konfiguracyjnym i trochę kodu w Lua.

Co dalej?

Naszym priorytetem jest zwiększenie wygody programowania dzięki Tarantool Data Grid. Na przykład, to IDE z obsługą profilowania i debugowania obsługujących, które działają w piaskownicy.

Również przykładamy dużą wagę do kwestii bezpieczeństwa. Właśnie teraz przechodzimy certyfikację FSTEK Rosji, aby potwierdzić wysoki poziom bezpieczeństwa i spełnić wymagania dotyczące certyfikacji produktów programowych używanych w systemach informacyjnych danych osobowych i państwowych systemach informacyjnych.

Ź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