Elasticsearch w produkcji - najlepsze praktyki wdrażania

Elasticsearch to wysoce zoptymalizowana wyszukiwarka do nowoczesnej analizy danych.

Elasticsearch to niesamowity silnik wyszukiwania i analizy w czasie rzeczywistym. Jest zbudowany na Apache Lucene. Jest rozpowszechniany, RESTful, łatwy w użyciu i wysoce dostępny. Przypadki użycia elasticsearch obejmują wspomaganie wyszukiwania, monitorowanie transakcji i wykrywanie błędów, wykrywanie treści, analitykę dziennika, wyszukiwanie rozmyte, agregację danych zdarzeń, wizualizację danych. Elasticsearch i reszta elastycznego stosu okazały się niezwykle wszechstronne, a jak widać powyżej przypadki użycia, istnieje wiele sposobów na zintegrowanie Elasticsearch z tym, co dostarcza dzisiaj twój produkt i dodanie do niego dodatkowego wglądu.

Używamy go intensywnie do wyszukiwania i analiz w Botmetric, indeksujemy około miliarda dokumentów dziennie i używamy bardzo złożonych agregacji do wizualizacji danych w czasie rzeczywistym.

To powiedziawszy, ładowanie aplikacji w porównaniu do uruchamiania jej w produkcji i utrzymaniu jest zupełnie inne. Ta arka obejmuje wiele z tych czynników z prawdziwych doświadczeń życiowych i jest podstawowymi powszechnymi elementami, które należy wziąć pod uwagę przy prowadzeniu Elasticsearch w produkcji.

Pamięć:

Elasticsearch i Lucene są napisane w Javie, co oznacza, że ​​musisz uważać na sterty sterty i statystyki JVM. Im więcej sterty jest dostępne dla Elasticsearch, tym więcej pamięci może użyć do filtrowania i innego buforowania w celu zwiększenia wydajności zapytań. Pamiętaj jednak, że zbyt dużo sterty może spowodować długie przerwy w usuwaniu elementów bezużytecznych. Nie ustawiaj Xmx powyżej wartości granicznej używanej przez JVM dla wskaźników skompresowanych obiektów (skompresowane ups); dokładna wartość graniczna jest różna, ale wynosi około 32 GB.

Częstym problemem jest konfigurowanie zbyt dużej sterty. Masz maszynę o pojemności 64 GB - i na golly, chcesz dać Elasticsearch wszystkie 64 GB pamięci. Wiecej znaczy lepiej! Kupa jest zdecydowanie ważna dla Elasticsearch. Jest używany przez wiele struktur danych w pamięci, aby zapewnić szybkie działanie. Ale powiedziawszy to, istnieje inny główny użytkownik pamięci, który jest poza stertą: pamięć podręczna plików systemu operacyjnego.

Lucene ma na celu wykorzystanie bazowego systemu operacyjnego do buforowania struktur danych w pamięci. Segmenty Lucene są przechowywane w osobnych plikach. Ponieważ segmenty są niezmienne, pliki te nigdy się nie zmieniają. To sprawia, że ​​są bardzo przyjazne dla pamięci podręcznej, a podstawowy system operacyjny chętnie zatrzyma gorące segmenty w pamięci, aby uzyskać szybszy dostęp. Segmenty te obejmują zarówno indeks odwrócony (dla wyszukiwania pełnotekstowego), jak i wartości doc (dla agregacji). Wydajność Lucene zależy od interakcji z systemem operacyjnym. Ale jeśli oddasz całą dostępną pamięć do stosu Elasticsearch, nie pozostanie żadna pamięć podręczna plików systemu operacyjnego. Może to poważnie wpłynąć na wydajność. Standardowym zaleceniem jest przekazanie sterty elasticsearch 50% dostępnej pamięci, a pozostałe 50% wolnej. Nie pozostanie nieużywany; Lucene chętnie zużyje wszystko, co pozostało do buforowania plików. Kupkę Elasticsearch można skonfigurować w następujący sposób:

eksport ES_HEAP_SIZE = 10g

lub

ES_JAVA_OPTS = "- Xms10g -Xmx10g" ./bin/elasticsearch

PROCESOR:

Elasticsearch obsługuje agregacje i filtrowane zapytania. Uruchamianie złożonych kwerend filtrowanych, intensywne indeksowanie, perkolacja i zapytania względem indeksów wymagają dużego procesora, więc wybranie odpowiedniego jest bardzo ważne. Należy zrozumieć specyfikacje procesorów i ich zachowanie w Javie, gdy zapytania są uruchamiane w JVM.

