Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Logi to ważna część systemu, która pozwala zrozumieć, czy działa on zgodnie z oczekiwaniami (lub nie). W kontekście architektury mikroserwisowej praca z logami staje się odrębną dyscypliną specjalnej olimpiady. Należy rozwiązać od razu szereg kwestii:

  • jak pisać logi z aplikacji;
  • gdzie pisać logi;
  • jak dostarczać logi do przechowywania i przetwarzania;
  • jak przetwarzać i przechowywać logi.

Wykorzystanie popularnych dzisiaj technologii konteneryzacji dodaje piasku na górę gór na polu możliwości rozwiązania problemu.

O tym dokładnie mówił referat Jurija Buszmielewa „Karta gór na polu zbierania i dostarczania logów”

Odtwarzaj wideo

Kogo to interesuje, zapraszam dalej.

Nazywam się Jurij Buszmielew. Pracuję w Lazada. Dziś opowiem o tym, jak tworzyliśmy nasze logi, jak je zbieraliśmy i co do nich piszemy.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Skąd pochodzimy? Kim jesteśmy? Lazada to numer 1 w e-commerce w sześciu krajach Azji Południowo-Wschodniej. Wszystkie te kraje są rozproszone po centrach danych. Obecnie mamy 4 centra danych. Dlaczego to ważne? Ponieważ niektóre rozwiązania były podyktowane bardzo słabym łączem między centrami. Mamy architekturę mikroserwisową. Byłem zaskoczony, odkrywając, że mamy już 80 mikroserwisów. Kiedy zaczynałem zadanie z logami, było ich tylko 20. Ponadto istnieje dość duża część starszego kodu PHP, z którą również trzeba żyć i się zgadzać. Wszystko to generuje nam w tej chwili ponad 6 milionów wiadomości na minutę w całym systemie. Następnie pokażę, jak próbujemy z tym żyć i dlaczego jest to takie.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Z tymi 6 milionami wiadomości musimy jakoś żyć. Co powinniśmy z nimi zrobić? 6 milionów wiadomości, które należy:

  • wysłać z aplikacji
  • otrzymać do dostarczenia
  • dostarczyć do analizy i przechowywania.
  • analizować
  • jakoś przechowywać.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Kiedy pojawiły się trzy miliony wiadomości, wyglądałem mniej więcej tak. Zaczynaliśmy od jakichś groszy. Oczywiście, że zapisujemy logi aplikacji. Na przykład, nie udało się połączyć z bazą danych, udało się połączyć z bazą danych, ale nie udało się czegoś przeczytać. Ale poza tym, każdy nasz mikroserwis zapisuje również log dostępu. Każde zapytanie, które trafia do mikroserwisu, ląduje w logu. Po co to robimy? Programiści chcą mieć możliwość śledzenia. W każdym logu dostępu znajduje się pole traceid, według którego specjalny interfejs rozwija całą sekwencję i ładnie pokazuje ślad. Ślad pokazuje, jak przebiegało zapytanie, i to pomaga naszym programistom szybciej radzić sobie z różnymi nieznanymi sprawami.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Jak z tym żyć? Teraz w skrócie opowiem o możliwościach — jak w ogóle ten problem jest rozwiązany. Jak rozwiązać zadanie zbierania, przesyłania i przechowywania logów.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Jak pisać z aplikacji? Oczywiście, że są różne sposoby. W szczególności istnieją najlepsze praktyki, o których mówią modni koledzy. Jest stary styl w dwóch wersjach, jak opowiadali dziadkowie. Są też inne sposoby.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Z zbieraniem logów sytuacja jest podobna. Nie ma zbyt wielu opcji rozwiązania tej konkretnej części. Już jest ich więcej, ale wciąż nie tak wiele.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Natomiast jeśli chodzi o dostarczanie i późniejszą analizę — liczba wariacji zaczyna ogromnie rosnąć. Nie będę teraz opisywał każdego wariantu. Myślę, że podstawowe opcje są znane każdemu, kto interesował się tematem.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Pokażę, jak robiliśmy to w Lazada i jak właściwie to wszystko się zaczęło.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Rok temu dołączyłem do Lazada i wysłano mnie do projektu dotyczącego logów. Było to mniej więcej tak. Log z aplikacji był zapisywany w stdout i stderr. Zrobiliśmy to zgodnie z trendami. Ale następnie programiści wyrzucili to ze standardowych strumieni, a potem jakoś specjaliści od infrastruktury się tym zajmą. Między specjalistami od infrastruktury a programistami są jeszcze wydawcy, którzy powiedzieli: „eee... no dobrze, zamknijmy je po prostu w pliku przez shell i to wszystko”. A ponieważ wszystko to było w kontenerze, to zapakowaliśmy to bezpośrednio w samym kontenerze, zamapowaliśmy katalog wewnątrz i położyliśmy to tam. Myślę, że wszystkim jest mniej więcej jasne, co z tego wyszło.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Zobaczmy teraz nieco dalej. Jak dostarczaliśmy te logi. Ktoś wybrał td-agent, który tak naprawdę jest fluentd, ale nie do końca fluentd. Nie do końca zrozumiałem relacje między tymi dwoma projektami, ale wydaje się, że dotyczą tego samego. I ten fluentd, napisany w Ruby, czytał pliki logów, parsował je do JSON przy użyciu jakichś wyrażeń regularnych. Następnie wysyłał je do Kafki. Przy czym dla każdego API mieliśmy 4 oddzielne topiki w Kafce. Dlaczego 4? Ponieważ było live, było staging, a także stdout i stderr. Programiści je tworzyli, a inżynierowie infrastruktury musieli je tworzyć w Kafce. Ponadto, Kafkę kontrolował inny dział. Dlatego trzeba było stworzyć tiket, aby oni stworzyli te 4 topiki dla każdego API. Wszyscy o tym zapominali. Ogólnie rzecz biorąc, był to bałagan i chaos.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Co dalej z tym robiliśmy? Wysyłaliśmy to do Kafki. Następnie połowa logów trafiała do Logstasha. Druga połowa logów była dzielona. Część leciała do jednego Grayloga, część – do drugiego Grayloga. Ostatecznie wszystko to trafiało do jednego klastra Elasticsearch. To znaczy, cały ten bałagan ostatecznie trafiał tam. Tak nie powinno się robić!

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Tak to wygląda, jeśli spojrzymy na to z dalszej perspektywy. Nie róbcie tak! Tutaj cyframi od razu zaznaczone są problematyczne miejsca. W rzeczywistości jest ich więcej, ale 6 to te naprawdę problematyczne, z którymi trzeba coś zrobić. O nich opowiem teraz oddzielnie.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Tutaj (1,2,3) zapisujemy pliki i, odpowiednio, mamy tutaj od razu trzy pułapki.

