Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Kadr z filmu „Nasz sekretny wszechświat: ukryte życie komórki”

Działalność inwestycyjna to jeden z najbardziej złożonych obszarów w świecie bankowości, ponieważ obejmują nie tylko kredyty, pożyczki i depozyty, ale także papiery wartościowe, waluty, towary, instrumenty pochodne i wszelkiego rodzaju złożoności w postaci produktów strukturyzowanych.

W ostatnim czasie można zaobserwować wzrost świadomości finansowej społeczeństwa. Coraz więcej osób angażuje się w handel na rynkach papierów wartościowych. Indywidualne rachunki inwestycyjne pojawiły się nie tak dawno temu. Umożliwiają handel na rynkach papierów wartościowych i albo otrzymują ulgi podatkowe, albo unikają płacenia podatków. A wszyscy klienci, którzy do nas przychodzą, chcą zarządzać swoim portfelem i widzieć raporty w czasie rzeczywistym. Co więcej, najczęściej jest to portfolio wieloproduktowe, czyli ludzie są klientami różnych linii biznesowych.

Ponadto rosną potrzeby regulatorów, zarówno rosyjskich, jak i zagranicznych.

Aby sprostać bieżącym potrzebom i położyć podwaliny pod przyszłe ulepszenia, opracowaliśmy rdzeń działalności inwestycyjnej w oparciu o Tarantool.

Trochę statystyk. Działalność inwestycyjna Alfa-Banku świadczy usługi maklerskie dla osób fizycznych i prawnych w celu zapewnienia możliwości obrotu na różnych rynkach papierów wartościowych, usługi depozytowe w zakresie przechowywania papierów wartościowych, usługi zarządzania trustami dla osób fizycznych z kapitałem prywatnym i dużym, usługi emisji papierów wartościowych dla innych spółek . Działalność inwestycyjna Alfa-Banku obejmuje ponad 3 tysiące kwotowań na sekundę, które są pobierane z różnych platform transakcyjnych. W ciągu dnia roboczego na rynkach zawieranych jest ponad 300 tys. transakcji w imieniu banku lub jego klientów. Na platformach zewnętrznych i wewnętrznych dochodzi do 5 tysięcy realizacji zleceń na sekundę. Jednocześnie wszyscy klienci, zarówno wewnętrzni, jak i zewnętrzni, chcą widzieć swoje pozycje w czasie rzeczywistym.

prehistoria

Gdzieś od początku lat 2000 nasze obszary działalności inwestycyjnej rozwijały się niezależnie: handel giełdowy, usługi maklerskie, handel walutami, pozagiełdowy obrót papierami wartościowymi i różnymi instrumentami pochodnymi. W rezultacie wpadliśmy w pułapkę funkcjonalnych studni. Co to jest? Każda linia biznesowa ma własne systemy, które powielają wzajemnie funkcje. Każdy system ma swój własny model danych, chociaż działają w oparciu o te same pojęcia: transakcje, instrumenty, kontrahenci, kwotowania i tak dalej. W miarę jak każdy system ewoluował niezależnie, wyłoniło się różnorodne zoo technologii.

Poza tym baza kodowa systemów jest już dość przestarzała, gdyż niektóre produkty powstały jeszcze w połowie lat 1990-tych. W niektórych obszarach spowolniło to proces rozwoju i wystąpiły problemy z wydajnością.

Wymagania dla nowego rozwiązania

Przedsiębiorstwa zdały sobie sprawę, że transformacja technologiczna jest niezbędna do dalszego rozwoju. Dostaliśmy zadania:

  1. Gromadź wszystkie dane biznesowe w jednym, szybkim magazynie i w jednym modelu danych.
  2. Nie wolno nam utracić ani zmienić tych informacji.
  3. Konieczne jest wersjonowanie danych, gdyż w każdej chwili regulator może poprosić o statystyki za lata ubiegłe.
  4. Musimy nie tylko wprowadzić jakiś nowy, modny system DBMS, ale stworzyć platformę do rozwiązywania problemów biznesowych.

