{"id":75796,"date":"2020-03-28T19:42:18","date_gmt":"2020-03-28T17:42:18","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/klaster-elasticsearch-na-200-tb"},"modified":"2020-03-28T19:42:18","modified_gmt":"2020-03-28T17:42:18","slug":"klaster-elasticsearch-na-200-tb","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/klaster-elasticsearch-na-200-tb","title":{"rendered":"Klastr Elasticsearch na 200 TB+","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/ca7a31eca0b3d4faf648dfb24ffbe215.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wielu napotyka Elasticsearch. Co si\u0119 jednak dzieje, gdy chcesz go u\u017cywa\u0107 do przechowywania log\u00f3w \"w szczeg\u00f3lnie du\u017cych ilo\u015bciach\"? Jak mo\u017cna to zrobi\u0107, aby bezbole\u015bnie przetrwa\u0107 awari\u0119 jednego z kilku centr\u00f3w danych? Jak powinna wygl\u0105da\u0107 architektura i na jakie pu\u0142apki mo\u017cna natkn\u0105\u0107 si\u0119?<\/p>\n<p><\/p>\n<p>W Odnoklassnikach postanowili\u015bmy z pomoc\u0105 Elasticsearch rozwi\u0105za\u0107 problem zarz\u0105dzania logami, a teraz dzielimy si\u0119 naszym do\u015bwiadczeniem na Habrze: zar\u00f3wno na temat architektury, jak i pu\u0142apek.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Nazywam si\u0119 Piotr Zajcew, pracuj\u0119 jako administrator systemu w Odnoklassnikach. Wcze\u015bniej r\u00f3wnie\u017c by\u0142em administratorem, pracowa\u0142em z Manticore Search, Sphinx Search i Elasticsearch. Mo\u017ce, je\u015bli pojawi si\u0119 jeszcze jaki\u015b ...search, prawdopodobnie b\u0119d\u0119 pracowa\u0107 i z nim. Uczestnicz\u0119 r\u00f3wnie\u017c w kilku projektach open source na zasadzie wolontariatu.<\/p>\n<p><\/p>\n<p>Kiedy przyszed\u0142em do Odnoklassnikach, nieroztropnie powiedzia\u0142em na rozmowie kwalifikacyjnej, \u017ce umiem pracowa\u0107 z Elasticsearch. Po tym jak si\u0119 oswoi\u0142em i wykona\u0142em kilka prostszych zada\u0144, dosta\u0142em du\u017c\u0105 odpowiedzialno\u015b\u0107 za reform\u0119 istniej\u0105cego systemu zarz\u0105dzania logami. <\/p>\n<p><\/p>\n<h2 id=\"trebovaniya\">Wymagania<\/h2>\n<p><\/p>\n<p>Wymagania systemowe zosta\u0142y sformu\u0142owane w nast\u0119puj\u0105cy spos\u00f3b:<\/p>\n<p><\/p>\n<ul>\n<li>Jako front-end mia\u0142 by\u0107 u\u017cywany Graylog. Poniewa\u017c firma mia\u0142a ju\u017c do\u015bwiadczenie z tym produktem, programi\u015bci i testerzy go znali, by\u0142 dla nich znajomy i wygodny.<\/li>\n<li>Obj\u0119to\u015b\u0107 danych: w \u015brednio 50-80 tysi\u0119cy wiadomo\u015bci na sekund\u0119, ale je\u015bli co\u015b si\u0119 psuje, to ruch nie jest w \u017caden spos\u00f3b ograniczony, mog\u0105 to by\u0107 2-3 miliony wierszy na sekund\u0119.<\/li>\n<li>Po om\u00f3wieniu z klientami wymaga\u0144 dotycz\u0105cych pr\u0119dko\u015bci przetwarzania zapyta\u0144, zrozumieli\u015bmy, \u017ce typowy wzorzec u\u017cycia takiego systemu jest taki: ludzie szukaj\u0105 log\u00f3w swojej aplikacji z ostatnich dw\u00f3ch dni i nie chc\u0105 czeka\u0107 na wynik swojego sformu\u0142owanego zapytania d\u0142u\u017cej ni\u017c sekund\u0119. <\/li>\n<li>Administratorzy nalegali, aby system \u0142atwo skalowa\u0142 si\u0119 w razie potrzeby, nie wymagaj\u0105c od nich g\u0142\u0119bokiego zrozumienia, jak jest zbudowany. <\/li>\n<li>Aby jedynym zadaniem konserwacyjnym, kt\u00f3re te systemy wymaga\u0142y okresowo, by\u0142o zmienianie jakiego\u015b sprz\u0119tu.<\/li>\n<li>Ponadto, w Odnoklassnikach istnieje wspania\u0142a tradycja techniczna: ka\u017cda us\u0142uga, kt\u00f3r\u0105 uruchamiamy, musi przetrwa\u0107 awari\u0119 centrum danych (niespodziewan\u0105, nieplanowan\u0105 i ca\u0142kowicie w dowolnym czasie).<\/li>\n<\/ul>\n<p><\/p>\n<p>Ostatnie wymaganie dotycz\u0105ce realizacji tego projektu kosztowa\u0142o nas najwi\u0119cej trudu, o czym opowiem jeszcze bardziej szczeg\u00f3\u0142owo.<\/p>\n<p><\/p>\n<h2 id=\"sreda\">\u015arodowisko<\/h2>\n<p><\/p>\n<p>Pracujemy w czterech centrach danych, natomiast w\u0119z\u0142y danych Elasticsearch mog\u0105 znajdowa\u0107 si\u0119 tylko w trzech (z szeregu przyczyn technicznych).<\/p>\n<p><\/p>\n<p>W tych czterech centrach danych znajduje si\u0119 oko\u0142o 18 tysi\u0119cy r\u00f3\u017cnych \u017ar\u00f3de\u0142 log\u00f3w \u2014 urz\u0105dzenia, kontenery, maszyny wirtualne.<\/p>\n<p><\/p>\n<p>Wa\u017cna cecha: uruchomienie klastra odbywa si\u0119 w kontenerach <noindex><a rel=\"nofollow\" href=\"https:\/\/podman.io\">Podman<\/a><\/noindex> nie na fizycznych maszynach, ale na <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/odnoklassniki\/blog\/346868\/\">w\u0142asnym produkcie chmurowym one-cloud<\/a><\/noindex>. Kontenery maj\u0105 przydzielone 2 rdzenie, odpowiadaj\u0105ce 2.0Ghz v4 z mo\u017cliwo\u015bci\u0105 wykorzystania pozosta\u0142ych rdzeni w przypadku ich bezczynno\u015bci. <\/p>\n<p><\/p>\n<p>Innymi s\u0142owy:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/073bffbfc3cff761bfabe0773b7f4ebc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"topologiya\">Topologia<\/h2>\n<p><\/p>\n<p>Og\u00f3lny wygl\u0105d rozwi\u0105zania na pocz\u0105tku wydawa\u0142 mi si\u0119 nast\u0119puj\u0105cy:<\/p>\n<p><\/p>\n<ul>\n<li>3-4 VIP znajduj\u0105 si\u0119 za rekordem A domeny Graylog, to jest adres, na kt\u00f3ry wysy\u0142ane s\u0105 logi.<\/li>\n<li>ka\u017cdy VIP stanowi r\u00f3wnowa\u017cnik obci\u0105\u017cenia LVS.<\/li>\n<li>Po nim logi trafiaj\u0105 do baterii Graylog, cz\u0119\u015b\u0107 danych jest w formacie GELF, cz\u0119\u015b\u0107 w formacie syslog.<\/li>\n<li>Nast\u0119pnie wszystko to w du\u017cych partiach zapisuje si\u0119 w baterii koordynator\u00f3w Elasticsearch. <\/li>\n<li>Oni z kolei wysy\u0142aj\u0105 zapytania o zapisywanie i odczytywanie do odpowiednich w\u0119z\u0142\u00f3w danych. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/21efcdf6992a07e0c5e9b477c567cca9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"terminologiya\">Terminologia<\/h2>\n<p><\/p>\n<p>Mo\u017cliwe, \u017ce nie wszyscy dok\u0142adnie rozumiej\u0105 terminologi\u0119, dlatego chcia\u0142bym si\u0119 na niej chwil\u0119 zatrzyma\u0107.<\/p>\n<p><\/p>\n<p>W Elasticsearch istnieje kilka typ\u00f3w w\u0119z\u0142\u00f3w \u2014 master, coordinator, data node. S\u0105 jeszcze dwa inne typy do r\u00f3\u017cnych przekszta\u0142ce\u0144 log\u00f3w i komunikacji mi\u0119dzy r\u00f3\u017cnymi klastrami, ale u\u017cywali\u015bmy tylko wymienionych. <\/p>\n<p><\/p>\n<p><strong>Master<\/strong><br \/>\nPinguj\u0105 wszystkie w\u0119z\u0142y obecne w klastrze, utrzymuj\u0105 aktualn\u0105 map\u0119 klastra i rozprzestrzeniaj\u0105 j\u0105 mi\u0119dzy w\u0119z\u0142ami, obs\u0142uguj\u0105 logik\u0119 zdarze\u0144, zajmuj\u0105 si\u0119 r\u00f3\u017cnymi rzeczami zwi\u0105zanymi z administracj\u0105 klastra. <\/p>\n<p><\/p>\n<p><strong>Koordynator<\/strong><br \/>\nWykonuje jedn\u0105 jedyn\u0105 zadanie: przyjmuje zapytania od klient\u00f3w dotycz\u0105ce odczytu lub zapisu i kieruje ten ruch. W przypadku, gdy zapytanie dotyczy zapisu, najprawdopodobniej zapyta master, do kt\u00f3rego shardu odpowiedniego indeksu to zapisa\u0107, i przekieruje zapytanie dalej. <\/p>\n<p><\/p>\n<p><strong>W\u0119ze\u0142 danych<\/strong><br \/>\nPrzechowuje dane, wykonuje przychodz\u0105ce zapytania o wyszukiwanie i operacje na umieszczonych na niej shardach.<\/p>\n<p><\/p>\n<p><strong>Graylog<\/strong><br \/>\nTo jest co\u015b w rodzaju po\u0142\u0105czenia Kibana z Logstash w stosie ELK. Graylog \u0142\u0105czy w sobie interfejs u\u017cytkownika oraz potok do przetwarzania log\u00f3w. W Graylog dzia\u0142aj\u0105 Kafka i Zookeeper, kt\u00f3re zapewniaj\u0105 sp\u00f3jno\u015b\u0107 Graylog jako klastra. Graylog potrafi buforowa\u0107 logi (Kafka) w przypadku braku dost\u0119pu do Elasticsearch i powtarza\u0107 nieudane zapytania do odczytu i zapisu, grupowa\u0107 i oznacza\u0107 logi wed\u0142ug zadanych regu\u0142. Podobnie jak Logstash, Graylog ma funkcjonalno\u015b\u0107 do modyfikacji ci\u0105g\u00f3w przed zapisem do Elasticsearch.<\/p>\n<p><\/p>\n<p>Ponadto w Graylog znajduje si\u0119 wbudowane odkrywanie us\u0142ug, kt\u00f3re umo\u017cliwia na podstawie jednej dost\u0119pnej w\u0119z\u0142a Elasticsearch uzyskanie ca\u0142ej mapy klastra i filtrowanie jej wed\u0142ug okre\u015blonego tagu, co pozwala na kierowanie zapyta\u0144 do konkretnych kontener\u00f3w.<\/p>\n<p><\/p>\n<p>Wizualnie wygl\u0105da to mniej wi\u0119cej tak:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/8673ba9c0300ea0153d34a9f98afbcf2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To jest zrzut ekranu z konkretnego instancji. Tutaj na podstawie zapytania wyszukiwania budujemy histogram, wy\u015bwietlamy odpowiednie ci\u0105gi.<\/p>\n<p><\/p>\n<h2 id=\"indeksy\">Indeksy<\/h2>\n<p><\/p>\n<p>Wracaj\u0105c do architektury systemu, chcia\u0142bym bli\u017cej przyjrze\u0107 si\u0119 temu, jak budowali\u015bmy model indeks\u00f3w, aby wszystko dzia\u0142a\u0142o poprawnie. <\/p>\n<p><\/p>\n<p>Na wcze\u015bniej przedstawionym schemacie to najni\u017cszy poziom: w\u0119z\u0142y danych Elasticsearch.<\/p>\n<p><\/p>\n<p>Indeks to du\u017ca wirtualna jednostka sk\u0142adaj\u0105ca si\u0119 z shard\u00f3w Elasticsearch. Sam ka\u017cdy z shard\u00f3w jest niczym innym jak indeksem Lucene. A ka\u017cdy indeks Lucene sk\u0142ada si\u0119 z jednego lub wi\u0119cej segment\u00f3w. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/13b858cb102dce26b0851516b2d36c43.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Podczas projektowania przewidywali\u015bmy, \u017ce aby spe\u0142ni\u0107 wymagania dotycz\u0105ce szybko\u015bci odczytu przy du\u017cych ilo\u015bciach danych, musimy r\u00f3wno \"roz\u0142o\u017cy\u0107\" te dane po w\u0119z\u0142ach danych. <\/p>\n<p><\/p>\n<p>To doprowadzi\u0142o do tego, \u017ce liczba shard\u00f3w na indeks (z replikami) musi by\u0107 \u015bci\u015ble r\u00f3wna liczbie w\u0119z\u0142\u00f3w danych. Po pierwsze, aby zapewni\u0107 wsp\u00f3\u0142czynnik replikacji r\u00f3wny dw\u00f3m (to znaczy, \u017ce mo\u017cemy straci\u0107 po\u0142ow\u0119 klastra). A po drugie, aby przetwarza\u0107 zapytania do odczytu i zapisu na co najmniej po\u0142owie klastra.<\/p>\n<p><\/p>\n<p>Czas przechowywania okre\u015blili\u015bmy pocz\u0105tkowo na 30 dni.<\/p>\n<p><\/p>\n<p>Rozk\u0142ad shard\u00f3w mo\u017cna graficznie przedstawi\u0107 w nast\u0119puj\u0105cy spos\u00f3b:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/242726053360d1a6bdf4e527edc6cae6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ca\u0142y ciemnoszary prostok\u0105t to indeks. Lewy czerwony kwadrat w nim to primary shard, pierwszy w indeksie. A b\u0142\u0119kitny kwadrat to replica shard. Znajduj\u0105 si\u0119 w r\u00f3\u017cnych centrach danych.<\/p>\n<p><\/p>\n<p>Kiedy dodajemy kolejny shard, trafia on do trzeciego centrum danych. Ostatecznie uzyskujemy tak\u0105 struktur\u0119, kt\u00f3ra zapewnia mo\u017cliwo\u015b\u0107 utraty DC bez utraty sp\u00f3jno\u015bci danych:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/27cbe4d4606f5ae5f3013ea46504134b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Rotacja indeks\u00f3w, czyli tworzenie nowego indeksu i usuwanie najstarszego, zosta\u0142a ustawiona na 48 godzin (wed\u0142ug wzorca korzystania z indeksu: najcz\u0119\u015bciej szuka si\u0119 wed\u0142ug ostatnich 48 godzin).<\/p>\n<p><\/p>\n<p>Taki interwa\u0142 rotacji indeks\u00f3w zwi\u0105zany jest z nast\u0119puj\u0105cymi przyczynami:<\/p>\n<p><\/p>\n<p>Gdy konkretna data-noda otrzymuje zapytanie wyszukiwawcze, z perspektywy wydajno\u015bci korzystniej jest, gdy odpytywana jest jeden shard, je\u015bli jego rozmiar jest zbli\u017cony do rozmiaru hipa nody. Pozwala to utrzyma\u0107 \u201egor\u0105c\u0105\u201d cz\u0119\u015b\u0107 indeksu w hipie i szybko do niej si\u0119ga\u0107. Gdy liczba \u201egor\u0105cych cz\u0119\u015bci\u201d wzrasta, to spada pr\u0119dko\u015b\u0107 wyszukiwania w indeksie.<\/p>\n<p><\/p>\n<p>Gdy noda zaczyna realizowa\u0107 zapytanie wyszukiwawcze na jednym shardzie, alokuje liczb\u0119 w\u0105tk\u00f3w r\u00f3wn\u0105 liczbie rdzeni z hyper-threading fizycznej maszyny. Je\u015bli zapytanie wyszukiwawcze dotyczy du\u017cej liczby shard\u00f3w, to liczba w\u0105tk\u00f3w ro\u015bnie proporcjonalnie. Negatywnie odbija si\u0119 to na pr\u0119dko\u015bci wyszukiwania i negatywnie wp\u0142ywa na indeksowanie nowych danych. <\/p>\n<p><\/p>\n<p>Aby zapewni\u0107 odpowiednie op\u00f3\u017anienie w wyszukiwaniu, zdecydowali\u015bmy si\u0119 na u\u017cycie SSD. Aby szybko przetwarza\u0107 zapytania, maszyny, na kt\u00f3rych znajdowa\u0142y si\u0119 te kontenery, musia\u0142y mie\u0107 co najmniej 56 rdzeni. Liczba 56 zosta\u0142a wybrana jako warunkowo wystarczaj\u0105ca wielko\u015b\u0107, okre\u015blaj\u0105ca liczb\u0119 w\u0105tk\u00f3w, kt\u00f3re b\u0119dzie generowa\u0142 Elasticsearch w trakcie pracy. W Elasticsearch wiele parametr\u00f3w puli w\u0105tk\u00f3w bezpo\u015brednio zale\u017cy od liczby dost\u0119pnych rdzeni, co z kolei ma bezpo\u015bredni wp\u0142yw na wymagan\u0105 liczb\u0119 w\u0119z\u0142\u00f3w w klastrze zgodnie z zasad\u0105 \u201emniej rdzeni \u2014 wi\u0119cej w\u0119z\u0142\u00f3w\u201d. <\/p>\n<p><\/p>\n<p>W rezultacie otrzymali\u015bmy, \u017ce \u015brednio shard wa\u017cy oko\u0142o 20 gigabajt\u00f3w, a na 1 indeks przypada 360 shard\u00f3w. W zwi\u0105zku z tym, je\u015bli rotujemy je co 48 godzin, to mamy ich 15. Ka\u017cdy indeks przechowuje dane za 2 dni.<\/p>\n<p><\/p>\n<h2 id=\"shemy-zapisi-i-chteniya-dannyh\">Schematy zapisu i odczytu danych<\/h2>\n<p><\/p>\n<p>Zastan\u00f3wmy si\u0119, jak w tym systemie zapisywane s\u0105 dane.<\/p>\n<p><\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce z Grayloga przychodzi do koordynatora jakie\u015b zapytanie. Na przyk\u0142ad chcemy zindeksowa\u0107 2-3 tysi\u0105ce wierszy. <\/p>\n<p><\/p>\n<p>Koordynator, otrzymawszy zapytanie z Graylog, pyta mastera: \u201eW zapytaniu o indeksowanie mieli\u015bmy konkretnie wskazany indeks, ale nie by\u0142o podane, do kt\u00f3rego shardu to zapisa\u0107.\u201d <\/p>\n<p><\/p>\n<p>Master odpowiada: \u201eZapisz te informacje w shardzie numer 71\u201d, po czym trafia ona bezpo\u015brednio do odpowiedniego data-node, w kt\u00f3rym znajduje si\u0119 primary-shard numer 71.<\/p>\n<p><\/p>\n<p>Nast\u0119pnie dziennik transakcji jest replikowany na replica-shard, kt\u00f3ry znajduje si\u0119 ju\u017c w innym centrum danych.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/fdb6a77cb78b1eed290e440478569e3b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Z Graylog do koordynatora przychodzi zapytanie wyszukiwania. Koordynator przekierowuje je wed\u0142ug indeksu, przy czym Elasticsearch na zasadzie round-robin rozdziela zapytania mi\u0119dzy primary-shard a replica-shard. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/cb32bac878e04d6f50d103ebbc395a7f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W\u0119z\u0142y w liczbie 180 odpowiadaj\u0105 nier\u00f3wnomiernie, a podczas gdy odpowiadaj\u0105, koordynator gromadzi informacje, kt\u00f3re ju\u017c \u201ewyrzuci\u0142y\u201d do niego szybsze data-nody. Nast\u0119pnie, gdy albo wszystkie informacje przyjd\u0105, albo osi\u0105gni\u0119ty zostanie limit czasowy dla zapytania, przekazuje wszystko bezpo\u015brednio klientowi. <\/p>\n<p><\/p>\n<p>Ca\u0142y ten system \u015brednio przetwarza zapytania wyszukiwania po ostatnich 48 godzinach w czasie 300-400ms, z wyj\u0105tkiem tych zapyta\u0144, kt\u00f3re maj\u0105 leading wildcard.<\/p>\n<p><\/p>\n<h2 id=\"cvetochki-s-elasticsearch-nastroyka-java\">\u201eKwiatki\u201d z Elasticsearch: konfiguracja Java<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/fc9ac4b8ee41bc35f5f01b8d9c4ff2f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aby wszystko dzia\u0142a\u0142o tak, jak pocz\u0105tkowo chcieli\u015bmy, d\u0142ugo testowali\u015bmy r\u00f3\u017cnorodne rzeczy w klastrze. <\/p>\n<p><\/p>\n<p>Pierwsza cz\u0119\u015b\u0107 odkrytych problem\u00f3w dotyczy\u0142a tego, jak w Elasticsearch domy\u015blnie skonfigurowana jest Java. <\/p>\n<p><\/p>\n<p><strong>Problem pierwszy<\/strong><br \/>\nZauwa\u017cyli\u015bmy bardzo du\u017c\u0105 liczb\u0119 komunikat\u00f3w o tym, \u017ce na poziomie Lucene, gdy uruchomione s\u0105 background job'y, \u0142\u0105czenie segment\u00f3w Lucene ko\u0144czy si\u0119 b\u0142\u0119dem. W logach wida\u0107 by\u0142o, \u017ce to by\u0142 b\u0142\u0105d OutOfMemoryError. Z telemetrii widzieli\u015bmy, \u017ce pami\u0119\u0107 heap jest wolna i nie by\u0142o jasne, dlaczego ta operacja si\u0119 nie powiod\u0142a. <\/p>\n<p><\/p>\n<p>Okaza\u0142o si\u0119, \u017ce scalanie indeks\u00f3w Lucene odbywa si\u0119 poza heapem. A kontenery s\u0105 do\u015b\u0107 sztywno ograniczone pod wzgl\u0119dem zu\u017cywanych zasob\u00f3w. W te zasoby upada\u0142 tylko heap (warto\u015b\u0107 heap.size by\u0142a mniej wi\u0119cej r\u00f3wna RAM), a niekt\u00f3re operacje off-heap ko\u0144czy\u0142y si\u0119 b\u0142\u0119dem alokacji pami\u0119ci, je\u015bli z jakiego\u015b powodu nie mie\u015bci\u0142y si\u0119 w tych ~500MB, kt\u00f3re pozostawa\u0142y do limitu.<\/p>\n<p><\/p>\n<p>Rozwi\u0105zanie by\u0142o do\u015b\u0107 trywialne: zwi\u0119kszyli\u015bmy dost\u0119pn\u0105 dla kontenera ilo\u015b\u0107 RAM, po czym zapomnieli\u015bmy, \u017ce w og\u00f3le mieli\u015bmy takie problemy.<\/p>\n<p><\/p>\n<p><strong>Problem drugi<\/strong><br \/>\nPo oko\u0142o 4-5 dniach od uruchomienia klastra zauwa\u017cyli\u015bmy, \u017ce data-nody zaczynaj\u0105 okresowo wypada\u0107 z klastra i wraca\u0107 do niego po 10-20 sekundach. <\/p>\n<p><\/p>\n<p>Gdy zacz\u0119li\u015bmy si\u0119 tym zajmowa\u0107, okaza\u0142o si\u0119, \u017ce pami\u0119\u0107 off-heap w Elasticsearch nie jest praktycznie w og\u00f3le kontrolowana. Gdy dali\u015bmy kontenerowi wi\u0119cej pami\u0119ci, zyskali\u015bmy mo\u017cliwo\u015b\u0107 zape\u0142niania pul bufor\u00f3w bezpo\u015brednich r\u00f3\u017cnymi informacjami, kt\u00f3re by\u0142y usuwane dopiero po uruchomieniu explicit GC ze strony Elasticsearch. <\/p>\n<p><\/p>\n<p>W niekt\u00f3rych przypadkach operacja ta trwa\u0142a do\u015b\u0107 d\u0142ugo, a w tym czasie klaster zd\u0105\u017cy\u0142 oznaczy\u0107 t\u0119 nod\u0119 jako ju\u017c niedost\u0119pn\u0105. Problem ten zosta\u0142 dobrze opisany. <noindex><a rel=\"nofollow\" href=\"https:\/\/discuss.elastic.co\/t\/elasticsearch-5-6-very-quickly-increasing-direct-buffer-pools\/119561\">tutaj<\/a><\/noindex>. <\/p>\n<p><\/p>\n<p>Rozwi\u0105zanie by\u0142o nast\u0119puj\u0105ce: ograniczyli\u015bmy Java mo\u017cliwo\u015b\u0107 u\u017cywania g\u0142\u00f3wnej cz\u0119\u015bci pami\u0119ci poza heapem na te operacje. Ograniczyli\u015bmy j\u0105 do 16 gigabajt\u00f3w (-XX:MaxDirectMemorySize=16g), co sprawi\u0142o, \u017ce explicit GC by\u0142 wywo\u0142ywany znacznie cz\u0119\u015bciej i dzia\u0142a\u0142 znacznie szybciej, przestaj\u0105c tym samym destabilizowa\u0107 klaster.<\/p>\n<p><\/p>\n<p><strong>Problem trzeci<\/strong><br \/>\nJe\u015bli my\u015blisz, \u017ce problemy z \u201enodami, kt\u00f3re opuszczaj\u0105 klaster w najmniej oczekiwanym momencie\u201d si\u0119 na tym ko\u0144cz\u0105, mylisz si\u0119. <\/p>\n<p><\/p>\n<p>Gdy konfigurowali\u015bmy prac\u0119 z indeksami, zdecydowali\u015bmy si\u0119 na mmapfs, aby <noindex><a rel=\"nofollow\" href=\"https:\/\/discuss.elastic.co\/t\/benchmarks-default-niofs-vs-memory-mapped-mmapfs\/13118\/2\">skr\u00f3ci\u0107 czas wyszukiwania<\/a><\/noindex> w \u015bwie\u017cych shardach z du\u017c\u0105 segmentacj\u0105. By\u0142 to do\u015b\u0107 powa\u017cny b\u0142\u0105d, poniewa\u017c przy u\u017cyciu mmapfs plik jest mapowany do pami\u0119ci operacyjnej, a nast\u0119pnie pracujemy ju\u017c z tym mapowanym plikiem. W zwi\u0105zku z tym, gdy garbage collector stara\u0142 si\u0119 zatrzyma\u0107 w\u0105tki w aplikacji, bardzo d\u0142ugo dochodzili\u015bmy do safepoint, a po drodze aplikacja przestawa\u0142a odpowiada\u0107 na zapytania mastera, czy \u017cyje. W zwi\u0105zku z tym master uznaje, \u017ce nody ju\u017c nie ma w klastrze. Po oko\u0142o 5-10 sekundach garbage collector w ko\u0144cu dzia\u0142a, node o\u017cywa, ponownie wchodzi do klastra i rozpoczyna inicjalizacj\u0119 shard\u00f3w. Ca\u0142o\u015b\u0107 mocno przypomina\u0142a \u201eprodukcj\u0119, na kt\u00f3r\u0105 zas\u0142u\u017cyli\u015bmy\u201d i nie nadawa\u0142a si\u0119 do niczego powa\u017cnego.<\/p>\n<p><\/p>\n<p>Aby pozby\u0107 si\u0119 takiego zachowania, najpierw przeszli\u015bmy na standardowy niofs, a p\u00f3\u017aniej, kiedy z pi\u0105tych wersji Elastic przeszli\u015bmy na sz\u00f3st\u0105, wypr\u00f3bowali\u015bmy hybridfs, w kt\u00f3rym problem ten si\u0119 nie pojawia\u0142. Wi\u0119cej o typach storage mo\u017cna poczyta\u0107. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/6.8\/index-modules-store.html\">tutaj<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Problem czwarty<\/strong><br \/>\nP\u00f3\u017aniej by\u0142a jeszcze bardzo zajmuj\u0105ca sprawa, kt\u00f3r\u0105 leczenie zaj\u0119\u0142o nam rekordowo du\u017co czasu. \u0141apali\u015bmy j\u0105 przez 2-3 miesi\u0105ce, poniewa\u017c wzorzec by\u0142 zupe\u0142nie niejasny. <\/p>\n<p><\/p>\n<p>Czasami nasi koordynatorzy wchodzili w Full GC, zazwyczaj gdzie\u015b po po\u0142udniu, i ju\u017c si\u0119 nie wracali. Przy logowaniu op\u00f3\u017anie\u0144 GC wygl\u0105da\u0142o to tak: wszystko sz\u0142o dobrze, dobrze, dobrze, a potem nagle \u2014 wszystko stawa\u0142o si\u0119 nagle z\u0142e. <\/p>\n<p><\/p>\n<p>Pocz\u0105tkowo my\u015bleli\u015bmy, \u017ce mamy z\u0142ego u\u017cytkownika, kt\u00f3ry uruchamia jak\u0105\u015b kwerend\u0119, kt\u00f3ra wybija koordynator z trybu pracy. Bardzo d\u0142ugo logowali\u015bmy zapytania, pr\u00f3buj\u0105c ustali\u0107, co si\u0119 dzieje. <\/p>\n<p><\/p>\n<p>Ostatecznie okaza\u0142o si\u0119, \u017ce w momencie, gdy jaki\u015b u\u017cytkownik uruchamia ogromne zapytanie, a ono trafia do konkretnego koordynatora Elasticsearch, niekt\u00f3re w\u0119z\u0142y odpowiadaj\u0105 d\u0142u\u017cej ni\u017c inne. <\/p>\n<p><\/p>\n<p>A czas, podczas gdy koordynator czeka na odpowied\u017a wszystkich w\u0119z\u0142\u00f3w, gromadzi w sobie wyniki przys\u0142ane przez ju\u017c odpowiedni\u0105 w\u0119z\u0142y. Dla GC oznacza to, \u017ce bardzo szybko zmienia si\u0119 wzorzec u\u017cycia pami\u0119ci heap. I ten GC, kt\u00f3rego u\u017cywali\u015bmy, nie radzi\u0142 sobie z tym zadaniem. <\/p>\n<p><\/p>\n<p>Jedynym rozwi\u0105zaniem, kt\u00f3re znale\u017ali\u015bmy, aby zmieni\u0107 zachowanie klastra w takiej sytuacji, by\u0142a migracja na JDK13 i u\u017cycie zbieracza \u015bmieci Shenandoah. To rozwi\u0105za\u0142o problem, koordynatory przesta\u0142y pada\u0107. <\/p>\n<p><\/p>\n<p>Na tym problemy z Java si\u0119 sko\u0144czy\u0142y, a zacz\u0119\u0142y problemy z przepustowo\u015bci\u0105. <\/p>\n<p><\/p>\n<h2 id=\"yagodki-s-elasticsearch-propusknaya-sposobnost\">\u00abOwoce\u00bb z Elasticsearch: przepustowo\u015b\u0107<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/bb5c08193d7d764515235e825cd30ce5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Problemy z przepustowo\u015bci\u0105 oznaczaj\u0105, \u017ce nasz klaster dzia\u0142a stabilnie, ale w szczytowych momentach liczby indeksowanych dokument\u00f3w i podczas manewr\u00f3w wydajno\u015b\u0107 jest niewystarczaj\u0105ca.<\/p>\n<p><\/p>\n<p>Pierwszym zauwa\u017conym objawem: przy jakich\u015b \u00abwybuchach\u00bb na produkcji, gdy nagle generuje si\u0119 bardzo du\u017ca ilo\u015b\u0107 log\u00f3w, w Graylog zaczyna cz\u0119sto pojawia\u0107 si\u0119 b\u0142\u0105d indeksacji es_rejected_execution. <\/p>\n<p><\/p>\n<p>Dzia\u0142o si\u0119 tak, poniewa\u017c thread_pool.write.queue na jednym w\u0119\u017ale danych, zanim Elasticsearch zd\u0105\u017cy przetworzy\u0107 zapytanie indeksacyjne i wrzuci\u0107 informacje do shardu na dysku, domy\u015blnie mo\u017ce buforowa\u0107 tylko 200 zapyta\u0144. I w <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/6.8\/modules-threadpool.html\">dokumentacji Elasticsearch<\/a><\/noindex> o tym parametrze m\u00f3wi si\u0119 bardzo ma\u0142o. Podano tylko maksymaln\u0105 liczb\u0119 w\u0105tk\u00f3w i domy\u015blny rozmiar.<\/p>\n<p><\/p>\n<p>Oczywi\u015bcie przyst\u0105pili\u015bmy do modyfikacji tej warto\u015bci i odkryli\u015bmy nast\u0119puj\u0105ce: konkretnie w naszym ustawieniu mo\u017cna ca\u0142kiem dobrze buforowa\u0107 do 300 zapyta\u0144, a wi\u0119ksza warto\u015b\u0107 wi\u0105\u017ce si\u0119 z tym, \u017ce znowu wkr\u00f3tce wpadamy w Full GC.<\/p>\n<p><\/p>\n<p>Ponadto, poniewa\u017c s\u0105 to partie wiadomo\u015bci, kt\u00f3re przychodz\u0105 w ramach jednego zapytania, nale\u017ca\u0142o r\u00f3wnie\u017c dostosowa\u0107 Graylog, aby zapisywa\u0142 niecz\u0119sto i ma\u0142ymi partiami, ale ogromnymi partiami lub co 3 sekundy, je\u015bli partia wci\u0105\u017c nie jest pe\u0142na. W takim przypadku informacja, kt\u00f3r\u0105 zapisujemy w Elasticsearch, staje si\u0119 dost\u0119pna nie po dw\u00f3ch sekundach, a po pi\u0119ciu (co nam w zupe\u0142no\u015bci odpowiada), ale zmniejsza si\u0119 liczba retray\u00f3w, kt\u00f3re musimy wykona\u0107, aby przes\u0142a\u0107 du\u017c\u0105 paczk\u0119 informacji.<\/p>\n<p><\/p>\n<p>Jest to szczeg\u00f3lnie wa\u017cne w momentach, gdy co\u015b gdzie\u015b si\u0119 zepsu\u0142o i intensywnie o tym informuje, aby nie otrzyma\u0107 ca\u0142kowicie spamowanego Elastic, a po pewnym czasie \u2014 nie dzia\u0142aj\u0105cych nod\u00f3w Graylog z powodu zatkanych bufor\u00f3w.<\/p>\n<p><\/p>\n<p>Ponadto, gdy mia\u0142y miejsce te eksplozje na produkcji, otrzymywali\u015bmy skargi od programist\u00f3w i tester\u00f3w: w momencie, gdy bardzo potrzebowali tych log\u00f3w, by\u0142y one im udost\u0119pniane bardzo wolno.<\/p>\n<p><\/p>\n<p>Zacz\u0119li\u015bmy bada\u0107. Z jednej strony by\u0142o jasne, \u017ce zar\u00f3wno zapytania wyszukiwania, jak i zapytania o indeksowanie dzia\u0142aj\u0105 w zasadzie na tych samych fizycznych maszynach, i w ten czy inny spos\u00f3b pewne spadki b\u0119d\u0105 mia\u0142y miejsce. <\/p>\n<p><\/p>\n<p>Jednak mo\u017cna to by\u0142o cz\u0119\u015bciowo obej\u015b\u0107 dzi\u0119ki temu, \u017ce w sz\u00f3stych wersjach Elasticsearch pojawi\u0142 si\u0119 algorytm, kt\u00f3ry pozwala\u0142 na rozdzielanie zapyta\u0144 mi\u0119dzy odpowiednie w\u0119z\u0142y danych nie w przypadkowy, losowy spos\u00f3b (kontener, kt\u00f3ry zajmuje si\u0119 indeksowaniem i utrzymuje primary-shard, mo\u017ce by\u0107 bardzo zaj\u0119ty, nie b\u0119dzie mo\u017cliwo\u015bci odpowiedzi szybko), ale skierowa\u0107 to zapytanie do mniej obci\u0105\u017conego kontenera z replica-shard, kt\u00f3ry odpowie znacznie szybciej. Innymi s\u0142owy, doszli\u015bmy do use_adaptive_replica_selection: true.<\/p>\n<p><\/p>\n<p>Obraz odczytu zaczyna wygl\u0105da\u0107 nast\u0119puj\u0105co:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/ae7c1645bb63692e580b1bca5c6e5db0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Przej\u015bcie na ten algorytm pozwoli\u0142o znacznie poprawi\u0107 czas zapyta\u0144 w momentach, gdy mieli\u015bmy du\u017cy ruch log\u00f3w do zapisania.<\/p>\n<p><\/p>\n<p>W ko\u0144cu g\u0142\u00f3wnym problemem by\u0142o bezbolesne wycofanie centrum danych.<\/p>\n<p><\/p>\n<p>Czego chcieli\u015bmy od klastra zaraz po utracie \u0142\u0105czno\u015bci z jednym DC: <\/p>\n<p><\/p>\n<ul>\n<li>Je\u015bli w od\u0142\u0105czonym centrum danych znajduje si\u0119 aktualny master, zostanie on wybrany ponownie i przeniesie si\u0119 jako rola na inny w\u0119ze\u0142 w innym DC.<\/li>\n<li>Master szybko usunie z klastra wszystkie niedost\u0119pne w\u0119z\u0142y.<\/li>\n<li>Na podstawie pozosta\u0142ych danych zrozumie, \u017ce w zaginionym centrum danych mieli\u015bmy takie primary shard'y, szybko promuj\u0105c komplementarne replica shard'y w pozosta\u0142ych centrach danych, co umo\u017cliwi nam kontynuacj\u0119 indeksacji danych. <\/li>\n<li>W wyniku tego nasza przepustowo\u015b\u0107 klastra do zapisu i odczytu b\u0119dzie stopniowo si\u0119 degradowa\u0107, jednak w og\u00f3lnym rozrachunku wszystko b\u0119dzie dzia\u0142a\u0107, cho\u0107 wolno, to stabilnie.<\/li>\n<\/ul>\n<p><\/p>\n<p>Jak si\u0119 okaza\u0142o, chcieli\u015bmy czego\u015b takiego:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/71fa3d19a61eb58ddb93a4df55c759c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A otrzymali\u015bmy to:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/ab32be4dfbbb4bcc3279d57021707980.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak do tego dosz\u0142o? <\/p>\n<p><\/p>\n<p>W momencie awarii centrum danych naszym w\u0105skim gard\u0142em sta\u0142 si\u0119 master.<\/p>\n<p><\/p>\n<p>Dlaczego?<\/p>\n<p><\/p>\n<p>Chodzi o to, \u017ce w masterze znajduje si\u0119 TaskBatcher, odpowiedzialny za rozprzestrzenianie okre\u015blonych zada\u0144 i zdarze\u0144 w klastrze. Jakiekolwiek wyj\u015bcie w\u0119z\u0142a, jakiekolwiek promowanie shard'a z replica do primary, jakiekolwiek zadanie dotycz\u0105ce stworzenia shard'a \u2014 wszystko to trafia najpierw do TaskBatcher'a, gdzie jest przetwarzane sekwencyjnie w jednym w\u0105tku.<\/p>\n<p><\/p>\n<p>W momencie wy\u0142\u0105czenia jednego centrum danych wszystkie w\u0119z\u0142y danych w pozosta\u0142ych centrach uznawa\u0142y za sw\u00f3j obowi\u0105zek informowanie master'a \"stracili\u015bmy takie shard'y i takie w\u0119z\u0142y danych.\" <\/p>\n<p><\/p>\n<p>Przy tym pozosta\u0142e w\u0119z\u0142y danych przesy\u0142a\u0142y t\u0119 informacj\u0119 aktualnemu master'owi i pr\u00f3bowa\u0142y czeka\u0107 na potwierdzenie, \u017ce j\u0105 przyj\u0105\u0142. Nie doczeka\u0142y si\u0119, poniewa\u017c master otrzymywa\u0142 zadania szybciej, ni\u017c zd\u0105\u017cy\u0142 odpowiada\u0107. W\u0119z\u0142y powtarza\u0142y zapytania po up\u0142ywie czasu, a master w tym czasie przesta\u0142 pr\u00f3bowa\u0107 na nie odpowiada\u0107, b\u0119d\u0105c ca\u0142kowicie poch\u0142oni\u0119ty sortingiem zapyta\u0144 wed\u0142ug priorytet\u00f3w.<\/p>\n<p><\/p>\n<p>W skrajnych przypadkach wygl\u0105da\u0142o to tak, \u017ce w\u0119z\u0142y danych spamowa\u0142y master'a do tego stopnia, \u017ce przechodzi\u0142 on w full GC. Po tym rola master'a przechodzi\u0142a na jaki\u015b nast\u0119pny w\u0119ze\u0142, z kt\u00f3rym dzia\u0142o si\u0119 dok\u0142adnie to samo, i ostatecznie klaster ca\u0142kowicie si\u0119 rozpada\u0142. <\/p>\n<p><\/p>\n<p>Przeprowadzili\u015bmy pomiary, i do wersji 6.4.0, gdzie to naprawiono, wystarczy\u0142o, aby wy\u0142\u0105czy\u0107 jednocze\u015bnie tylko 10 w\u0119z\u0142\u00f3w danych z 360, aby ca\u0142kowicie zawali\u0107 klaster.<\/p>\n<p><\/p>\n<p>Wygl\u0105da\u0142o to mniej wi\u0119cej tak:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/3bed554b2703e7521339e9d943648ee4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Po wersji 6.4.0, w kt\u00f3rej naprawiono ten problem, w\u0119z\u0142y danych przesta\u0142y zabija\u0107 master'a. Ale przez to nie sta\u0142 si\u0119 'm\u0105drzejszy'. A dok\u0142adniej: kiedy wy\u0142\u0105czamy 2, 3 lub 10 (dowoln\u0105 liczb\u0119 poza jedn\u0105) w\u0119z\u0142\u00f3w danych, master otrzymuje jakie\u015b pierwsze powiadomienie, kt\u00f3re m\u00f3wi, \u017ce w\u0119ze\u0142 A si\u0119 wy\u0142\u0105czy\u0142, i pr\u00f3buje o tym opowiedzie\u0107 w\u0119z\u0142owi B, w\u0119z\u0142owi C, w\u0119z\u0142owi D. <\/p>\n<p><\/p>\n<p>Na chwil\u0119 obecn\u0105 mo\u017cna temu zaradzi\u0107 tylko poprzez ustawienie limitu czasowego na pr\u00f3by komunikacji z kim\u015b, wynosz\u0105cego oko\u0142o 20-30 sekund, co pozwala zarz\u0105dza\u0107 pr\u0119dko\u015bci\u0105 wyj\u015bcia centrum danych z klastra.<\/p>\n<p><\/p>\n<p>Zasadniczo mie\u015bci si\u0119 to w wymaganiach, kt\u00f3re pierwotnie zosta\u0142y postawione wobec ko\u0144cowego produktu w projekcie, ale z punktu widzenia 'czystej nauki' to b\u0142\u0105d. Tak czy inaczej, zosta\u0142 on skutecznie naprawiony przez programist\u00f3w w wersji 7.2.<\/p>\n<p><\/p>\n<p>Co wi\u0119cej, kiedy pewien w\u0119ze\u0142 danych wychodzi\u0142, okazywa\u0142o si\u0119, \u017ce rozprzestrzenienie informacji o jego wyj\u015bciu jest wa\u017cniejsze ni\u017c powiadomienie ca\u0142ego klastra, \u017ce znajdowa\u0142y si\u0119 na nim takie a takie primary-shardy (aby promowa\u0107 replica-shard w innym centrum danych do primary, co umo\u017cliwia\u0142o zapisywanie informacji).<\/p>\n<p><\/p>\n<p>Dlatego gdy wszystko ju\u017c 'przygas\u0142o', wyszed\u0142e w\u0119z\u0142y danych nie s\u0105 natychmiast oznaczane jako stale. W zwi\u0105zku z tym musimy czeka\u0107, a\u017c wszystkie pingi do wysz\u0142ych w\u0119z\u0142\u00f3w danych dojd\u0105 do timeoutu, a dopiero potem nasz klaster zaczyna informowa\u0107 o tym, gdzie nale\u017cy kontynuowa\u0107 zapis informacji. Wi\u0119cej szczeg\u00f3\u0142\u00f3w mo\u017cna przeczyta\u0107 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/elastic\/elasticsearch\/issues\/46909\">tutaj<\/a><\/noindex>. <\/p>\n<p><\/p>\n<p>W rezultacie operacja wyj\u015bcia centrum danych zajmuje nam dzi\u015b oko\u0142o 5 minut w godzinach szczytu. Dla tak du\u017cej i niepor\u0119cznej machiny, jest to ca\u0142kiem dobry wynik.<\/p>\n<p><\/p>\n<p>Ostatecznie doszli\u015bmy do nast\u0119puj\u0105cego rozwi\u0105zania:<\/p>\n<p><\/p>\n<ul>\n<li>Mamy 360 w\u0119z\u0142\u00f3w danych z dyskami o pojemno\u015bci 700 gigabajt\u00f3w.<\/li>\n<li>60 koordynator\u00f3w do routingu ruchu pomi\u0119dzy tymi w\u0142a\u015bnie w\u0119z\u0142ami danych.<\/li>\n<li>40 master\u00f3w, kt\u00f3re wci\u0105\u017c posiadamy jako pewnego rodzaju spu\u015bcizn\u0119 z czas\u00f3w przed wersj\u0105 6.4.0 \u2014 aby przetrwa\u0107 wyj\u015bcie centrum danych, byli\u015bmy mentalnie przygotowani na utrat\u0119 kilku maszyn, aby zagwarantowa\u0107, \u017ce nawet w najgorszym scenariuszu b\u0119dziemy mieli quorum master\u00f3w.<\/li>\n<li>Jakiekolwiek pr\u00f3by \u0142\u0105czenia r\u00f3l na jednym kontenerze ko\u0144czy\u0142y si\u0119 tym, \u017ce pr\u0119dzej czy p\u00f3\u017aniej w\u0119ze\u0142 psu\u0142 si\u0119 pod obci\u0105\u017ceniem. <\/li>\n<li>W ca\u0142ym klastrze u\u017cywa si\u0119 heap.size r\u00f3wnemu 31 gigabajt\u00f3w: wszelkie pr\u00f3by zmniejszenia rozmiaru prowadzi\u0142y do tego, \u017ce przy ci\u0119\u017ckich zapytaniach wyszukiwania z prowadz\u0105cym wildcard albo psu\u0142y si\u0119 jakie\u015b w\u0119z\u0142y, albo wy\u0142\u0105cza\u0142 si\u0119 circuit breaker w samym Elasticsearch.<\/li>\n<li>Ponadto, aby zapewni\u0107 wydajno\u015b\u0107 wyszukiwania, starali\u015bmy si\u0119 utrzymywa\u0107 liczb\u0119 obiekt\u00f3w w klastrze na minimalnym mo\u017cliwym poziomie, aby przetwarza\u0107 jak najmniej zdarze\u0144 w najszlachetniejszym miejscu, kt\u00f3re uda\u0142o nam si\u0119 uzyska\u0107 w masterze.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"naposledok-o-monitoringe\">Na koniec o monitorowaniu.<\/h2>\n<p><\/p>\n<p>Aby to wszystko dzia\u0142a\u0142o tak, jak zamierzono, monitorujemy nast\u0119puj\u0105ce rzeczy:<\/p>\n<p><\/p>\n<ul>\n<li>Ka\u017cdy w\u0119ze\u0142 w datacenter zg\u0142asza si\u0119 do naszej chmury, informuj\u0105c, \u017ce jest obecny i ma takie a takie shard'y. Kiedy gdzie\u015b co\u015b wy\u0142\u0105czamy, klaster po 2-3 sekundach informuje nas, \u017ce w centrum A wy\u0142\u0105czyli\u015bmy w\u0119z\u0142y 2, 3 i 4 \u2014 oznacza to, \u017ce w innych datacentrach nie mo\u017cemy wy\u0142\u0105cza\u0107 tych w\u0119z\u0142\u00f3w, na kt\u00f3rych pozosta\u0142y shard'y w pojedynczym egzemplarzu.<\/li>\n<li>Znaj\u0105c charakter zachowania mastera, bardzo uwa\u017cnie obserwujemy liczb\u0119 zada\u0144 oczekuj\u0105cych. Poniewa\u017c nawet jedno wisz\u0105ce zadanie, je\u015bli nie timeoutuje si\u0119 na czas, teoretycznie w jakiej\u015b krytycznej sytuacji mo\u017ce sta\u0107 si\u0119 powodem, dla kt\u00f3rego na przyk\u0142ad nie powiedzie si\u0119 promocja shard'a replica na primary, przez co przestanie dzia\u0142a\u0107 indeksacja.<\/li>\n<li>R\u00f3wnie\u017c bardzo dok\u0142adnie zwracamy uwag\u0119 na op\u00f3\u017anienia garbage collector'a, poniewa\u017c mieli\u015bmy ju\u017c z tym powa\u017cne problemy przy optymalizacji.<\/li>\n<li>Odrzucenia w w\u0105tkach, aby wcze\u015bniej wiedzie\u0107, gdzie znajduje si\u0119 \"w\u0105skie gard\u0142o\".<\/li>\n<li>No i standardowe metryki, takie jak heap, RAM i I\/O.<\/li>\n<\/ul>\n<p><\/p>\n<p>Przy budowaniu monitoringu koniecznie trzeba uwzgl\u0119dni\u0107 cechy Thread Pool w Elasticsearch. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/6.8\/modules-threadpool.html\">Dokumentacja Elasticsearch<\/a><\/noindex> opisem mo\u017cliwo\u015bci konfiguracji i warto\u015bci domy\u015blnych dla wyszukiwania, indeksacji, ale ca\u0142kowicie milczy na temat thread_pool.management. Te w\u0105tki obs\u0142uguj\u0105 mi\u0119dzy innymi zapytania typu _cat\/shards oraz inne podobne, kt\u00f3re s\u0105 wygodne do wykorzystania przy pisaniu monitoringu. Im wi\u0119kszy klaster, tym wi\u0119cej takich zapyta\u0144 wykonywanych jest w jednostce czasu, a wspomniany thread_pool.management jest nie tylko nieobecny w oficjalnej dokumentacji, ale r\u00f3wnie\u017c domy\u015blnie limitowany do 5 w\u0105tk\u00f3w, co bardzo szybko si\u0119 wyczerpuje, po czym monitoring przestaje dzia\u0142a\u0107 poprawnie.<\/p>\n<p><\/p>\n<p>Co chcia\u0142bym powiedzie\u0107 na koniec: uda\u0142o nam si\u0119! Uda\u0142o nam si\u0119 da\u0107 naszym programistom i deweloperom narz\u0119dzie, kt\u00f3re praktycznie w ka\u017cdej sytuacji potrafi szybko i wiarygodnie dostarczy\u0107 informacje o tym, co dzieje si\u0119 na produkcji.<\/p>\n<p><\/p>\n<p>Tak, to by\u0142o do\u015b\u0107 skomplikowane, ale mimo to uda\u0142o si\u0119 nasze oczekiwania wkomponowa\u0107 w istniej\u0105ce ju\u017c produkty, kt\u00f3re przy tym nie musieli\u015bmy \u0142ata\u0107 ani przepisywa\u0107 pod siebie.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Klastr Elasticsearch na 200 TB+\" src=\"\/wp-content\/uploads\/2020\/03\/1e852123ca5ec5eaec27bdc66b6c4e83.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/odnoklassniki\/blog\/494260\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0421 Elasticsearch \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435. \u041d\u043e \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0448\u044c \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043b\u043e\u0433\u0438 \u00ab\u0432 \u043e\u0441\u043e\u0431\u043e \u043a\u0440\u0443\u043f\u043d\u043e\u043c \u043e\u0431\u044a\u0451\u043c\u0435\u00bb? \u0414\u0430 \u0435\u0449\u0451 \u0438 \u0431\u0435\u0437\u0431\u043e\u043b\u0435\u0437\u043d\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u043e\u0432? \u041a\u0430\u043a\u043e\u0439 \u0441\u0442\u043e\u0438\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u0438 \u043d\u0430 \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 \u043d\u0430\u0442\u043a\u043d\u0451\u0448\u044c\u0441\u044f? \u041c\u044b \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 elasticsearch \u0440\u0435\u0448\u0438\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 \u043b\u043e\u0433-\u043c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442\u0430, \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0425\u0430\u0431\u0440\u043e\u043c \u043e\u043f\u044b\u0442\u043e\u043c: \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":75797,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-75796","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0421 Elasticsearch \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/klaster-elasticsearch-na-200-tb\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u043b\u0430\u0441\u0442\u0435\u0440 Elasticsearch \u043d\u0430 200 \u0422\u0411+ | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0421 Elasticsearch \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/klaster-elasticsearch-na-200-tb\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-03-28T17:42:18+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-28T17:42:18+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83c\udfc6Klaster Elasticsearch na 200 TB+ | ProHoster","description":"Z Elasticsearch spotyka si\u0119 wielu.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/klaster-elasticsearch-na-200-tb","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u043b\u0430\u0441\u0442\u0435\u0440 Elasticsearch \u043d\u0430 200 \u0422\u0411+ | ProHoster","og:description":"\u0421 Elasticsearch \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/klaster-elasticsearch-na-200-tb","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-03-28T17:42:18+00:00","article:modified_time":"2020-03-28T17:42:18+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"75796","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 17:49:32","updated":"2022-09-27 21:24:26","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/75796","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=75796"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/75796\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/75797"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=75796"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=75796"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=75796"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}