Pierwsza (1) – musimy je gdzieś zapisać. Nie zawsze chcielibyśmy dawać API możliwość zapisywania bezpośrednio do pliku. Pożądane byłoby, aby API było izolowane w kontenerze, a jeszcze lepiej – aby było w trybie tylko do odczytu. Jestem administratorem systemów, więc mam nieco alternatywne spojrzenie na te sprawy.

Druga kwestia (2,3) — otrzymujemy dużo zapytań do API. API zapisuje dużo danych do pliku. Pliki rosną. Musimy je rotować. Bo inaczej nie zaopatrujemy się w żadne dyski. Rotacja jest zła, ponieważ są one przekierowane przez shell do katalogu. Nie możemy ich rotować. Nie można powiedzieć aplikacji, aby ponownie otworzyła deskryptory. Bo deweloperzy spojrzą na ciebie jak na idiotę: „Jakie deskryptory? Napisaliśmy w stdout”. Infrastrukturyści zrealizowali copytruncate w logrotate, które po prostu tworzy kopię pliku i truncuje oryginał. W związku z tym, między tymi procesami kopiowania zazwyczaj kończy się miejsce na dysku.

(4) Mieliśmy różne formaty w różnych API. Nieco się różniły, ale trzeba było pisać różne regexp. Ponieważ wszystko to było zarządzane przez Puppet, istniała duża wiązka klas z własnymi problemami. Dodatkowo, td-agent przez większość czasu mógł zjadać pamięć, zwalniać, mógł po prostu udawać, że działa i nic nie robić. Na zewnątrz nie dało się zrozumieć, że nic nie robi. W najlepszym wypadku mógł się zawiesić, a potem ktoś go podniesie. A dokładniej, przyjdzie alert i ktoś ręcznie go podniesie.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