Dodatkowo nasi architekci ustalają własne warunki:

  1. Nowe rozwiązanie musi być klasy Enterprise, czyli musi być już przetestowane w niektórych dużych firmach.
  2. Tryb działania rozwiązania powinien mieć znaczenie krytyczne. Oznacza to, że musimy być obecni w kilku data center jednocześnie i spokojnie przetrwać awarię jednego data center.
  3. System musi być skalowalny w poziomie. Faktem jest, że wszystkie nasze obecne systemy są skalowalne tylko w pionie, a już sięgamy sufitu z powodu niskiego wzrostu mocy sprzętu. Nadszedł zatem moment, w którym aby przetrwać, potrzebujemy systemu skalowalnego horyzontalnie.
  4. Powiedziano nam między innymi, że rozwiązanie musi być tanie.

Poszliśmy standardową drogą: sformułowaliśmy wymagania i skontaktowaliśmy się z działem zakupów. Stamtąd otrzymaliśmy listę firm, które w zasadzie są gotowe to dla nas zrobić. Powiedzieliśmy wszystkim o problemie i otrzymaliśmy ocenę rozwiązań od sześciu z nich.

W banku nie wierzymy nikomu na słowo, lubimy wszystko testować sami. Dlatego obowiązkowym warunkiem naszego konkursu ofertowego było zdanie testów obciążeniowych. Sformułowaliśmy zadania testów obciążenia, a trzy z sześciu firm zgodziły się już na wdrożenie na własny koszt prototypowego rozwiązania opartego na technologiach in-memory w celu jego przetestowania.

Nie będę zdradzać jak wszystko testowaliśmy i ile czasu to zajęło, podsumuję tylko: najlepiej w testach obciążeniowych wykazało się prototypowe rozwiązanie oparte na Tarantoolu od zespołu deweloperskiego Mail.ru Group. Podpisaliśmy umowę i rozpoczęliśmy rozwój. Z Grupy Mail.ru pracowały cztery osoby, a z Alfa-Banku było trzech programistów, trzech analityków systemowych, architekt rozwiązań, właściciel produktu i mistrz Scrum.

Następnie opowiem Ci o tym, jak rozwijał się nasz system, jak ewoluował, co zrobiliśmy i dlaczego właśnie to.

Rozwój

Pierwsze pytanie, jakie sobie zadaliśmy, brzmiało: jak uzyskać dane z naszych obecnych systemów. Zdecydowaliśmy, że protokół HTTP będzie dla nas w zupełności odpowiedni, ponieważ wszystkie obecne systemy komunikują się ze sobą, wysyłając XML lub JSON przez HTTP.

Korzystamy z serwera HTTP wbudowanego w Tarantool, ponieważ nie musimy przerywać sesji SSL, a jego wydajność jest dla nas wystarczająca.

Jak już mówiłem wszystkie nasze systemy żyją w różnych modelach danych i na wejściu musimy doprowadzić obiekt do modelu, który sami opisujemy. Potrzebny był język, który umożliwiłby transformację danych. Wybraliśmy imperatyw Lua. Cały kod konwersji danych uruchamiamy w piaskownicy – ​​jest to bezpieczne miejsce, poza które działający kod nie wyjdzie. Aby to zrobić, po prostu ładujemy wymagany kod, tworząc środowisko z funkcjami, które nie mogą niczego blokować ani upuszczać.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Po konwersji należy sprawdzić dane pod kątem zgodności z tworzonym przez nas modelem. Długo dyskutowaliśmy, jaki powinien być ten model i jakim językiem go opisać. Wybraliśmy Apache Avro, ponieważ język jest prosty i obsługuje Tarantool. Nowe wersje modelu i niestandardowego kodu mogą być uruchamiane kilka razy dziennie, nawet pod obciążeniem lub bez, o każdej porze dnia i bardzo szybko dostosowują się do zmian.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Po weryfikacji dane muszą zostać zapisane. Robimy to za pomocą vsharda (mamy repliki odłamków rozproszone geograficznie).

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Co więcej, specyfika jest taka, że ​​większość systemów, które przesyłają nam dane, nie przejmuje się tym, czy je otrzymaliśmy, czy nie. Dlatego od samego początku wdrożyliśmy kolejkę naprawczą. Co to jest? Jeśli z jakiegoś powodu obiekt nie zostanie poddany transformacji danych lub weryfikacji, nadal potwierdzamy jego odbiór, ale jednocześnie zapisujemy obiekt w kolejce do naprawy. Jest spójny i zlokalizowany w głównej hurtowni danych biznesowych. Od razu napisaliśmy dla niego interfejs administratora, różne metryki i alerty. Dzięki temu nie tracimy danych. Nawet jeśli coś się zmieniło w źródle, jeśli zmienił się model danych, natychmiast to wykryjemy i będziemy mogli się dostosować.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Teraz musisz dowiedzieć się, jak odzyskać zapisane dane. Dokładnie przeanalizowaliśmy nasze systemy i zobaczyliśmy, że klasyczny stos Java i Oracle koniecznie zawiera jakiś rodzaj ORM, który konwertuje dane z relacyjnego na obiektowy. Dlaczego więc nie od razu przekazać obiektów systemom w postaci wykresu? Dlatego z radością przyjęliśmy GraphQL, który spełnił wszystkie nasze potrzeby. Pozwala odbierać dane w postaci wykresów i wyciągać tylko to, czego w danym momencie potrzebujesz. Możesz nawet wersjonować interfejs API z dużą elastycznością.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Niemal natychmiast zdaliśmy sobie sprawę, że dane, które wydobywaliśmy, nie były wystarczające. Stworzyliśmy funkcje, które można powiązać z obiektami w modelu – zasadniczo polami obliczeniowymi. Oznacza to, że do pola dołączamy pewną funkcję, która np. wylicza średnią cenę ofertową. A odbiorca zewnętrzny, który żąda danych, nawet nie wie, że jest to pole obliczeniowe.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Wdrożony system uwierzytelniania.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Potem zauważyliśmy, że w naszej decyzji skrystalizowało się kilka ról. Rola jest rodzajem agregatora funkcji. Zazwyczaj role mają różne profile wykorzystania sprzętu:

  • T-Connect: obsługuje połączenia przychodzące, ograniczony procesor, niskie zużycie pamięci, bezstanowy.
  • IB-Core: przetwarza dane, które otrzymuje poprzez protokół Tarantool, czyli operuje tabelami. Nie przechowuje również stanu i jest skalowalny.
  • Przechowywanie: przechowuje tylko dane, nie używa żadnej logiki. Ta rola implementuje najprostsze interfejsy. Skalowalny dzięki vshard.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Oznacza to, że za pomocą ról oddzieliliśmy od siebie różne części klastra, które można skalować niezależnie od siebie.

