Elasticsearch în producție - Cele mai bune practici pentru implementare

Elasticsearch este un motor de căutare extrem de optimizat pentru analiza modernă a datelor.

Elasticsearch este un motor uimitor de căutare și analiză în timp real. Este construit pe Apache Lucene. Este distribuit, RESTIT, ușor de pornit și foarte disponibil. Cazurile de utilizare Elasticsearch includ alimentarea căutării, monitorizarea tranzacțiilor și detectarea erorilor, descoperirea conținutului, analiza jurnalului, căutarea confuză, agregarea datelor evenimentelor, vizualizarea datelor. Elasticsearch și restul Elastic Stack s-au dovedit a fi extrem de versatile și, după cum puteți vedea cazurile de utilizare de mai sus, există mai multe modalități de a integra Elasticsearch în ceea ce livrează produsul dvs. astăzi și să îi adăugați un plus de vedere.

Îl utilizăm foarte mult pentru căutare și analize la Botmetric, indexăm aproximativ un miliard de documente pe zi și folosim agregări foarte complexe pentru vizualizarea datelor în timp real.

Acestea fiind spuse, bootstrapping-ul unei aplicații vs rularea acesteia în producție și întreținere sunt total diferite. Această arcul acoperă mulți dintre acești factori din experiențele de viață reală și sunt elementele comune de bază pe care ar trebui să le luați în considerare pentru rularea Elasticsearch în producție.

Memorie:

Elasticsearch și Lucene sunt scrise în Java, ceea ce înseamnă că trebuie să te uiți la spațiul heapspace și JVM. Cu cât mai multă disponibilitate este Elasticsearch, cu atât mai multă memorie poate fi folosită pentru filtru și alte cache pentru a crește performanța interogării. Rețineți însă că prea multă grămadă te poate supune unor pauze lungi de colectare a gunoiului. Nu setați Xmx peste limita de siguranță pe care JVM o folosește pentru indicatoarele cu obiect comprimat (oops comprimat); limita exactă variază, dar este aproape de 32 GB.

O problemă comună este configurarea unui grup prea mare. Aveți o mașină de 64 GB - și, în mod gol, doriți să dați Elasticsearch toate 64 GB memorie. Mai mult e mai bine! Mormanul este cu siguranță important pentru Elasticsearch. Este utilizat de multe structuri de date din memorie pentru a asigura o operare rapidă. Dar, cu acest lucru, există un alt utilizator major de memorie care este off-cache: sistem de memorie cache pentru fișiere.

Lucene este proiectat pentru a folosi sistemul de operare de bază pentru memorarea în cache a structurilor de date în memorie. Segmentele Lucene sunt stocate în fișiere individuale. Deoarece segmentele sunt imuabile, aceste fișiere nu se schimbă niciodată. Acest lucru le face foarte prietenoase în cache, iar sistemul de operare de bază va menține fericit segmentele calde rezidente în memorie pentru un acces mai rapid. Aceste segmente includ atât indexul inversat (pentru căutarea textului complet), cât și valorile doc (pentru agregări). Performanța lui Lucene se bazează pe această interacțiune cu sistemul de operare. Dar dacă dați toată memoria disponibilă mormanului Elasticsearch, nu va mai rămâne nimic pentru memoria cache de fișiere OS. Acest lucru poate avea un impact grav asupra performanței. Recomandarea standard este să acordăm 50% din memoria disponibilă Elapse Elasticsearch, lăsând în același timp celălalt 50% liber. Nu va fi neutilizat; Lucene va consuma din fericire orice rămâne pentru memoria cache de fișiere. Elasticsearch heap poate fi configurat în următoarele moduri,

export ES_HEAP_SIZE = 10g

sau

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

PROCESOR:

Elasticsearch acceptă agregări și interogări filtrate. Pentru a rula interogări filtrate complexe, indexare intensivă, percolare și interogări împotriva indicilor au nevoie de procesoare grele, astfel încât alegerea celui potrivit este esențială. Trebuie să înțelegeți specificațiile procesorului și cum se comportă cu Java pe măsură ce interogările sunt rulate pe JVM.