(6) A największym koszmarem był elasticsearch. Ponieważ to była stara wersja. Nie mieliśmy wówczas dedykowanych mistrzów. Mieliśmy różnorodne logi, gdzie pola mogły się pokrywać. Różne logi różnych aplikacji mogły być zapisywane z tymi samymi nazwami pól, ale wewnątrz mogły zawierać różne dane. To znaczy, jeden log przychodzi z Integer w polu, na przykład, level. Inny log przychodzi z String w polu level. W braku statycznego mapowania otrzymujemy coś niesamowitego. Jeśli po rotacji indeksu w elasticsearch pierwsza wiadomość dotrze jako ciąg, to żyjemy normalnie. Ale jeśli pierwsza dotrze jako Integer, to wszystkie kolejne wiadomości, które dotarły jako String, po prostu się odrzucają. Ponieważ typ pola się nie zgadza.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Zaczęliśmy zadawać sobie te pytania. Postanowiliśmy nie szukać winnych.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Ale coś trzeba zrobić! Oczywistą sprawą jest to, że należy ustanowić standardy. Niektóre standardy mieliśmy już wcześniej. Niektóre wprowadziliśmy nieco później. Na szczęście, jednolity format logów dla wszystkich API został zatwierdzony w tamtym czasie. Jest on zapisany w standardach interakcji serwisów. W związku z tym, ci, którzy chcą otrzymywać logi, muszą pisać je w tym formacie. Jeśli ktoś nie pisze logów w tym formacie, to znaczy, że niczego nie gwarantujemy.

Następnie, chciałbym ustalić jednolity standard dla sposobów zapisu, dostarczania i zbierania logów. Właściwie, gdzie je pisać i czym je dostarczać. Idealna sytuacja to taka, gdzie w projektach używa się tej samej biblioteki. Istnieje oddzielna biblioteka logowania dla Go, istnieje oddzielna biblioteka dla PHP. Wszyscy, którzy z nami współpracują, powinni ich używać. Na chwilę obecną powiedziałbym, że jesteśmy na poziomie około 80%. Ale niektórzy nadal jedzą kaktusy.

I tam (na slajdzie) ledwie zaczyna się klarować "SLA na dostarczanie logów". Na razie go nie ma, ale pracujemy nad tym. Ponieważ to bardzo wygodne, kiedy infrastruktura mówi, że jeśli zapisujesz w takim a takim formacie w takie a takie miejsce i nie więcej niż N wiadomości na sekundę, to dostarczymy to z jakimś prawdopodobieństwem tam. To niweluje wiele bólu głowy. Jeśli SLA jest, to jest po prostu wspaniale!

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Jak zaczęliśmy rozwiązywać problem? Główna przeszkoda była z td-agent. Nie było jasne, gdzie się podziały nasze logi. Czy są dostarczane? Czy są zbierane? Gdzie one w ogóle są? Dlatego pierwszym krokiem była decyzja o zastąpieniu td-agent. Opcje, czym go zastąpić, tutaj krótko nakreśliłem.

Fluentd. Po pierwsze, spotkałem się z nim w poprzedniej pracy i tam również sporadycznie padał. Po drugie, to to samo, tylko w profilu.

Filebeat. Czym był dla nas wygodny? Tym, że jest na Go, a my mamy dużą wiedzę w Go. W związku z tym, jeśli coś, mogliśmy go jakoś przystosować do siebie. Dlatego go nie wzięliśmy. Aby nawet nie było pokusy do przepisania go na swój sposób.

Oczywistym rozwiązaniem dla administratora systemu pozostają różne syslogi w takiej ilości (syslog-ng/rsyslog/nxlog).

Lub napisać coś własnego, ale to odrzuciliśmy, podobnie jak filebeat. Jeśli coś pisać, to lepiej tworzyć coś użytecznego dla biznesu. Do dostarczania logów lepiej wziąć coś gotowego.

Dlatego wybór sprowadzał się właściwie do decyzji między syslog-ng a rsyslog. Skusiłem się na rsyslog, ponieważ w Puppet mieliśmy już klasy dla rsyslog i nie zauważyłem między nimi oczywistej różnicy. Tam syslog, tu syslog. Tak, u niektórych dokumentacja jest gorsza, u innych lepsza. Ten robi tak, a tamten — inaczej.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

