Żyjemy w niezwykłych czasach, kiedy można szybko i łatwo połączyć kilka gotowych narzędzi open source, skonfigurować je z "wyłączonym umysłem" na podstawie porad ze stackoverflow, nie wgłębiając się w "wielkie litery" i wprowadzić do użytku komercyjnego. A kiedy przyjdzie czas na aktualizacje/rozszerzenia lub ktoś przypadkowo zrestartuje kilka maszyn — zrozumieć, że rozpoczął się jakiś natrętny zły sen na jawie, wszystko nagle stało się nie do poznania, nie ma drogi powrotnej, przyszłość jest niepewna i bezpieczniej jest zamiast programowania hodować pszczoły i robić ser.
Nie ma w tym nic dziwnego, że bardziej doświadczeni koledzy, z głowami posypanymi siwizną od błędów, kontemplując nieprawdopodobnie szybkie wdrożenie paczek "kontenerów" w "kostkach" na dziesiątkach serwerów w "modnych językach" z wbudowaną obsługą asynchronicznego, nieblokującego wejścia-wyjścia — skromnie się uśmiechają. I milcząco wciąż przeglądają "man ps", do krwi w oczy wgłębiają się w źródła "nginx" i piszą-piszą-piszą testy jednostkowe. Koledzy wiedzą, że najciekawsza część dopiero przed nimi, kiedy "to wszystko" pewnej nocy stanie się koszmarem przed Nowym Rokiem. Ich jedyną pomocą będzie głęboka znajomość natury unix, zapamiętane tabele stanów TCP/IP oraz podstawowe algorytmy sortowania i wyszukiwania.
Ach tak, trochę zszedłem z tematu, ale mam nadzieję, że udało się oddać stan oczekiwania.
Dziś chciałbym podzielić się naszym doświadczeniem w wdrażaniu wygodnego i niedrogiego stosu dla DataLake, który rozwiązuje większość problemów analitycznych w firmie dla zupełnie różnych działów.
Jakiś czas temu doszliśmy do zrozumienia, że firmy coraz bardziej potrzebują owoców zarówno analityki produktowej, jak i technicznej (nie wspominając o "wisienkach na torcie" w postaci machine learning) i aby zrozumieć trendy i ryzyka — trzeba gromadzić i analizować coraz więcej i więcej metryk.
Podstawowa analityka techniczna w "Bitrix24"
Kilka lat temu, równocześnie z uruchomieniem serwisu „Bitrix24”, aktywnie inwestowaliśmy czas i zasoby w stworzenie prostej i niezawodnej platformy analitycznej, która pomogłaby szybko dostrzegać problemy w infrastrukturze i zaplanować najbliższy krok. Oczywiście, woleliśmy skorzystać z gotowych narzędzi, maksymalnie prostych i intuicyjnych. W rezultacie wybrano nagios do monitorowania oraz munin do analityki i wizualizacji. Teraz mamy tysiące kontroli w nagiosie, setki wykresów w muninie, a koledzy codziennie i skutecznie z nich korzystają. Metryki są zrozumiałe, wykresy klarowne, system działa niezawodnie od kilku lat, a regularnie dodawane są nowe testy i wykresy: wprowadzamy nową usługę do eksploatacji — dodajemy kilka testów i wykresów. Powodzenia.
Ręka na pulsie — rozszerzona analiza techniczna
Pragnienie uzyskania informacji o problemach „jak najszybciej” skłoniło nas do aktywnych eksperymentów z prostymi i przejrzystymi narzędziami — pinba i xhprof.
Pinba przesyłała nam w pakietach UDP statystyki dotyczące prędkości działania części stron internetowych na PHP, a w trybie online mogliśmy zobaczyć w magazynie MySQL (pinba dostarcza własny silnik MySQL do szybkiej analizy zdarzeń) krótki wykaz problemów i szybko na nie reagować. A xhprof automatycznie zbierał wykresy wykonania najwolniejszych stron PHP klientów i analizował, co mogło do tego prowadzić — na spokojnie, popijając herbatę lub coś mocniejszego.
Jakiś czas temu narzędzia zostały wzbogacone o kolejny, dość prosty i przejrzysty silnik oparty na algorytmie indeksowania odwrotnego, doskonale zaimplementowany w legendarnej bibliotece Lucene — Elastic/Kibana. Prosta idea wielowątkowego zapisu dokumentów do indeksu odwrotnego Lucene w oparciu o zdarzenia w logach oraz szybkie wyszukiwanie z użyciem podziału na fasety — okazała się naprawdę przydatna.
Pomimo dość technicznego wyglądu wizualizacji w Kibanie z „przeciekającymi w górę” niskopoziomowymi koncepcjami typu „bucket” i na nowo wynalezionym językiem zapomnianej równości algebraicznej — narzędzie stało się dla nas dużą pomocą w następujących zadaniach:
- Ile błędów PHP miała klient Bitrix24 na portalu p1 w ciągu ostatniej godziny i jakie to były? Zrozumieć, wybaczyć i szybko naprawić.
- Ile wideo połączeń zostało zrealizowanych na portalach w Niemczech w ciągu ostatnich 24 godzin, w jakiej jakości i czy wystąpiły problemy z kanałem/siecią?
- Jak dobrze działa funkcjonalność systemu (nasze rozszerzenie w C dla PHP), skompilowana z źródeł w ostatniej aktualizacji serwisu i wypuszczona dla klientów? Czy nie ma segfaultów?
- Czy dane klientów są przechowywane w pamięci PHP? Czy nie występują błędy przekroczenia przydzielonej pamięci procesów: „out of memory”? Znaleźć i neutralizować.
Oto konkretny przykład. Mimo dokładnego i wielowarstwowego testowania, klient w bardzo nietypowym przypadku i z uszkodzonymi danymi wejściowymi napotkał nieprzyjemny i niespodziewany błąd. Rozległ się sygnał alarmowy i rozpoczęto proces szybkiej naprawy:

Dodatkowo, kibana umożliwia organizację powiadomień o wskazanych zdarzeniach i w krótkim czasie z narzędzia zaczęło korzystać dziesiątki pracowników z różnych działów — od wsparcia technicznego i rozwoju po QA.
Aktywność każdego działu w firmie stała się łatwa do śledzenia i mierzenia — zamiast ręcznej analizy logów na serwerach wystarczy raz skonfigurować parsowanie logów i ich wysyłanie do klastra elastic, aby cieszyć się na przykład obserwowaniem w dashboardzie kibana liczby sprzedanych dwugłowych kociąt, wydrukowanych na drukarce 3D w zeszłym miesiącu księżycowym.
Podstawowa analiza biznesowa
Wszystkie firmy wiedzą, że często analiza biznesowa zaczyna się od ekstremalnie aktywnego korzystania, tak, tak, z Excela. Ale najważniejsze, aby na nim się nie skończyła. Dobrze robi jeszcze chmurny Google Analytics — do dobrego szybko się przyzwyczajamy.
W naszej, harmonijnie rozwijającej się firmie, zaczęli się pojawiać "prorocy" bardziej intensywnej pracy z większymi danymi. Regularnie pojawiały się wymagania dotyczące głębszych i bardziej wieloaspektowych raportów, a staraniami chłopaków z różnych działów zorganizowano proste i praktyczne rozwiązanie — połączenie ClickHouse i PowerBI.
Przez dość długi czas to elastyczne rozwiązanie doskonale pomagało, ale stopniowo zaczęło docierać zrozumienie, że ClickHouse — nie jest gumowy i nie można nad nim tak się znęcać.
Ważne jest, aby dobrze zrozumieć, że ClickHouse, podobnie jak Druid, Vertica czy Amazon RedShift (który bazuje na Postgres), to silniki analityczne zoptymalizowane do wygodnej analizy (suma, agregacje, minimum-maksimum w kolumnach i trochę można dołączać), ponieważ są zorganizowane dla efektywnego przechowywania kolumn r tabeli relacyjnych, w przeciwieństwie do znanego nam MySQL i innych baz danych (o układzie wierszy).
W istocie ClickHouse to jedynie bardziej pojemna „baza” danych, z niezbyt wygodnym wstawianiem punktowym (tak zaplanowane, wszystko w porządku), ale z przyjemną analityką i zestawem interesujących, potężnych funkcji do pracy z danymi. Tak, można nawet stworzyć klaster — ale rozumiecie, że nie jest całkiem poprawne używać mikroskopu do wbijania gwoździ i zaczęliśmy szukać innych rozwiązań.
Popyt na Pythona i analityków
W naszej firmie jest wielu programistów, którzy piszą kod prawie każdego dnia przez 10-20 lat w PHP, JavaScript, C#, C/C++, Java, Go, Rust, Python, Bash. Mamy również wielu doświadczonych administratorów systemów, którzy przeszli przez niejedną całkowicie niewiarygodną katastrofę, która nie mieści się w prawach statystyki (na przykład, gdy większość dysków w RAID-10 zostaje zniszczona podczas silnego uderzenia pioruna). W takich warunkach przez długi czas nie było jasne, czym jest „analityk w Pythonie”. Python jest jak PHP, tylko nazwa jest nieco dłuższa, a ślad substancji zmieniających świadomość w kodzie źródłowym interpretera jest nieco mniejszy. Jednak w miarę tworzenia coraz to nowszych raportów analitycznych doświadczeni programiści coraz bardziej zaczęli dostrzegać znaczenie wąskiej specjalizacji w narzędziach takich jak numpy, pandas, matplotlib, seaborn.
Decydującą rolę, prawdopodobnie, odegrały nagłe omdlenia pracowników w wyniku połączenia słów „regresja logistyczna” oraz demonstracja efektywnego tworzenia raportów na dużych zbiorach danych z pomocą, tak, tak, pyspark.
Apache Spark, jego paradygmat funkcyjny, na który doskonale pasuje algebra relacyjna, wywarł tak ogromne wrażenie na programistach przyzwyczajonych do MySQL, że konieczność wzmocnienia szeregów doświadczonymi analitykami stała się jasna jak dzień.
Dalsze próby Apache Spark/Hadoop wznieść się i co poszło nie całkiem zgodnie ze scenariuszem
Jednak wkrótce stało się jasne, że ze Spark, najwyraźniej, coś systemowo nie jest w porządku, bądź po prostu trzeba lepiej myć ręce. Jeśli stos Hadoop/MapReduce/Lucene był tworzony przez doświadczonych programistów, co jest oczywiste, jeśli spojrzeć na źródła w Javie lub pomysły Douga Cuttinga w Lucene, to Spark, nagle, napisany jest w bardzo kontrowersyjnym z praktycznego punktu widzenia, nie rozwijającym się egzotycznym języku Scala. A regularne awarie obliczeń w klastrze Spark z powodu nielogicznej i niezbyt przejrzystej pracy z alokacją pamięci pod operacje reduce (wylatuje od razu wiele kluczy) — stworzyło wokół niego aurę czegoś, co ma dużo do zrobienia. Dodatkowo sytuację pogarszała duża liczba dziwnych otwartych portów, tymczasowych plików rosnących w najmniej zrozumiałych miejscach i ogromna liczba zależności jar — co wywoływało u administratorów systemów jedną, dobrze znaną od dziecka emocję: niezmierną nienawiść (a może trzeba było myć ręce mydłem).
Przeżyliśmy kilka wewnętrznych projektów analitycznych, które intensywnie wykorzystywały Apache Spark (w tym Spark Streaming, Spark SQL) oraz ekosystem Hadoop (i inne temu podobne). Pomimo tego, że z czasem nauczyliśmy się dobrze przygotowywać i monitorować „to” i „ono” praktycznie przestało niespodziewanie padać z powodu zmiany charakteru danych i nierównowagi równomiernego haszowania RDD, coraz silniejsze było pragnienie posiadania czegoś już gotowego, aktualizowanego i zarządzanego gdzieś w chmurze. W tym czasie spróbowaliśmy skorzystać z gotowej chmurowej wersji Amazon Web Services — i następnie staraliśmy się rozwiązywać zadania już na niej. EMR to przygotowany przez Amazona Apache Spark z dodatkowym oprogramowaniem z ekosystemu, mniej więcej jak zestaw Cloudera/Hortonworks.
„Gumowe” magazynowanie plików do analizy — pilna potrzeba
Doświadczenie „przygotowywania” Hadoop/Spark z oparzeniami różnych części ciała nie poszło na marne. Coraz wyraźniej rysowała się potrzeba stworzenia jednego niedrogiego i niezawodnego magazynu plików, który byłby odporny na awarie sprzętowe i w którym można byłoby przechowywać pliki w różnych formatach z różnych systemów oraz wykonywać na tych danych efektywne i w rozsądnym czasie realizowane wybory do raportów.
Chciałbym, aby aktualizacja oprogramowania tej platformy nie zamieniała się w noworoczną nocną koszmar z czytaniem 20-stronicowych śladów Java i analizowaniem kilometrów szczegółowych logów działania klastra za pomocą Spark History Server i lupy. Chciałbym mieć prosty i przejrzysty instrument, który nie wymagałby regularnego zagłębiania się w szczegóły, jeśli standardowe zapytanie MapReduce przestaje działać z powodu braku pamięci węzła redukującego dane przy nie najlepiej dobranym algorytmie partycjonowania danych źródłowych.
Amazon S3 - kandydat na DataLake?
Doświadczenie z Hadoop/MapReduce nauczyło mnie, że potrzebna jest zarówno skalowalna, niezawodna system plików, jak i skalowalne węzły robocze, które "przybywają" bliżej danych, aby nie przesyłać danych przez sieć. Węzły robocze powinny umieć czytać dane w różnych formatach, ale raczej nie powinny odczytywać zbędnych informacji i powinny mieć możliwość przechowywania danych w formatach wygodnych dla węzłów roboczych.
Jeszcze raz - główny pomysł. Nie ma ochoty na "załadowanie" dużych danych do jednego silnika analitycznego klastra, który i tak prędzej czy później się będzie dusił i będzie konieczne jego brzydkie dzielenie. Chciałbym przechowywać pliki, po prostu pliki, w zrozumiałym formacie i wykonywać na nich efektywne zapytania analityczne różnymi, ale zrozumiałymi narzędziami. A plików w różnych formatach będzie coraz więcej. I lepiej podzielić nie silnik, lecz dane źródłowe. Potrzebujemy skalowalnego i uniwersalnego DataLake, postanowiliśmy…
A co jeśli przechowywać pliki w znanym i wielu osobom skalowalnym chmurze Amazon S3, nie martwiąc się o własne przygotowanie bitewnych kotletów z Hadoop?
Jasne, danych osobowych „nie można”, ale inne dane, jeśli przenieść je tam i „efektywnie nimi operować”?
Klastrowo-bigdata-analizujący ekosystem Amazon Web Services - bardzo prostymi słowami
Sądząc po naszym doświadczeniu z AWS, tam od dawna i aktywnie używa się pod różnymi sosami Apache Hadoop/MapReduce, na przykład w usłudze DataPipeline (pozdrawiam kolegów, nauczyli się to dobrze przygotowywać). Tutaj skonfigurowaliśmy kopie zapasowe z różnych usług z tabel DynamoDB:

I są one regularnie wykonywane na wbudowanych klastrach Hadoop/MapReduce jak zegarki od kilku lat. „Skonfigurowałem i zapomniałem”:

Można również skutecznie zajmować się datasańskim, uruchamiając dla analityków notebooki Jupiter w chmurze i wykorzystując je do szkolenia oraz wdrażania modeli AI na platformie AWS SageMaker. Oto jak to u nas wygląda:

Tak, można uruchomić notebooka w chmurze dla siebie lub analityka i podłączyć go do klastra Hadoop/Spark, obliczyć i wszystko później "załatwić":

Jest to rzeczywiście wygodne dla poszczególnych projektów analitycznych, a w niektórych z powodzeniem wykorzystywaliśmy usługę EMR do masowych obliczeń i analiz. A co z systemowym rozwiązaniem dla DataLake, czy uda się? W tym momencie byliśmy na granicy nadziei i rozpaczy i kontynuowaliśmy poszukiwania.
AWS Glue to starannie zapakowany Apache Spark "na sterydach".
Okazało się, że AWS ma "swoją" wersję stosu "Hive/Pig/Spark". Rolę Hive, czyli katalogu plików i ich typów w DataLake, pełni usługa „Data catalog”, która nie ukrywa swojej kompatybilności z formatem Apache Hive. W tej usłudze należy dodać informacje o tym, gdzie znajdują się Twoje pliki i w jakim są formacie. Dane mogą być przechowywane nie tylko w s3, ale i w bazie danych, ale o tym nie w tym poście. Oto jak zorganizowany jest u nas katalog danych DataLake:

Pliki są zarejestrowane, świetnie. Jeśli pliki zostały zaktualizowane — uruchamiamy ręcznie lub według harmonogramu crawlerów, które zaktualizują informacje o nich z jeziora i zapiszą je. Następnie dane z jeziora można przetwarzać, a wyniki gdzieś eksportować. W najprostszym przypadku — także eksportujemy do s3. Przetwarzanie danych można przeprowadzać wszędzie, ale proponuje się skonfigurowanie procesu przetwarzania na klastrze Apache Spark, wykorzystując rozszerzone możliwości poprzez API AWS Glue. W istocie można wziąć stary dobry i znany kod w Pythonie z wykorzystaniem biblioteki pyspark i skonfigurować jego uruchomienie na N węzłach klastra o jakiejś mocy z monitoringiem, bez grzebania w tajnikach Hadoop i przenoszenia kontenerów dockerowych oraz rozwiązywania konfliktów zależności.
Jeszcze raz — prosta idea. Nie trzeba konfigurować Apache Spark, wystarczy napisać kod w Pythonie dla pyspark, przetestować go lokalnie na komputerze stacjonarnym, a następnie uruchomić na dużym klastrze w chmurze, wskazując, gdzie znajdują się dane źródłowe i gdzie umieścić wynik. Czasami jest to potrzebne i użyteczne, a oto jak to jest skonfigurowane u nas:

W ten sposób, jeśli trzeba obliczyć coś na klastrze Spark na danych w s3 — piszemy kod w Pythonie/pyspark, testujemy i w drogę do chmury.
A co z orkiestracją? A jeśli zadanie się nie uda? Tak, proponuje się stworzenie ładnego pipeline'u w stylu Apache Pig i nawet to przetestowaliśmy, ale zdecydowaliśmy się na użycie naszego głęboko dostosowanego systemu orkiestracji opartego na PHP i JavaScript (rozumiem, że może to budzić mój wewnętrzny dysonans, ale działa od lat i bez błędów).

Format plików przechowywanych w jeziorze danych — klucz do wydajności
Bardzo, bardzo ważne jest zrozumienie jeszcze dwóch kluczowych kwestii. Aby zapytania o dane pliki w jeziorze były jak najszybsze i aby wydajność nie spadała przy dodawaniu nowej informacji, należy:
- Kolumny plików przechowywać osobno (aby nie było potrzeby czytania wszystkich wierszy, by zrozumieć, co jest w kolumnach). W tym celu przyjęliśmy format parquet z kompresją
- Bardzo ważne jest dzielenie plików na foldery w duchu: język, rok, miesiąc, dzień, tydzień. Silniki, które rozumieją ten typ shardingu, będą przeszukiwać tylko odpowiednie foldery, nie przeszukując wszystkich danych po kolei.
W zasadzie w ten sposób dostarczasz dane źródłowe w najbardziej efektywnej formie dla nakładanych powyżej silników analitycznych, które również potrafią selektywnie wchodzić do podzielonych folderów i czytać z plików tylko potrzebne kolumny. Nie trzeba nigdzie „wrzucać” danych (bo przechowalnia może po prostu nie wytrzymać) — po prostu od razu rozsądnie umieść je w systemie plików w odpowiednim formacie. Oczywiście należy zrozumieć, że przechowywanie ogromnego pliku csv w DataLake, który trzeba najpierw odczytać liniami klastrami, aby wydobyć kolumny — nie jest zbyt rozsądne. Przemyśl jeszcze raz dwa powyższe punkty, jeśli nie jest jasne, po co to wszystko.
AWS Athena — „diabeł” z pudełka
I tu, tworząc jezioro, natknęliśmy się nieco przypadkowo na Amazon Athena. Okazało się, że starannie ułożone pliki ogromnych logów w odpowiednim (parquet) formacie kolumnowym w shardach-folderach — można bardzo szybko przeszukiwać i tworzyć niezwykle informacyjne raporty BEZ klastrów Apache Spark/Glue.
Silnik Athena, działający na danych w s3, oparty jest na legendarnym — przedstawiciel rodziny podejść MPP (massive parallel processing) do przetwarzania danych, pobierający dane tam, gdzie leżą, od s3 i Hadoop do Cassandry i zwykłych plików tekstowych. Wystarczy poprosić Athenę o wykonanie zapytania SQL, a reszta „działa szybko i sama”. Ważne jest, że Athena jest „inteligentna”, wchodzi tylko do potrzebnych sharded folderów i odczytuje tylko potrzebne kolumny w zapytaniu.
Opłaty za zapytania do Atheny są również ciekawe. Płacimy za . Tzn. nie za liczbę maszyn w klastrze co minutę, ale… za rzeczywiście przeszukane na 100-500 maszynach dane, które są niezbędne do wykonania zapytania.
A zapraszając tylko potrzebne kolumny z odpowiednio sharded folderów, okazało się, że usługa Athena kosztuje nas dziesiątki dolarów miesięcznie. To świetnie, prawie za darmo, w porównaniu do analityki na klastrach!
Oto, jak shardujemy swoje dane w s3:

W efekcie, w krótkim czasie, w firmie bardzo różne działy, od bezpieczeństwa informacji po analitykę, zaczęły aktywnie składać zapytania do Atheny i szybko, w ciągu sekund, otrzymywać przydatne odpowiedzi z „wielkich” danych za dość długie okresy: miesiące, półrocze itd.
Ale poszliśmy dalej i zaczęliśmy szukać odpowiedzi w chmurze : analityk w znanej konsoli pisze zapytanie SQL, które na 100-500 maszyn „za grosze” przeszukuje dane w s3 i zazwyczaj zwraca odpowiedź w jednostkach sekund. Wygodne. I szybkie. Nadal w to nie wierzę.
W rezultacie, decydując się na przechowywanie danych w s3, w efektywnym formacie kolumnowym z rozsądnym shardowaniem danych w folderach… otrzymaliśmy DataLake oraz szybki i tani silnik analityczny — za darmo. I stał się on bardzo popularny w firmie, ponieważ rozumie SQL i działa znacznie szybciej niż poprzez uruchamianie/zatrzymywanie/konfigurowanie klastrów. „A jeśli wynik jest taki sam, po co płacić więcej?”
Zapytanie do Atheny wygląda mniej więcej tak. Oczywiście, jeśli chcesz, możesz stworzyć dość , ale ograniczymy się do prostego grupowania. Zobaczmy, jakie kody odpowiedzi miał klient kilka tygodni temu w logach pracy serwera WWW i upewnijmy się, że nie ma błędów:

Wnioski
Przechodząc, można powiedzieć, że długo, ale bolesną drogę, nieustannie ocenialiśmy ryzyka oraz poziom złożoności i koszty wsparcia, znaleźliśmy rozwiązanie dla DataLake i analityki, które ciągle nas zachwyca swoją prędkością i kosztem posiadania.
Okazało się, że zbudowanie efektywnego, szybkiego i taniego w eksploatacji DataLake dla potrzeb zupełnie różnych działów firmy — jest na wyciągnięcie ręki nawet dla doświadczonych programistów, którzy nigdy nie pracowali jako architekci i nie potrafią rysować kwadratów na kwadratach ze strzałkami oraz znając 50 terminów z ekosystemu Hadoop.
Na początku drogi głowa bolała od licznych dzikich zoologicznych ogrodów oprogramowania otwartego i zamkniętego oraz rozumienia ciężaru odpowiedzialności przed potomkami. Po prostu zacznij budować swój DataLake od prostych narzędzi: nagios/munin -> elastic/kibana -> Hadoop/Spark/s3 …, zbierając opinie i dogłębnie rozumiejąc fizykę zachodzących procesów. Wszystko, co skomplikowane i mętne — zostaw dla wrogów i konkurencji.
Jeśli nie chcesz do chmury i lubisz wspierać, aktualizować i łatać otwarte projekty, można zbudować podobny do naszego model lokalnie, na tanich biurowych komputerach z Hadoop i Presto na górze. Najważniejsze — nie zatrzymywać się i iść naprzód, liczyć, szukać prostych i jasnych rozwiązań, a na pewno się uda! Powodzenia wszystkim i do zobaczenia!
Źródło: habr.com