Każda pula obsługuje wiele wątków, które można skonfigurować i ma kolejkę. Zmiana tego nie jest zalecana, chyba że masz bardzo specyficzne wymagania, ponieważ Elasticsearch dokonuje alokacji rdzeni dynamicznie.

Rodzaje pul wątków:

Elasticsearch ma 3 typy pul wątków.

  1. Buforowane: buforowana pula wątków to niezwiązana pula wątków, która odrodzi się w wątku, jeśli istnieją oczekujące żądania. Ta pula wątków służy do zapobiegania blokowaniu lub odrzucaniu żądań przesyłanych do tej puli. Nieużywane wątki w tej puli wątków zostaną zakończone po wygaśnięciu utrzymania aktywności (domyślnie pięć minut). Buforowana pula wątków jest zarezerwowana dla ogólnej puli wątków.
  2. Naprawiono: stała pula wątków zawiera stały rozmiar wątków do obsługi żądań z kolejką (opcjonalnie ograniczoną) dla oczekujących żądań, które nie mają wątków do ich obsługi. Parametr size kontroluje liczbę wątków i domyślnie przyjmuje liczbę rdzeni razy 5.
  3. Skalowanie: pula wątków skalujących zawiera dynamiczną liczbę wątków. Liczba ta jest proporcjonalna do obciążenia pracą i waha się między 1 a wartością parametru rozmiaru.

Elasticsearch dzieli użycie procesora na pule wątków różnego typu:

  • ogólne: w przypadku standardowych operacji, takich jak wykrywanie i typ puli wątków, jest buforowany.
  • indeks: do operacji indeksowania / usuwania. Typ puli wątków jest ustalony.
  • szukaj: dla operacji zliczania / wyszukiwania. Typ puli wątków jest ustalony.
  • get: dla operacji get. Typ puli wątków jest ustalony.
  • luzem: do operacji masowych, takich jak indeksowanie masowe. Typ puli wątków jest ustalony. Najlepsza konfiguracja dokumentów zbiorczych zależy od konfiguracji klastra, którą można zidentyfikować, wypróbowując wiele wartości.
  • perkolacja: do perkolacji. Typ puli wątków jest ustalony.
  • Odśwież: Do operacji odświeżania. Typ puli wątków jest skalowany.

Zmiana konkretnej puli wątków można wykonać, ustawiając parametry specyficzne dla typu.

Czytaj więcej https://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-threadpool.html#types

Rozmiar odłamka:

Odłamek to jednostka, w której Elasticsearch dystrybuuje dane w klastrze. Szybkość, z jaką Elasticsearch może przesuwać odłamki podczas ponownego równoważenia danych, np. po awarii zależy od wielkości i liczby odłamków, a także wydajności sieci i dysku.

W Elasticsearch każde zapytanie jest wykonywane w jednym wątku na odłamek. Wiele fragmentów można jednak przetwarzać równolegle, podobnie jak wiele zapytań i agregacji dla tego samego fragmentu.

Oznacza to, że minimalne opóźnienie zapytania, gdy nie jest używane buforowanie, będzie zależeć od danych, rodzaju zapytania, a także rozmiaru odłamka. Zapytanie o wiele małych odłamków przyspieszy przetwarzanie na odłamek, ale ponieważ o wiele więcej zadań trzeba ustawić w kolejce i przetworzyć w sekwencji, niekoniecznie będzie to szybsze niż zapytanie o mniejszą liczbę większych odłamków. Posiadanie wielu małych odłamków może również zmniejszyć przepustowość zapytań, jeśli istnieje wiele współbieżnych zapytań.

Każdy odłamek ma dane, które muszą być przechowywane w pamięci i wykorzystuje przestrzeń sterty. Obejmuje to struktury danych przechowujące informacje na poziomie niezależnego fragmentu, a także na poziomie segmentu w celu określenia, gdzie dane znajdują się na dysku. Rozmiar tych struktur danych nie jest stały i będzie się różnić w zależności od przypadku użycia. Jedną ważną cechą narzutu związanego z segmentem jest jednak to, że nie jest on ściśle proporcjonalny do wielkości segmentu. Oznacza to, że większe segmenty mają mniejszy narzut na wolumen danych w porównaniu do mniejszych segmentów. Różnica może być znaczna. Wybór odpowiedniej liczby odłamków jest skomplikowany, ponieważ nigdy nie wiesz, ile dokumentów otrzymasz przed rozpoczęciem. Posiadanie wielu odłamków może być zarówno dobre, jak i straszne dla gromady. Zarządzanie indeksami i odłamkami może przeciążać węzeł główny, co może przestać odpowiadać, co prowadzi do dziwnych i nieprzyjemnych zachowań. Przydziel swoim głównym węzłom wystarczającą ilość zasobów, aby poradzić sobie z rozmiarem klastra.