A teraz trochę o rsyslog. Po pierwsze, jest świetny, ponieważ ma wiele modułów. Posiada zrozumiały dla człowieka RainerScript (nowoczesny język konfiguracji). Fantastycznym bonusem jest to, że mogliśmy za pomocą standardowych narzędzi zasymulować zachowanie td-agent, a dla aplikacji nic się nie zmieniło. To znaczy, zmieniamy td-agent na rsyslog, a wszystko inne na razie zostawiamy. I od razu uzyskujemy działającą dostawę. Ponadto mmnormalize to niesamowita rzecz w rsyslog. Pozwala analizować logi, ale nie za pomocą Grok i regexp. Tworzy abstrakcyjny drzewo składniowe. Analizuje logi mniej więcej tak, jak kompilator analizuje kod źródłowy. Dzięki temu działa bardzo szybko, zużywa mało CPU i w ogóle, naprawdę świetna rzecz. Jest mnóstwo innych bonusów. Nie będę się nad nimi zatrzymywał.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Rsyslog ma jeszcze wiele wad. Są one mniej więcej takie same, jak bonusy. Główne problemy — trzeba umieć go skonfigurować i dobrać odpowiednią wersję.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Zdecydowaliśmy, że będziemy pisać logi do gniazda unix. I to nie do /dev/log, ponieważ tam mamy bałagan z systemowymi logami, tam journald jest w tym pipeline. Dlatego piszmy do niestandardowego gniazda. Przypniemy je do oddzielnego zestawu reguł. Nie będziemy niczego mieszać. Wszystko będzie przejrzyste i zrozumiałe. Tak właśnie zrobiliśmy. Katalog z tymi gniazdami jest standaryzowany i przesyłany do wszystkich kontenerów. Kontenery mogą widzieć potrzebne sobie gniazdo, otwierać je i pisać do niego.

Dlaczego nie plik? Ponieważ wszyscy czytali artykuł o Baduśce, która próbowała przekazać plik do dockera i odkrywała, że po restarcie rsyslog zmienia descriptor pliku, a docker gubi ten plik. Trzyma otwarty jakiś inny, ale już nie to gniazdo, do którego piszą. Postanowiliśmy, że obejdziemy ten problem i jednocześnie obiegnziemy problem blokady.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Rsyslog wykonuje czynności wskazane na slajdzie i wysyła logi albo do relaya, albo do Kafka. Kafka odpowiada starym sposobom. Relay — to próbowałem użyć czysto rsyslog do dostarczania logów. Bez Message Queue, standardowymi środkami rsyslog. W zasadzie, to działa.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Są jednak pewne niuanse dotyczące tego, jak następnie umieszczać je w tej części (Logstash/Graylog/ES). Ta część (rsyslog-rsyslog) jest używana między centrum danych. Tutaj znajduje się skompresowane łącze TCP, które pozwala zaoszczędzić pasmo i odpowiednio zwiększa prawdopodobieństwo, że otrzymamy jakieś logi z innego centrum danych w warunkach, kiedy kanał jest zablokowany. Ponieważ mamy Indonezję, gdzie sytuacja jest zła. Tam ta problematyka występuje na stałe.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Zastanawialiśmy się, jak właściwie monitorować, z jakim prawdopodobieństwem logi, które zapisaliśmy z aplikacji, docierają do drugiego końca? Postanowiliśmy zebrać metryki. Rsyslog ma swój moduł zbierania statystyk, w którym znajdują się różne liczniki. Na przykład może pokazać ci rozmiar kolejki, lub ile wiadomości dotarło w danej akcji. Można z nich coś wyciągnąć. Ponadto ma własne liczniki, które można dostosować, a on będzie ci pokazywał, na przykład, liczbę wiadomości, które zapisało jakieś API. Następnie napisałem rsyslog_exporter w Pythonie i wysłaliśmy to wszystko do Prometheus, tworząc wykresy. Bardzo chcieliśmy metryk Graylog, ale jeszcze nie zdążyliśmy ich skonfigurować.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Z jakimi problemami się zmierzyliśmy? Problemy pojawiły się, gdy odkryliśmy (NIESPODZIEWANIE!), że nasze Live API zapisują 50 tys. wiadomości na sekundę. To tylko Live API bez stagingu. A Graylog pokazuje nam tylko 12 tysięcy wiadomości na sekundę. I pojawiło się uzasadnione pytanie, gdzie są pozostałe? Z czego wnioskujemy, że Graylog po prostu nie daje sobie rady. Spojrzeliśmy i rzeczywiście, Graylog z Elasticsearch nie radził sobie z tym ruchem.

Dalej, inne odkrycia, które poczyniliśmy w trakcie.