Stworzyliśmy więc asynchroniczne rejestrowanie przepływu danych transakcyjnych i kolejkę napraw z interfejsem administratora. Nagranie jest z biznesowego punktu widzenia asynchroniczne: jeśli mamy pewność, że zapiszemy dane do siebie, nieważne gdzie, to potwierdzimy to. Jeśli nie zostanie to potwierdzone, oznacza to, że coś poszło nie tak i należy przesłać dane. To jest nagranie asynchroniczne.

Testowanie

Od samego początku projektu zdecydowaliśmy, że spróbujemy wdrożyć rozwój oparty na testach. Testy jednostkowe piszemy w Lua z wykorzystaniem frameworka tarantool/tap, a testy integracyjne w Pythonie z wykorzystaniem frameworka pytest. Jednocześnie w pisanie testów integracyjnych angażujemy zarówno programistów, jak i analityków.

Jak wykorzystujemy rozwój oparty na testach?

Jeśli chcemy jakiejś nowej funkcji, staramy się najpierw napisać dla niej test. Kiedy odkryjemy błąd, najpierw napiszemy test, a dopiero potem go naprawimy. Na początku ciężko tak pracować, jest niezrozumienie ze strony pracowników, wręcz sabotaż: „Naprawmy to teraz szybko, zróbmy coś nowego, a potem przykryjmy to testami”. Tylko to „później” prawie nigdy nie nadchodzi.

Dlatego najpierw musisz zmusić się do napisania testów i poprosić o to innych. Uwierz mi, rozwój oparty na testach przynosi korzyści nawet w krótkim okresie. Poczujesz, że Twoje życie stało się łatwiejsze. Uważamy, że 99% kodu jest obecnie objęte testami. Wydaje się to dużo, ale nie mamy żadnych problemów: testy są uruchamiane przy każdym zatwierdzeniu.

Najbardziej jednak kochamy testy obciążeniowe, uważamy je za najważniejsze i przeprowadzamy je regularnie.

Opowiem Wam krótką historię o tym jak przeprowadziliśmy pierwszy etap testów obciążeniowych jednej z pierwszych wersji. Zainstalowaliśmy system na laptopie dewelopera, włączyliśmy obciążenie i otrzymywaliśmy 4 tysiące transakcji na sekundę. Dobry wynik jak na laptopa. Zainstalowaliśmy go na wirtualnej ławce obciążeniowej składającej się z czterech serwerów, słabszych niż w wersji produkcyjnej. Wdrożony do minimum. Uruchamiamy go i w jednym wątku uzyskujemy wynik gorszy niż na laptopie. Treść szokująca.