Złą rzeczą jest to, że liczba odłamków jest niezmienna i jest definiowana podczas tworzenia indeksu. Po utworzeniu indeksu jedynym sposobem zmiany liczby odłamków jest usunięcie indeksów, utworzenie ich ponownie i ponowneindeksowanie.

Replikacja

Elasticsearch obsługuje replikację, dane są replikowane między węzłami danych, więc utrata węzła nie doprowadziłaby do utraty danych. Domyślnie współczynnik replikacji wynosi 1, ale w zależności od wymagań produktu można go zwiększyć. Im więcej replik, tym bardziej będą odporne na awarie Twoje dane. Kolejną zaletą posiadania większej liczby replik jest to, że każdy węzeł zawiera odłamek repliki, co poprawia wydajność kwerendy, ponieważ repliki są również używane do kwerend.

Formuła replikacji używana przez Elasticsearch dla spójności jest następująca:

(podstawowy + liczba_replicas) / 2 + 1

Optymalizacja alokacji

W oparciu o wymagania dotyczące danych produktu możemy podzielić dane na gorące i zimne. Indeksy, do których dostęp jest uzyskiwany częściej niż inne, można przydzielić więcej węzłów danych, podczas gdy indeksy, do których dostęp jest rzadziej dostępny, mogą mieć przydzielone mniej zasobów. Ta strategia jest szczególnie przydatna do przechowywania danych szeregów czasowych, takich jak dzienniki aplikacji (np .: ELK).

Można to osiągnąć, uruchamiając cronjob, który przenosi indeksy do różnych węzłów w regularnych odstępach czasu.

Gorący węzeł to rodzaj węzła danych, który wykonuje wszystkie indeksowania w klastrze. Posiadają również najnowsze wskaźniki, ponieważ zwykle są one najczęściej wyszukiwane. Ponieważ indeksowanie jest operacją intensywną pod względem procesorów i operacji we / wy, serwery te muszą być wydajne i zabezpieczone przez dołączoną pamięć SSD. Zalecamy uruchomienie co najmniej 3 gorących węzłów w celu zapewnienia wysokiej dostępności. Jednak w zależności od ilości ostatnich danych, które chcesz gromadzić i wyszukiwać, może być konieczne zwiększenie tej liczby, aby osiągnąć swoje cele w zakresie wydajności.

Ciepły węzeł to rodzaj węzła danych zaprojektowanego do obsługi dużej liczby indeksów tylko do odczytu, które nie są tak często pytane. Ponieważ te wskaźniki są tylko do odczytu, ciepły węzeł zwykle wykorzystuje duże podłączone dyski (zwykle dyski obrotowe) zamiast dysków SSD. Podobnie jak w przypadku gorącego węzła, zalecamy co najmniej 3 ciepłe węzły dla wysokiej dostępności. I tak jak poprzednio, z zastrzeżeniem, że większe ilości danych mogą wymagać dodatkowych węzłów w celu spełnienia wymagań dotyczących wydajności. Należy również pamiętać, że konfiguracje procesora i pamięci często będą musiały odzwierciedlać te z twoich gorących węzłów. Można to ustalić tylko poprzez przetestowanie zapytań podobnych do tych, które wystąpiłyby w sytuacji produkcyjnej.

Więcej informacji na temat ciepłego i ciepłego węzła znajduje się tutaj.

Inną strategią, którą możesz dostosować, jest archiwizacja indeksów do s3 i przywracanie, gdy potrzebujesz danych z tych indeksów. Możesz przeczytać więcej o tym tutaj.

Topologia węzła:

Węzły Elasticsearch można podzielić na trzy kategorie: węzeł główny, węzeł danych, węzeł klienta.

  1. Węzeł główny: węzeł główny może być mały, jeśli nie jest również węzłem danych, ponieważ nie przechowuje żadnych indeksów / odłamków. Do jego obowiązków należy przechowywanie szczegółowego stanu klastra oraz pomoc w danych i innych węzłach w wyszukiwaniu metadanych indeksów / odłamków. Elasticsearch powinien mieć wiele węzłów głównych, aby uniknąć problemu podziału mózgu.
  2. Węzeł danych: Węzeł danych jest odpowiedzialny za przechowywanie / sprawdzanie rzeczywistych danych indeksu.
  3. Węzeł klienta: Węzeł klienta jest używany jako serwer proxy do indeksowania i wyszukiwania. Jest to wysoce zalecane, jeśli agregacje są intensywnie używane. Są to specjalne węzły ElasticSearch, które nie kwalifikują się ani do danych, ani do wzorca. Węzły klienckie rozpoznają klaster i dlatego mogą działać jako inteligentne usługi równoważenia obciążenia. Możesz wysłać swoje zapytania do węzłów klienta, które mogą podjąć kosztowne zadanie zebrania odpowiedzi na wyniki zapytania z każdego z węzłów danych.

dodaj te ustawienia do pliku elasticsearch.yml dla odpowiednich węzłów.

Węzeł główny: node.master: true node.data:false
Węzeł danych: node.master: false node.data:true
Węzeł klienta: node.master: false node.data:false

Wskazówki dotyczące rozwiązywania problemów:

Wydajność wyszukiwania elastycznego zależy w dużej mierze od komputera, na którym jest zainstalowany. Procesor, użycie pamięci i dyskowe operacje we / wy to podstawowe parametry systemu operacyjnego dla każdego węzła Elasticsearch. Zaleca się przyjrzenie się wskaźnikom wirtualnej maszyny Java (JVM), gdy zużycie procesora gwałtownie wzrasta. W poniższym przykładzie przyczyną tego wzrostu była wyższa aktywność odśmiecania.

  1. Ciśnienie stosu: wysokie ciśnienie pamięci wpływa na wydajność klastra na dwa sposoby: gdy ciśnienie pamięci wzrasta do 75% i więcej, pozostaje mniej pamięci, a teraz klaster musi również wydać trochę zasobów procesora, aby odzyskać pamięć poprzez zbieranie pamięci. Te cykle procesora nie są dostępne do obsługi żądań użytkowników, gdy jest włączone czyszczenie pamięci. W rezultacie czasy odpowiedzi na żądania użytkowników wydłużają się, gdy system staje się coraz bardziej ograniczony zasobami. Jeśli presja pamięci nadal rośnie i osiąga prawie 100%, stosowana jest znacznie bardziej agresywna forma zbierania śmieci, co z kolei dramatycznie wpływa na czas odpowiedzi klastra. Wskaźnik czasów odpowiedzi indeksu pokazuje, że wysokie ciśnienie pamięci prowadzi do znacznego wpływu na wydajność.
  2. Wzrost w pamięci non-heap JVM, niszcząc pamięć przeznaczoną na bufor strony i prawdopodobnie powodując zbieranie OOM na poziomie jądra.
  3. Unikaj problemu podzielonego mózgu. Rozszczepiony mózg to scenariusz, w którym klaster się rozpada. Na przykład masz klaster 6 węzłów. 2 węzły rozłączają się z klastrem, ale nadal mogą się widzieć. Te 2 węzły następnie tworzą kolejny klaster. Wybiorą nawet między sobą nowego mistrza. Mamy teraz dwa klastry o tej samej nazwie, jeden z 4 węzłami, a drugi z 2 węzłami. Każdy ma również węzeł główny. Nazywa się to problemem podziału mózgu w klastrach ES. Aby tego uniknąć, ustaw parametr discovery.zen.minimum_master_nodes parametru ES na połowę liczby węzłów + 1.
  4. Ponieważ Elasticsearch intensywnie wykorzystuje urządzenia pamięci masowej, monitorowanie We / Wy dysku zapewnia, że ​​ta podstawowa potrzeba zostanie zaspokojona. Istnieje wiele przyczyn zmniejszonej liczby operacji we / wy dysku, uważanych za kluczową miarę do przewidywania wielu rodzajów problemów. Dobrym miernikiem jest sprawdzenie skuteczności indeksowania i wydajności zapytań. Analiza operacji odczytu i zapisu bezpośrednio wskazuje, czego system najbardziej potrzebuje w konkretnym przypadku użycia. Ustawienia systemu operacyjnego dla I / O dysku są podstawą wszystkich innych optymalizacji, a dostrojenie I / O dysku pozwala uniknąć potencjalnych problemów. Jeśli dyskowe operacje we / wy są nadal niewystarczające, należy ocenić środki zaradcze, takie jak optymalizacja liczby odłamków i ich rozmiaru, ograniczanie fuzji, zastępowanie wolnych dysków, przenoszenie na dyski SSD lub dodawanie większej liczby węzłów zgodnie z okolicznościami powodującymi operacje we / wy wąskie gardła.
  5. W przypadku aplikacji, które korzystają z wyszukiwania, wygoda użytkownika jest silnie skorelowana z opóźnieniem żądań wyszukiwania. Istnieje wiele czynników, które mogą wpływać na wydajność zapytań, takich jak skonstruowane zapytania, nieprawidłowo skonfigurowany klaster Elasticsearch, problemy z pamięcią JVM i usuwaniem śmieci, operacje dyskowe IO itd. Opóźnienie zapytania to metryka, która bezpośrednio wpływa na użytkowników, więc upewnij się, że umieściłeś na nim alerty.
  6. Większość filtrów w Elasticsearch jest domyślnie buforowana. Oznacza to, że podczas pierwszego wykonania filtrowanego zapytania Elasticsearch znajdzie dokumenty pasujące do filtru i zbuduje strukturę zwaną „zestawem bitów” na podstawie tych informacji. Dane przechowywane w zestawie bitów zawierają identyfikator dokumentu i to, czy dany dokument pasuje do filtra. Kolejne wykonywanie zapytań mających ten sam filtr ponownie wykorzysta informacje zapisane w zestawie bitów, dzięki czemu wykonanie zapytania będzie szybsze dzięki zapisaniu operacji we / wy i cykli procesora. Zalecane jest użycie filtra w zapytaniu. Aby uzyskać więcej informacji, patrz tutaj.
  7. Czas odświeżania i czas scalania są ściśle związane z wydajnością indeksowania, a ponadto wpływają na ogólną wydajność klastra. Czas odświeżania wzrasta wraz z liczbą operacji na plikach dla indeksu Lucene (fragment).
  8. Włączenie powolnego rejestrowania zapytań pomoże określić, które zapytania są wolne i co można zrobić, aby je poprawić, szczególnie przydatne w przypadku zapytań wieloznacznych.
  9. Zwiększ rozmiar ulimit, aby zezwolić na maksymalne pliki.
  10. Wydajność ElasticSearch może ucierpieć, gdy system operacyjny zdecyduje się wymienić nieużywaną pamięć aplikacji. Wyłącz zamianę, ustawiając ustawienia na poziomie systemu operacyjnego lub ustaw następujące opcje w konfiguracji ElasticSearch bootstrap.mlockall: true
  11. Wyłącz usuwanie wszystkich indeksów przez zapytanie z użyciem symboli wieloznacznych. Aby upewnić się, że ktoś nie wykona operacji DELETE na wszystkich indeksach (* lub _all), ustaw action.destructive_requires_name na true.