Zapis do gniazda jest blokowany. Jak to się stało? Kiedy używałem rsyslog do dostarczania, w pewnym momencie zepsuło się połączenie między centrami danych. W jednym miejscu zatrzymała się dostawa, inne miejsce również. Wszystko dotarło do maszyny z API, które zapisują do gniazda rsyslog. Tam zapełniła się kolejka. Następnie zapełniła się kolejka do zapisu w uniksowym gnieździe, która domyślnie wynosi 128 pakietów. A następny write() w aplikacji zostaje zablokowany. Kiedy patrzyliśmy na bibliotekę, której używamy w aplikacjach na Go, napisano, że zapis do gniazda odbywa się w trybie nieblokującym. Byliśmy pewni, że nic nie jest blokowane. Ponieważ czytaliśmy. artykuł o Baduśce, która o tym napisała. Ale jest jeden problem. Wokół tego wywołania była jeszcze nieskończona pętla, w której nieustannie próbowało się włożyć wiadomość do gniazda. To umknęło naszej uwadze. Musieliśmy przepisali bibliotekę. Od tego czasu zmieniała się ona kilka razy, ale teraz pozbyliśmy się blokad we wszystkich podsystemach. Dlatego można zatrzymać rsyslog i nic się nie stanie.

Należy monitorować rozmiar kolejek, co pomaga uniknąć tych pułapek. Po pierwsze, możemy monitorować, kiedy zaczynamy tracić wiadomości. Po drugie, możemy monitorować, że mamy w zasadzie problemy z dostarczaniem.

I jeszcze jeden nieprzyjemny aspekt — amplifikacja 10 razy w architekturze mikroserwisowej — to bardzo łatwe. Mamy niewiele przychodzących zapytań, ale z powodu grafu, po którym te wiadomości dalej przebiegają, z powodu logów dostępu, rzeczywiście zwiększamy obciążenie logów około dziesięciokrotnie. Niestety nie zdążyłem policzyć dokładnych cyfr, ale mikroserwisy — tak już są. Trzeba to mieć na uwadze. Mamy więc sytuację, że w tej chwili podsystem zbierania logów jest najbardziej obciążony w Lazada.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Jak rozwiązać problem elasticsearch? Jeśli musisz szybko uzyskać logi w jednym miejscu, aby nie biegać po wszystkich maszynach i nie zbierać ich tam, użyj pamięci plikowej. To działa niezawodnie. Można to zrobić z dowolnego serwera. Wystarczy włożyć tam dyski i zainstalować syslog. Po tym masz gwarancję, że wszystkie logi są w jednym miejscu. Potem można powoli konfigurować elasticsearch, graylog, lub coś innego. Ale już będziesz miał wszystkie logi, a co więcej, możesz je przechowywać tak długo, jak starczy pamięci dyskowej.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

W momencie mojego wystąpienia schemat wyglądał tak. Praktycznie przestaliśmy pisać do pliku. Teraz prawdopodobnie wyłączymy resztki. Na lokalnych maszynach, na których uruchomione są API, przestaniemy pisać do plików. Po pierwsze, istnieje pamięć plikowa, która działa bardzo dobrze. Po drugie, na tych maszynach ciągle kończy się miejsce, trzeba je nieustannie monitorować.

Ta część z Logstash i Graylog rzeczywiście przeszkadza. Dlatego trzeba się jej pozbyć. Trzeba wybrać coś jednego.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Postanowiliśmy zrezygnować z Logstash i Kibana. Mamy dział bezpieczeństwa. Jaki to ma związek? Związek polega na tym, że Kibana bez X-Pack i Shield nie pozwala na ograniczenie uprawnień dostępu do logów. Dlatego wybraliśmy Graylog. Ma to wszystko. Nie bardzo go lubię, ale działa. Kupiliśmy nowy sprzęt, zainstalowaliśmy tam świeżego Grayloga i przenieśliśmy wszystkie logi z rygorystycznymi formatami do oddzielnego Grayloga. Rozwiązaliśmy problem z różnymi typami tych samych pól organizacyjnie.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Co dokładnie wchodzi w nowego Grayloga? Po prostu zapisaliśmy wszystko w Dockerze. Wzięliśmy sporo serwerów, uruchomiliśmy trzy instancje Kafka, 7 serwerów Grayloga w wersji 2.3 (ponieważ chcieliśmy Elasticsearch w wersji 5). Wszystko to działało na RAID-zie z HDD. Zobaczyliśmy szybkość indeksowania do 100 tysięcy wiadomości na sekundę. Zauważyliśmy, że mamy 140 terabajtów danych tygodniowo.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