Fiecare pool rulează un număr de fire, care pot fi configurate și au o coadă. Modificarea acestui lucru nu este recomandată decât dacă aveți o cerință foarte specifică, deoarece Elasticsearch face alocarea nucleelor ​​în mod dinamic.

Tipuri de grup de fire:

Elasticsearch are 3 tipuri de bazine de fire.

  1. În memorie în cache: pool-ul de thread în cache este un pool de fire nelimitate care va genera un thread dacă există solicitări pendinte. Acest pool de thread este utilizat pentru a împiedica blocarea sau respingerea cererilor trimise la acest pool. Firele neutilizate în acest pool de fire vor fi încheiate după expirarea unei menținere în viață (valorile implicite la cinci minute). Grupul de threaduri din cache este rezervat pool-ului de filet generic.
  2. Soluționat: Grupul de fire fixe conține o dimensiune fixă ​​de fire pentru a gestiona solicitările cu o coadă (opțional, delimitat) pentru cererile în așteptare care nu au fire pentru a le deservi. Parametrul de dimensiune controlează numărul de fire, și implicit la numărul de nuclee de 5 ori.
  3. Scalare: pool-ul de filare de scalare conține un număr dinamic de fire. Acest număr este proporțional cu volumul de muncă și variază între 1 și valoarea parametrului de mărime.

Elasticsearch împarte utilizarea procesorului în grupuri de fire de diferite tipuri:

  • generice: pentru operațiunile standard, cum ar fi descoperirea și tipul pool de filet este în cache.
  • index: pentru operațiunile index / delete. Tipul grupului de fire este fix.
  • căutare: pentru operații de numărare / căutare. Tipul grupului de fire este fix.
  • obține: pentru operațiunile de obținere. Tipul grupului de fire este fix.
  • vrac: pentru operațiuni în vrac, cum ar fi indexarea în vrac. Tipul grupului de fire este fix. Cea mai bună configurație a documentelor în vrac depinde de configurația clusterului, aceasta putând fi identificată prin încercarea mai multor valori.
  • percolate: pentru percolare. Tipul grupului de fire este fix.
  • refresh: Pentru operații de actualizare. Tipul grupului de fire este de dimensiuni reduse.

Modificarea unui grup de thread-uri specifice se poate face prin setarea parametrilor specifici tipului său.

Citiți mai multe https://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-threadpool.html#types

Dimensiune ciob:

Partea este unitatea la care Elasticsearch distribuie date în cluster. Viteza cu care Elasticsearch poate muta cioburi în jurul reechilibrării datelor, de ex. în urma unui eșec, va depinde de dimensiunea și numărul de cioburi, precum și de performanța rețelei și a discului.

În Elasticsearch, fiecare interogare este executată într-un singur fir per fragment. Totuși, mai multe fragmente pot fi procesate în paralel, la fel ca și interogări și agregări multiple împotriva aceluiași fragment.

Acest lucru înseamnă că latența minimă a interogării, atunci când nu este implicată memoria în cache, va depinde de date, de tipul de interogare, precum și de dimensiunea fragmentului. Interogarea multor fragmente mici va face procesarea per bucată mai rapidă, dar întrucât mai multe sarcini trebuie să fie puse în coadă și procesate în ordine, nu va fi neapărat mai rapid decât interogarea unui număr mai mic de fragmente mai mari. Dacă aveți o mulțime de fragmente mici, puteți reduce, de asemenea, debitul de interogare dacă există mai multe interogări simultane.

Fiecare bucată are date care trebuie păstrate în memorie și folosește spațiu de acumulatori. Aceasta include structuri de date care dețin informații la nivel de fragment și, de asemenea, la nivel de segment, pentru a defini locul în care datele se află pe disc. Mărimea acestor structuri de date nu este fixă ​​și va varia în funcție de cazul de utilizare. O caracteristică importantă a aerului în legătură cu segmentul este însă aceea că nu este strict proporțională cu dimensiunea segmentului. Acest lucru înseamnă că segmentele mai mari au cheltuieli aeriene mai mici pe volum de date, comparativ cu segmentele mai mici. Diferența poate fi substanțială. Alegerea numărului potrivit de fragmente este complicată, deoarece nu știi niciodată câte documente vei primi înainte de a începe. A avea o mulțime de cioburi poate fi atât bun, cât și teribil pentru un grup. Gestionarea indicilor și a cioburilor poate supraîncărca nodul principal, ceea ce ar putea deveni fără răspuns, ceea ce duce la un comportament ciudat și urât. Alocați nodurile master suficiente resurse pentru a face față dimensiunii clusterului.