Przed zakończeniem oto lista adresów URL, które są przydatne do oglądania danych.

  • / _cluster / health? pretty: Dla wskaźnika kondycji klastra.
  • / _status? pretty: wszystkie informacje o wszystkich indeksach.
  • / _nodes? pretty: wszystkie informacje o węzłach.
  • / _cat / master? pretty: dla węzła głównego.
  • / _stats? pretty: w przypadku alokacji niezależnych fragmentów statystyki indeksów.
  • / _nodes / stats? pretty: W przypadku statystyk poszczególnych węzłów obejmuje to statystyki jvm, http, io dla węzła.

Agregacja wskaźników w Elasticsearch jest obsługiwana przez większość narzędzi do monitorowania systemu, takich jak Datadog, TICK. Zalecane jest korzystanie z takich narzędzi, a tworzenie lejka jest zalecane do ciągłego monitorowania Elasticsearch.

Wniosek:

Elasticsearch to rozproszony mechanizm wyszukiwania pełnotekstowego i analizy, który pozwala wielu najemcom przeszukiwać całe zestawy danych, niezależnie od wielkości, z niespotykaną prędkością. Oprócz możliwości wyszukiwania pełnotekstowego, ElasticSearch pełni również funkcję systemu analitycznego i rozproszonej bazy danych. ElasticSearch ma świetne ustawienia domyślne na początek. Ale kiedy minie początkowy etap eksperymentów, musisz poświęcić trochę czasu na dostosowanie ustawień do swoich potrzeb. Zaleca się ponowne sprawdzenie konfiguracji wraz z oficjalną dokumentacją, aby upewnić się, że klaster jest skonfigurowany zgodnie z Twoimi potrzebami.