I znów kłopoty! Mamy w planach dwie wyprzedaże. Przeszliśmy przez 6 milionów wiadomości. Nasz Graylog nie nadąża przetwarzać. Musimy jakoś przetrwać.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Przetrwaliśmy w ten sposób. Dodaliśmy jeszcze kilka serwerów i SSD. Obecnie żyjemy w ten sposób. Teraz przetwarzamy już 160 tysięcy wiadomości na sekundę. Nie osiągnęliśmy jeszcze limitu, więc na razie nie wiadomo, ile tak naprawdę możemy z tego wyciągnąć.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Takie mamy plany na przyszłość. Z nich, naprawdę, najważniejsze to high availability. Na razie go nie mamy. Kilka maszyn jest skonfigurowanych identycznie, ale wszystko przechodzi przez jedną maszynę. Musimy poświęcić czas na skonfigurowanie failovera między nimi.

Zebrać metryki z Grayloga.

Ustawić limit prędkości, aby nasze jedno, szalejące API, nie zabiło nam pasma ani niczego innego.

I na koniec, podpisać jakiś SLA z deweloperami, że możemy obsłużyć tyle. Jeśli piszecie więcej, to przepraszam.

I napisać dokumentację.

Jurij Buszmeliew „Mapa grbeń na polu zbierania i dostarczania logów” — transkrypcja wykładu

Krótko mówiąc, podsumowanie wszystkiego, co przeszliśmy. Po pierwsze, standardy. Po drugie, syslog — tort. Po trzecie, rsyslog działa dokładnie tak, jak jest napisane na slajdzie. A teraz przejdźmy do pytań.

Pytania.

Pytanie: Dlaczego w końcu zdecydowaliśmy się nie brać… (filebeat?)

Odpowiedź: Trzeba pisać do pliku. Bardzo nie chciałem. Kiedy twoje API wysyła tysiące wiadomości na sekundę, nawet jeśli co godzinę będziesz rotować, to wciąż nie jest opcja. Można pisać w pipe. Na co deweloperzy mnie zapytali: „Co się stanie, jeśli proces, do którego piszemy, się zawiesi”? Po prostu nie znalazłem, co im odpowiedzieć, i powiedziałem: „Cóż, ok, nie róbmy tak.”

Pytanie: Dlaczego nie zapisujecie logów po prostu w HDFS?

Odpowiedź: To następny krok. Myśleliśmy o tym na początku, ale obecnie nie mamy zasobów, aby się tym zająć, więc pozostaje to jako rozwiązanie długoterminowe.

Pytanie: Format kolumnowy byłby bardziej odpowiedni.

Odpowiedź: Rozumiem wszystko. Jesteśmy „za” obiema rękami.

Pytanie: Piszecie do rsyslog. Tam można używać zarówno TCP, jak i UDP. Ale jeśli używacie UDP, to jak zapewniacie dostawę?

Odpowiedź: Są dwa momenty. Po pierwsze, od razu wszystkim mówię, że nie gwarantujemy dostawy logów. Kiedy programiści przychodzą i mówią: „A może zaczniemy tam pisać dane finansowe, a wy będziecie je gdzieś tam przechowywać na wypadek, gdyby coś się stało”, odpowiadamy „Świetnie! Zacznijcie blokować zapis do gniazda i róbcie to w transakcjach, aby mieć pewność, że wrzucicie to do gniazda i upewnicie się, że to odebraliśmy.” I w tym momencie wszyscy od razu tracą zainteresowanie. A skoro nie ma zainteresowania, to po co nam pytania? Jeśli nie chcecie gwarantować zapisu do gniazda, to po co mamy gwarantować dostawę? Dajemy najlepsze starania. Naprawdę staramy się dostarczyć jak najwięcej i jak najlepiej, ale nie dajemy 100% gwarancji. Dlatego nie piszcie tam danych finansowych. Do tego są bazy danych z transakcjami.

Pytanie: Kiedy API generuje jakieś wiadomości w logach i przekazuje kontrolę mikroserwisom, czy natknęliście się na problem, że wiadomości z różnych mikroserwisów przychodzą w niewłaściwej kolejności? To powoduje zamieszanie.

Odpowiedź: To normalne, że przychodzą w różnej kolejności. Trzeba być na to przygotowanym. Ponieważ jakakolwiek dostawa w sieci nie gwarantuje porządku, lub trzeba na to specjalnie przeznaczyć zasoby. Jeśli weźmiemy magazyny plików, to każde API zapisuje logi w swoim pliku. Właściwie to rsyslog rozkłada je po katalogach. Każde API ma swoje logi, gdzie można zajrzeć, a potem w tym logu można je porównać według timestamp. Jeśli idą sprawdzić w Graylog, to tam posortują je według timestamp. Wszystko będzie w porządku.