Było nam bardzo smutno. Patrzymy na obciążenie serwerów, ale okazuje się, że są one bezczynne.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Dzwonimy do programistów, a oni nam, ludziom wywodzącym się ze świata Javy, tłumaczą, że Tarantool jest jednowątkowy. Może być efektywnie wykorzystany tylko przez jeden rdzeń procesora pod obciążeniem. Następnie wdrożyliśmy maksymalną możliwą liczbę instancji Tarantool na każdym serwerze, włączyliśmy obciążenie i otrzymaliśmy już 14,5 tys. transakcji na sekundę.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Pozwól mi jeszcze raz wyjaśnić. Ze względu na podział na role, które w różny sposób korzystają z zasobów, nasze role odpowiedzialne za przetwarzanie połączeń i transformację danych obciążały tylko procesor i były ściśle proporcjonalne do obciążenia.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
W tym przypadku pamięć była wykorzystywana jedynie do przetwarzania połączeń przychodzących i obiektów tymczasowych.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Z drugiej strony, na serwerach pamięci masowej obciążenie procesora wzrosło, ale znacznie wolniej niż na serwerach przetwarzających połączenia.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Zużycie pamięci rosło wprost proporcjonalnie do ilości załadowanych danych.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool

Usługi

Aby opracować nasz nowy produkt specjalnie jako platformę aplikacyjną, stworzyliśmy komponent umożliwiający wdrażanie na nim usług i bibliotek.

Usługi to nie tylko małe fragmenty kodu działające na niektórych polach. Mogą to być dość duże i złożone struktury będące częścią klastra, sprawdzające dane referencyjne, uruchamiające logikę biznesową i zwracające odpowiedzi. Eksportujemy również schemat usługi do GraphQL, a konsument otrzymuje uniwersalny punkt dostępu do danych, z możliwością introspekcji w całym modelu. To jest bardzo wygodne.

Ponieważ usługi zawierają znacznie więcej funkcji, zdecydowaliśmy, że powinny istnieć biblioteki, w których będziemy przenosić często używany kod. Dodaliśmy je do bezpiecznego środowiska, po wcześniejszym sprawdzeniu, czy niczego nam to nie psuje. A teraz możemy przypisać dodatkowe środowiska do funkcji w postaci bibliotek.

Chcieliśmy mieć platformę nie tylko do przechowywania, ale także do przetwarzania danych. A ponieważ mieliśmy już sporo replik i fragmentów, zaimplementowaliśmy rodzaj przetwarzania rozproszonego i nazwaliśmy to map redukcja, ponieważ okazało się, że jest podobne do oryginalnej redukcji mapy.

Stare systemy

Nie wszystkie nasze starsze systemy mogą wywoływać nas przez HTTP i używać GraphQL, chociaż obsługują ten protokół. Dlatego stworzyliśmy mechanizm, który pozwala na replikację danych do tych systemów.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Jeśli coś się dla nas zmieni, w roli Storage zostaną uruchomione unikalne wyzwalacze, a wiadomość ze zmianami trafi do kolejki przetwarzania. Jest wysyłany do systemu zewnętrznego przy użyciu osobnej roli replikatora. Ta rola nie przechowuje stanu.

Nowe ulepszenia