Ceea ce este rău este că numărul de cioburi este imuabil și este definit atunci când creați indexul. Odată ce indexul este creat, singura modalitate de a modifica numărul de fragmente este să ștergi indicii, să îi creezi din nou și să te reindexezi.

replică

Elasticsearch acceptă replicarea, datele sunt replicate printre nodurile de date, astfel încât o pierdere de nod nu ar duce la pierderea datelor. În mod implicit, factorul de replicare este 1, dar în funcție de cerințele produsului dvs. acesta poate fi crescut. Cu cât vor fi mai multe replici, mai rezistente vor fi datele dvs. Un alt avantaj de a avea mai multe replici este faptul că fiecare nod conține un fragment de replică, ceea ce îmbunătățește performanța interogării, deoarece replicile sunt utilizate și pentru interogare.

Formula de replicare folosită de Elasticsearch pentru consecvență este,

(primar + număr_de_replică) / 2 + 1

Optimizarea alocării

Pe baza cerințelor de date despre produs, putem clasifica datele în cald și rece. Indicii la care este accesat mai frecvent decât alții, li se pot aloca mai multe noduri de date, în timp ce indicii care sunt accesați mai puțin frecvent, pot avea resurse mai puține alocate. Această strategie este utilă în special pentru stocarea datelor din seriile de timp precum jurnalele de aplicații (de exemplu: ELK).

Acest lucru se poate realiza rulând un cronjob care mută indicii la diferite noduri la intervale regulate.

Nodul fierbinte este un tip de nod care efectuează toate indexările din cluster. De asemenea, aceștia dețin cei mai recenți indici, deoarece aceștia au tendința de a fi interogați cel mai frecvent. Deoarece indexarea este o operație intensă a procesorului și IO, aceste servere trebuie să fie puternice și să fie susținute de stocarea SSD atașată. Vă recomandăm să rulați cel puțin 3 noduri Hot pentru o disponibilitate ridicată. În funcție de cantitatea de date recente pe care doriți să le colectați și să le întrebați, este posibil să fie necesar să creșteți acest număr pentru a vă atinge obiectivele de performanță.

Nodul cald este un tip de nod de date conceput pentru a gestiona o cantitate mare de indici de citire numai care nu sunt la fel de probabil să fie interogați frecvent. Deoarece acești indici sunt numai de citire, nodul cald tinde să utilizeze discuri mari atașate (de obicei discuri învârtite) în loc de SSD-uri. Ca și în cazul nodului fierbinte, vă recomandăm un minim de 3 noduri calde pentru disponibilitate ridicată. Și ca înainte, cu avizul, cantități mai mari de date pot necesita noduri suplimentare pentru a îndeplini cerințele de performanță. De asemenea, rețineți că configurațiile procesorului și ale memoriei vor trebui adesea să oglindească pe cele ale nodurilor dvs. fierbinți. Acest lucru poate fi determinat numai prin testarea cu întrebări similare cu ceea ce ați experimenta într-o situație de producție.

Pentru mai multe detalii despre nodul cald și cald, consultați aici.

O altă strategie pe care o puteți adapta este, arhivarea indicilor la s3 și restabilirea atunci când aveți nevoie de date din acei indici. Puteți citi mai multe despre asta de aici.

Topologia nodurilor:

Nodurile Elasticsearch pot fi împărțite în trei categorii nod principal, nod date, nod client.

  1. Nodul principal: Nodul principal poate fi mic dacă nu este un nod Data, deoarece nu stochează indici / cioburi. Responsabilitatea sa este stocarea stării detaliate a clusterului și a datelor de ajutor și a altor noduri în căutarea meta-date a indicilor / fragmentelor. Elasticsearch ar trebui să aibă mai multe noduri master pentru a evita problemele cerebrale împărțite.
  2. Nodul de date: Nodul de date este responsabil pentru stocarea / interogarea datelor index reale.
  3. Nod client: Nodul client este folosit ca proxy pentru indexare și căutare. Acest lucru este foarte recomandat dacă agregările sunt foarte utilizate. Acestea sunt noduri speciale ElasticSearch care nu sunt nici date, nici eligibile master. Nodurile clientului sunt conștiente de cluster și, prin urmare, pot acționa ca balanțe inteligente de încărcare. Puteți trimite întrebările către nodurile client, care pot prelua apoi sarcina scumpă de a colecta răspunsuri la rezultatele interogării de la fiecare nod.

adăugați aceste setări la fișierul elasticsearch.yml pentru nodurile respective.

Nodul principal: node.master: adevărat nod.data:false
Nod de date: node.master: false node.data:true
Nod client: node.master: false node.data:false

Sfaturi pentru soluționarea problemelor:

Performanța Elasticsearch depinde foarte mult de mașina pe care este instalat. CPU, memorie de utilizare și I / O de disc sunt valori de bază ale sistemului de operare pentru fiecare nod Elasticsearch. Se recomandă să analizați valorile Java Virtual Machine (JVM) atunci când utilizarea CPU crește. În exemplul următor, motivul vârfului a fost activitatea mai mare de colectare a gunoiului.

  1. Presiune de acumulare: presiunea ridicată a memoriei funcționează împotriva performanțelor clusterului în două moduri: Pe măsură ce presiunea în memorie crește până la 75% și mai mult, rămâne disponibilă mai puțină memorie, iar acum clusterul dvs. trebuie să cheltuiască unele resurse CPU pentru a recupera memoria prin colectarea gunoiului. Aceste cicluri ale procesorului nu sunt disponibile pentru gestionarea cererilor utilizatorului în timp ce colectarea gunoiului este activă. Drept urmare, timpii de răspuns pentru solicitările utilizatorului crește pe măsură ce sistemul devine din ce în ce mai restrâns la resurse. Dacă presiunea în memorie continuă să crească și să ajungă aproape de 100%, se folosește o formă mult mai agresivă de colectare a gunoiului, care la rândul său va afecta dramatic timpul de răspuns la cluster. Indicele Times Response Times indică faptul că presiunea ridicată a memoriei duce la un impact semnificativ asupra performanței.
  2. Creștere în memoria JVM non-heap, consumând memoria destinată cache-ului de pagină și, probabil, provocând recoltarea OOM la nivel de kernel.
  3. Evitati problema creierului divizat. Creierul divizat este un scenariu în care clusterul se desparte. De exemplu, aveți 6 cluster cu noduri. 2 noduri se deconectează de la cluster, dar totuși se pot vedea reciproc. Aceste 2 noduri creează apoi un alt cluster. Vor alege chiar un nou stăpân între ei. Avem acum două clustere cu același nume, unul cu 4 noduri și altul cu 2 noduri. Fiecare are și un nod principal. Aceasta este ceea ce se numește problemă cu creierul divizat cu clusterele ES. Pentru a evita acest lucru, setați parametrul ES Discover.zen.minimum_master_nodes la jumătate din numărul de noduri + 1.
  4. Întrucât Elasticsearch utilizează foarte mult dispozitivele de stocare, monitorizarea I / O a discului asigură îndeplinirea acestei nevoi de bază. Există multe motive pentru I / O de disc redus, considerată o metrică cheie pentru a prezice multe tipuri de probleme. Este o metrică bună pentru a verifica eficacitatea indexării și a performanței interogării. Analizarea operațiunilor de citire și scriere indică în mod direct ceea ce sistemul are nevoie cel mai mult în cazul specific de utilizare. Setările sistemului de operare pentru I / O de disc sunt o bază pentru toate celelalte optimizări, reglarea I / O a discului poate evita problemele potențiale. În cazul în care I / O pe disc nu este încă suficient, măsurile de optimizare, cum ar fi optimizarea numărului de cioburi și a mărimii acestora, îmbinare accelerată, înlocuirea discurilor lente, mutarea la SSD-uri sau adăugarea mai multor noduri ar trebui evaluate în funcție de circumstanțele care provoacă I ​​/ O. blocaje.
  5. Pentru aplicațiile care se bazează pe căutare, experiența utilizatorului este foarte corelată cu latența solicitărilor de căutare. Există multe lucruri care pot afecta performanța interogării, cum ar fi interogări construite, cluster Elasticsearch configurat în mod necorespunzător, memorie JVM și probleme de colectare a gunoiului, disc IO și așa mai departe. Latency query este metrica care afectează direct utilizatorii, așa că asigurați-vă că puneți unele alerte.
  6. Majoritatea filtrelor din Elasticsearch sunt memorate în cache în mod implicit. Asta înseamnă că în timpul primei execuții a unei interogări filtrate, Elasticsearch va găsi documente care se potrivesc filtrului și va construi o structură numită „bit” folosind informațiile respective. Datele stocate în bitet conțin un identificator de document și dacă un anumit document se potrivește cu filtrul. Execuțiile ulterioare ale interogărilor care au același filtru vor reutiliza informațiile stocate în bitet, făcând astfel executarea interogării mai rapidă prin salvarea operațiilor I / O și a ciclurilor CPU. Utilizarea filtrului în interogare este recomandată. Pentru mai multe detalii, consultați aici.
  7. Timpul de actualizare și timpul de îmbinare sunt strâns legate de performanța de indexare, plus că afectează performanța generală a clusterului. Timpul de actualizare crește odată cu numărul de operații de fișiere pentru indicele (fragmentul) Lucene.
  8. Activarea înregistrării lente a interogărilor va ajuta la identificarea interogărilor care sunt lente și ce se poate face pentru îmbunătățirea acestora, utilă în special pentru interogări cu wildcard.
  9. Măriți dimensiunea ulimit pentru a permite fișierele max.
  10. Performanța ElasticSearch poate suferi atunci când sistemul de operare decide să schimbe memoria de aplicație neutilizată. Dezactivați schimbarea prin setarea nivelului sistemului de operare sau setați următoarele în configurația ElasticSearch bootstrap.mlockall: true
  11. Dezactivați ștergerea tuturor indicilor prin interogarea wildcard. Pentru a vă asigura că cineva nu emite o operație DELETE pe toți indexurile (* sau _all), setați action.destructive_requires_name la true.