Pytanie: Timestamp może różnić się o milisekundy.

Odpowiedź: Timestamp generuje samo API. W tym tkwi cała sztuczka. Mamy NTP. API generuje timestamp już w samej wiadomości. To nie rsyslog go dodaje.

Pytanie: Nie jest do końca jasne, jak przebiega interakcja pomiędzy centrami danych. W ramach jednego centrum danych wiadomo, jak zebrano i przetworzono logi. Jak odbywa się interakcja między centrami danych? Czy każde centrum danych funkcjonuje niezależnie?

Odpowiedź: Prawie. Każdy kraj znajduje się w jednym centrum danych. Na ten moment nie mamy rozproszenia, by jeden kraj był rozlokowany w różnych centrach danych. Dlatego nie musimy ich łączyć. W każdym centrum znajdują się Log Relay. To serwer Rsyslog. Tak naprawdę są dwie maszyny zarządzające. Są one skonfigurowane identycznie. Na razie ruch przechodzi przez jedną z nich. Ta maszyna agreguje wszystkie logi. Ma też kolejkę dyskową na wszelki wypadek. Kompresuje logi i wysyła je do centralnego centrum danych (w Singapurze), gdzie są następnie przesyłane do Grayloga. W każdym centrum danych znajduje się własna przestrzeń dyskowa. W przypadku, gdy utracimy łączność, mamy wszystkie logi tam. Pozostaną tam. Zostaną zachowane.

Pytanie: Czy w sytuacjach awaryjnych otrzymujecie logi stamtąd?

Odpowiedź: Można pójść tam (do magazynu plików) i sprawdzić.

Pytanie: Jak monitorujecie, że nie tracicie logów?

Odpowiedź: W rzeczywistości tracimy je i to monitorujemy. Monitorowanie uruchomiliśmy miesiąc temu. W bibliotece używanej przez Go API są metryki. Zlicza ile razy nie udało się zapisać do socketu. Na ten moment istnieje sprytna heurystyka. Jest bufor. Próbuje zapisywać z niego wiadomości do socketu. Jeśli bufor się przepełni, zaczyna je odrzucać. I zlicza, ile ich odrzucił. Jeśli zaczynają się przepełniać liczniki, dowiadujemy się o tym. Obecnie trafiają też do Prometheusa, a w Grafanie można zobaczyć wykresy. Można skonfigurować powiadomienia. Ale na razie nie wiadomo, do kogo je wysyłać.

Pytanie: W Elasticsearch przechowujecie logi z replikacją. Ile macie replik?

Odpowiedź: Jedna replika.

Pytanie: To tylko jedna replika?

Odpowiedź: To master i replika. Dane są przechowywane w dwóch egzemplarzach.

Pytanie: Czy jakoś dostosowywaliście rozmiar bufora rsyslog?

Odpowiedź: Piszę dane do niestandardowego gniazda unix. Od razu nakłada to na nas ograniczenie do 128 kilobajtów. Nie możemy zapisać więcej. Zostało to zapisane w standardzie. Kto chce mieć dostęp do pamięci, ten musi pisać 128 kilobajtów. Biblioteki obcinają dane i ustawiają flagę, że wiadomość została obcięta. W naszym standardzie samej wiadomości jest specjalne pole, które pokazuje, czy zostało ono obcięte podczas zapisu, czy nie. Mamy więc możliwość śledzenia tego aspektu.

Pytanie: Czy piszecie uszkodzony JSON?

Odpowiedź: Uszkodzony JSON zostanie odrzucony albo podczas relay, bo pakiet jest za duży. Albo zostanie odrzucony przez Graylog, bo nie będzie mógł sparsować JSON. Ale są tutaj niuanse, które musimy naprawić, a te w większości mają związek z rsyslog. Już zgłosiłem tam kilka problemów, nad którymi jeszcze trzeba popracować.

Pytanie: Dlaczego Kafka? Czy próbowaliście RabbitMQ? Graylog nie działa przy takich obciążeniach?

Odpowiedź: U nas nie działa Graylog. A Graylog nie działa u nas. To naprawdę problematyczny system. W rzeczywistości nie jest potrzebny. Wolałbym pisać z rsyslog bezpośrednio do elasticsearch i później korzystać z Kibana. Musimy jednak uzgodnić to z bezpieczeństwem. To możliwa opcja naszego rozwoju, kiedy pozbędziemy się Graylog i będziemy używać Kibana. Nie ma sensu używać Logstash. Bo wszystko to mogę zrobić za pomocą rsyslog. Ma on moduł do zapisu w elasticsearch. Staramy się jakoś żyć z Graylog. Nawet trochę go dostosowaliśmy. Ale wciąż jest jeszcze miejsce na poprawę.