Jak pamiętacie, z biznesowego punktu widzenia robiliśmy nagrywanie asynchroniczne. Ale potem zdali sobie sprawę, że to nie wystarczy, ponieważ istnieje klasa systemów, które muszą natychmiast otrzymać odpowiedź na temat statusu operacji. Rozszerzyliśmy więc nasz GraphQL i dodaliśmy mutacje. Organicznie wpisują się w istniejący paradygmat pracy z danymi. Dla nas jest to pojedynczy punkt umożliwiający zarówno czytanie, jak i pisanie dla innej klasy systemów.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Zdaliśmy sobie także sprawę, że same usługi nam nie wystarczą, bo raportów jest dość dużo i trzeba je budować raz dziennie, tygodniowo, miesięcznie. Może to zająć dużo czasu, a raporty mogą nawet zablokować pętlę zdarzeń Tarantool. Dlatego stworzyliśmy osobne role: planisty i biegacza. Biegacze nie przechowują stanu. Wykonują ciężkie zadania, których nie jesteśmy w stanie obliczyć na bieżąco. Rola planisty monitoruje harmonogram uruchamiania tych zadań, który jest opisany w konfiguracji. Same zadania przechowywane są w tym samym miejscu co dane biznesowe. Gdy nadejdzie odpowiedni moment, planista przejmuje zadanie, przekazuje je biegaczowi, który je liczy i zapisuje wynik.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Nie wszystkie zadania muszą być uruchamiane zgodnie z harmonogramem. Niektóre raporty należy czytać na żądanie. Gdy tylko pojawi się to wymaganie, w piaskownicy tworzone jest zadanie i wysyłane do biegacza w celu wykonania. Po pewnym czasie użytkownik otrzymuje asynchroniczną odpowiedź, że wszystko zostało przeliczone i raport jest gotowy.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Początkowo trzymaliśmy się paradygmatu przechowywania wszystkich danych, wersjonowania ich i nieusuwania. Ale w życiu od czasu do czasu trzeba coś usunąć, głównie jakieś surowe lub pośrednie informacje. Na podstawie wygaśnięcia stworzyliśmy mechanizm czyszczenia magazynu z nieaktualnych danych.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool
Rozumiemy również, że prędzej czy później nadejdzie sytuacja, gdy w pamięci zabraknie miejsca na przechowywanie danych, a mimo to dane będą musiały zostać zapisane. W tym celu wkrótce udostępnimy pamięć dyskową.

Jak zbudowaliśmy rdzeń działalności inwestycyjnej Alfa-Banku w oparciu o Tarantool

wniosek

Zaczęliśmy od zadania załadowania danych do jednego modelu i spędziliśmy trzy miesiące na jego opracowywaniu. Mieliśmy sześć systemów dostarczania danych. Cały kod transformacji do jednego modelu to około 30 tysięcy linii w Lua. A większość pracy jest jeszcze przed nami. Czasami brakuje motywacji ze strony sąsiednich zespołów, a istnieje wiele okoliczności, które komplikują pracę. Jeśli kiedykolwiek staniesz przed podobnym zadaniem, pomnóż czas, który wydaje ci się normalny na jego realizację, przez trzy, a nawet cztery.

Pamiętaj też, że istniejących problemów w procesach biznesowych nie da się rozwiązać za pomocą nowego SZBD, nawet bardzo produktywnego. Co miałem na myśli? Na początku naszego projektu stworzyliśmy wśród klientów wrażenie, że teraz wprowadzimy nową, szybką bazę danych i będziemy żyć! Procesy będą przebiegać szybciej, wszystko będzie dobrze. Tak naprawdę technologia nie rozwiązuje problemów, jakie mają procesy biznesowe, ponieważ procesami biznesowymi są ludzie. I trzeba pracować z ludźmi, a nie z technologią.

Rozwój oparty na testach może być bolesny i czasochłonny na wczesnych etapach. Ale pozytywny efekt będzie zauważalny nawet w krótkiej perspektywie, kiedy nie trzeba nic robić, aby przeprowadzić testy regresyjne.

Niezwykle ważne jest przeprowadzanie testów obciążeniowych na wszystkich etapach rozwoju. Im szybciej zauważysz jakąś wadę w architekturze, tym łatwiej będzie ją naprawić, co pozwoli Ci zaoszczędzić dużo czasu w przyszłości.

Z Luą nie dzieje się nic złego. Pisać w nim może nauczyć się każdy: programista Java, programista JavaScript, programista Pythona, front-end lub back-end. Piszą o tym nawet nasi analitycy.

Kiedy mówimy o tym, że nie mamy SQL, ludzie przerażają. „Jak zdobyć dane bez SQL? Czy to jest możliwe? Z pewnością. W systemie klasy OLTP SQL nie jest potrzebny. Istnieje alternatywa w postaci jakiegoś języka, który natychmiast przywraca widok zorientowany na dokument. Na przykład GraphQL. Istnieje alternatywa w postaci przetwarzania rozproszonego.

Jeśli rozumiesz, że będziesz musiał skalować, zaprojektuj swoje rozwiązanie na Tarantoolu w taki sposób, aby mogło działać równolegle na dziesiątkach instancji Tarantool. Jeśli tego nie zrobisz, będzie to później trudne i bolesne, ponieważ Tarantool może efektywnie wykorzystać tylko jeden rdzeń procesora.

Źródło: www.habr.com

Dodaj komentarz