Înainte de a termina, iată lista de URL-uri utile pentru urmărirea valorilor.

  • / _cluster / health? drăguț: Pentru indicatorul de sănătate al clusterului.
  • / _status? drăguț: Pentru toate informațiile despre toți indicii.
  • / _nodes? drăguț: Pentru toate informațiile despre noduri.
  • / _cat / master? drăguț: Pentru nodul principal.
  • / _stats? drăguț: pentru alocarea fragmentelor, statistici cu indicii.
  • / _nodes / stats? drăguț: Pentru statisticile individuale ale nodurilor, acestea includ, jvm, http, io statistici pentru nod.

Agregarea metrică a Elasticsearch este acceptată de majoritatea instrumentelor de monitorizare a sistemelor precum Datadog, TICK. Utilizarea unor astfel de instrumente este recomandată și crearea unei pâlnii este foarte recomandată pentru monitorizarea continuă a Elasticsearch.

Concluzie:

Elasticsearch este un motor de căutare și analiză de text complet distribuit, care permite mai multor locatari să caute în întregul set de date, indiferent de dimensiune, la viteze fără precedent. Pe lângă capacitățile sale de căutare cu text complet, ElasticSearch se dublează ca un sistem de analiză și o bază de date distribuită. ElasticSearch are setări prestabilite minunate pentru a începe. Dar, odată trecută faza de experimentare inițială, trebuie să petreci ceva timp pentru a regla setările pentru nevoile tale. Este recomandat să revizuiți configurația mai târziu, împreună cu documentația oficială, pentru a vă asigura că clusterul este configurat pentru a răspunde nevoilor dvs.