O Kafka. Tak to historycznie się ułożyło. Kiedy przyszedłem, już istniała i już były tam zapisywane logi. Po prostu uruchomiliśmy nasz klaster i przenieśliśmy do niego logi. Zarządzamy nią, wiemy, jak się czuje. Co do RabbitMQ... nie dogadujemy się z RabbitMQ. Ale RabbitMQ działa u nas. Mamy go w produkcji i były z nim problemy. Teraz przed wyprzedażą go poprawiliśmy i zaczęło działać normalnie. Jednak przed tym nie byłem gotów wprowadzić go do produkcji. Jest jeszcze jeden punkt. Graylog potrafi czytać wersję AMQP 0.9, a rsyslog potrafi pisać wersję AMQP 1.0. Nie ma żadnego rozwiązania, które potrafiłoby i to, i to. Jest albo to, albo tamto. Dlatego na ten moment tylko Kafka. Ale tam też są swoje niuanse. Ponieważ omkafka tej wersji rsyslog, której używamy, może stracić cały bufor wiadomości, który wydobyła z rsyslog. Narazie się z tym godzimy.

Pytanie: Używacie Kafki tylko dlatego, że już ją mieliście? Nie wykorzystujecie jej do innych celów?

Odpowiedź: Kafka, która była, jest używana przez zespół Data Science. To zupełnie inny projekt, o którym, niestety, nie mogę nic powiedzieć. Nie jestem na bieżąco. Była pod opieką zespołu Data Science. Kiedy wprowadzali logi, postanowili z niej skorzystać, żeby nie instalować jeszcze swojej. Teraz zaktualizowaliśmy Graylog i utraciliśmy kompatybilność, ponieważ tam jest stara wersja Kafki. Musieliśmy założyć własną. Przy okazji pozbyliśmy się tych czterech tematów na każdy API. Zrobiliśmy jeden szeroki temat dla wszystkich live, jeden szeroki temat dla wszystkich staging i po prostu wszystko tam wrzucamy. Graylog jednocześnie to wszystko wydobywa.

Pytanie: Po co to czarowanie z gniazdami? Czy próbowaliście użyć log-driver syslog dla kontenerów?

Odpowiedź: W momencie, kiedy zajmowaliśmy się tym zagadnieniem, nasze relacje z Dockerem były napięte. To była wersja Docker 1.0 lub 0.9. Docker sam w sobie był dość dziwny. Po drugie, jeśli dodamy do niego logi... Mam niepotwierdzone podejrzenie, że przepuszcza wszystkie logi przez siebie, przez demon Dockera. Jeśli jedno API wariuje, pozostałe API zderzają się z tym, że nie mogą wysłać stdout i stderr. Nie wiem, do czego to prowadzi. Mój instynkt podpowiada mi, że w tym miejscu nie należy używać syslog drivera Dockera. Nasz dział testowania funkcjonalnego ma swój własny mały klaster Graylog z logami. Używają driverów logów Dockera i wydaje się, że tam wszystko działa dobrze. Ale oni od razu piszą GELF do Graylog. W momencie, kiedy wszystko to zaplanowaliśmy, potrzebowaliśmy, żeby to po prostu działało. Być może później, kiedy ktoś przyjdzie i powie, że działa to już od lat normalnie, spróbujemy.

Pytanie: Realizujecie dostawę między centrami danych za pomocą rsyslog. Dlaczego nie przez Kafka?

Odpowiedź: Robimy tak i tak, w rzeczywistości. Z dwóch powodów. Jeśli kanał jest całkowicie zablokowany, to nawet nasze skompresowane logi się przez niego nie przechodzą. A Kafka pozwala na ich po prostu utratę w trakcie przesyłania. W ten sposób pozbywamy się zatykania tych logów. W takim przypadku wykorzystujemy Kafka bezpośrednio. Jeśli mamy dobry kanał i chcemy go zwolnić, używamy rsyslog. Ale tak naprawdę można go skonfigurować tak, aby sam odrzucał to, co nie przeszło. Na ten moment gdzieś używamy dostawy rsyslog bezpośrednio, gdzieś Kafka.

Ź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