Cluster Elasticsearch 200 TB+

Cluster Elasticsearch 200 TB+

Mulți oameni se luptă cu Elasticsearch. Dar ce se întâmplă când vrei să-l folosești pentru a stoca jurnale „într-un volum deosebit de mare”? Și este, de asemenea, nedureros să experimentezi eșecul unuia dintre mai multe centre de date? Ce fel de arhitectură ar trebui să faci și în ce capcane te vei împiedica?

Noi, cei de la Odnoklassniki, am decis să folosim elasticsearch pentru a rezolva problema gestionării jurnalelor, iar acum împărtășim experiența noastră cu Habr: atât despre arhitectură, cât și despre capcane.

Sunt Pyotr Zaitsev, lucrez ca administrator de sistem la Odnoklassniki. Înainte de asta, am fost și administrator, am lucrat cu Manticore Search, Sphinx search, Elasticsearch. Poate că, dacă apare o altă căutare..., probabil că voi lucra și eu cu ea. De asemenea, particip la o serie de proiecte open source pe bază de voluntariat.

Când am venit la Odnoklassniki, am spus nesăbuit la interviu că aș putea lucra cu Elasticsearch. După ce m-am înțeles și am finalizat câteva sarcini simple, mi s-a dat marea sarcină de a reforma sistemul de gestionare a jurnalelor care exista la acea vreme.

Cerințe

Cerințele de sistem au fost formulate după cum urmează:

  • Graylog urma să fie folosit ca interfață. Deoarece compania avea deja experiență în utilizarea acestui produs, programatorii și testerii îl cunoșteau, le era familiar și convenabil.
  • Volumul de date: în medie 50-80 de mii de mesaje pe secundă, dar dacă ceva se rupe, atunci traficul nu este limitat de nimic, poate fi de 2-3 milioane de linii pe secundă
  • După ce am discutat cu clienții cerințele pentru viteza de procesare a interogărilor de căutare, ne-am dat seama că tiparul tipic de utilizare a unui astfel de sistem este acesta: oamenii caută jurnalele aplicației lor în ultimele două zile și nu doresc să aștepte mai mult de un al doilea pentru rezultatul unei interogări formulate.
  • Administratorii au insistat ca sistemul să fie ușor de scalat dacă este necesar, fără a le solicita să aprofundeze cum funcționează.
  • Astfel încât singura sarcină de întreținere pe care aceste sisteme o necesită periodic este schimbarea unor componente hardware.
  • În plus, Odnoklassniki are o tradiție tehnică excelentă: orice serviciu pe care îl lansăm trebuie să supraviețuiască unei eșecuri a centrului de date (bruscă, neplanificată și absolut în orice moment).

Cel mai mult ne-a costat ultima cerință în implementarea acestui proiect, despre care voi vorbi mai detaliat.

Miercuri

Lucrăm în patru centre de date, în timp ce nodurile de date Elasticsearch pot fi localizate doar în trei (din mai multe motive non-tehnice).

Aceste patru centre de date conțin aproximativ 18 mii de surse de jurnal diferite - hardware, containere, mașini virtuale.

Caracteristică importantă: clusterul începe în containere Podman nu pe mașini fizice, ci pe propriul produs cloud one-cloud. Containerelor li se garantează 2 nuclee, similar cu 2.0Ghz v4, cu posibilitatea de a recicla nucleele rămase dacă sunt inactiv.

Cu alte cuvinte:

Cluster Elasticsearch 200 TB+

Topologie

Am văzut inițial forma generală a soluției după cum urmează:

  • 3-4 VIP-uri se află în spatele înregistrării A a domeniului Graylog, aceasta este adresa la care sunt trimise jurnalele.
  • fiecare VIP este un echilibrator LVS.
  • După el, jurnalele merg la bateria Graylog, unele dintre date sunt în format GELF, altele în format syslog.
  • Apoi toate acestea sunt scrise în loturi mari unei baterii de coordonatori Elasticsearch.
  • Și ei, la rândul lor, trimit solicitări de scriere și citire către nodurile de date relevante.

Cluster Elasticsearch 200 TB+

terminologie

Poate că nu toată lumea înțelege terminologia în detaliu, așa că aș dori să mă opresc puțin asupra ei.

Elasticsearch are mai multe tipuri de noduri - master, coordonator, data node. Există alte două tipuri pentru transformări diferite de jurnal și comunicare între diferite clustere, dar le-am folosit doar pe cele enumerate.

Maestru
Face ping la toate nodurile prezente în cluster, menține o hartă actualizată a clusterului și o distribuie între noduri, procesează logica evenimentelor și efectuează diverse tipuri de întreținere la nivel de cluster.

Coordonator
Îndeplinește o singură sarcină: acceptă cereri de citire sau scriere de la clienți și direcționează acest trafic. În cazul în care există o cerere de scriere, cel mai probabil, acesta îl va întreba pe master în ce fragment din indexul relevant ar trebui să îl introducă și va redirecționa cererea în continuare.

Nod de date
Stochează date, efectuează interogări de căutare care sosesc din exterior și efectuează operațiuni asupra fragmentelor aflate pe el.

greylog
Aceasta este ceva ca o fuziune a Kibana cu Logstash într-o stivă ELK. Graylog combină atât o interfață de utilizare, cât și o conductă de procesare a jurnalelor. Sub capotă, Graylog rulează Kafka și Zookeeper, care oferă conectivitate la Graylog ca un cluster. Graylog poate stoca în cache jurnalele (Kafka) în cazul în care Elasticsearch este indisponibil și repetă solicitările de citire și scriere nereușite, grupează și marca jurnalele conform regulilor specificate. La fel ca Logstash, Graylog are funcționalitate pentru a modifica rândurile înainte de a le scrie în Elasticsearch.

În plus, Graylog are un serviciu de descoperire încorporat care permite, pe baza unui nod Elasticsearch disponibil, să obțină întreaga hartă a clusterului și să o filtreze după o etichetă specifică, ceea ce face posibilă direcționarea cererilor către anumite containere.

Vizual arată cam așa:

Cluster Elasticsearch 200 TB+

Aceasta este o captură de ecran dintr-o anumită instanță. Aici construim o histogramă bazată pe interogarea de căutare și afișăm rânduri relevante.

Indici

Revenind la arhitectura sistemului, aș dori să mă opresc mai detaliat asupra modului în care am construit modelul de index, astfel încât totul să funcționeze corect.

În diagrama de mai sus, acesta este cel mai jos nivel: noduri de date Elasticsearch.

Un index este o entitate virtuală mare alcătuită din fragmente Elasticsearch. În sine, fiecare dintre cioburi nu este altceva decât un indice Lucene. Și fiecare indice Lucene, la rândul său, este format din unul sau mai multe segmente.

Cluster Elasticsearch 200 TB+

La proiectare, ne-am gândit că, pentru a îndeplini cerințele privind viteza de citire pe o cantitate mare de date, trebuie să „împrăștiem” aceste date în mod uniform între nodurile de date.

Acest lucru a dus la faptul că numărul de fragmente pe index (cu replici) ar trebui să fie strict egal cu numărul de noduri de date. În primul rând, pentru a asigura un factor de replicare egal cu doi (adică putem pierde jumătate din cluster). Și, în al doilea rând, pentru a procesa cereri de citire și scriere pe cel puțin jumătate din cluster.

Am stabilit mai întâi timpul de depozitare ca fiind de 30 de zile.

Distribuția fragmentelor poate fi reprezentată grafic după cum urmează:

Cluster Elasticsearch 200 TB+

Întregul dreptunghi gri închis este un index. Pătratul roșu din stânga din el este ciobul primar, primul din index. Și pătratul albastru este o replică. Acestea sunt situate în diferite centre de date.

Când adăugăm un alt fragment, acesta merge la al treilea centru de date. Și, în cele din urmă, obținem această structură, care face posibilă pierderea DC fără a pierde consistența datelor:

Cluster Elasticsearch 200 TB+

Rotația indicilor, de ex. creând un nou index și ștergându-l pe cel mai vechi, l-am făcut egal cu 48 de ore (după tiparul de utilizare a indexului: ultimele 48 de ore sunt căutate cel mai des).

Acest interval de rotație a indicelui se datorează următoarelor motive:

Când o solicitare de căutare ajunge la un anumit nod de date, atunci, din punct de vedere al performanței, este mai profitabilă atunci când este interogat un fragment, dacă dimensiunea sa este comparabilă cu dimensiunea șoldului nodului. Acest lucru vă permite să păstrați partea „fierbintă” a indexului într-o grămadă și să o accesați rapid. Când există o mulțime de „părți fierbinți”, viteza de căutare a indexului se degradează.

Când un nod începe să execute o interogare de căutare pe un fragment, acesta alocă un număr de fire egal cu numărul de nuclee de hyperthreading ale mașinii fizice. Dacă o interogare de căutare afectează un număr mare de fragmente, atunci numărul de fire crește proporțional. Acest lucru are un impact negativ asupra vitezei de căutare și afectează negativ indexarea datelor noi.

Pentru a oferi latența necesară de căutare, am decis să folosim un SSD. Pentru a procesa rapid cererile, mașinile care găzduiau aceste containere trebuiau să aibă cel puțin 56 de nuclee. Cifra de 56 a fost aleasă ca valoare suficientă condiționat care determină numărul de fire pe care Elasticsearch le va genera în timpul funcționării. În Elasitcsearch, mulți parametri de pool de fire depind direct de numărul de nuclee disponibile, care, la rândul său, afectează în mod direct numărul necesar de noduri din cluster, conform principiului „mai puține nuclee - mai multe noduri”.

Drept urmare, am constatat că, în medie, un shard cântărește aproximativ 20 de gigaocteți și există 1 de cioburi pe index. În consecință, dacă le rotim o dată la 360 de ore, atunci avem 48 dintre ele. Fiecare index conține date pentru 15 zile.

Circuite de scriere și citire a datelor

Să ne dăm seama cum sunt înregistrate datele în acest sistem.

Să presupunem că vine o solicitare de la Graylog către coordonator. De exemplu, vrem să indexăm 2-3 mii de rânduri.

Coordonatorul, după ce a primit o solicitare de la Graylog, îl întreabă pe maestru: „În cererea de indexare, am specificat în mod specific un index, dar în ce fragment să scriem nu a fost specificat”.

Maestrul răspunde: „Scrieți această informație în fragmentul numărul 71”, după care sunt trimise direct la nodul de date relevant, unde se află numărul de fragment primar 71.

După care jurnalul de tranzacții este replicat într-un fragment de replică, care se află într-un alt centru de date.

Cluster Elasticsearch 200 TB+

O solicitare de căutare ajunge de la Graylog coordonatorului. Coordonatorul îl redirecționează în funcție de index, în timp ce Elasticsearch distribuie cererile între primary-shard și replica-shard folosind principiul round-robin.

Cluster Elasticsearch 200 TB+

Cele 180 de noduri răspund inegal și, în timp ce răspund, coordonatorul acumulează informații care au fost deja „scuipate” de nodurile de date mai rapide. După aceasta, când fie au ajuns toate informațiile, fie solicitarea a ajuns la un timeout, dă totul direct clientului.

Întregul sistem procesează, în medie, interogările de căutare din ultimele 48 de ore în 300-400 ms, excluzând acele interogări cu un metacaracter principal.

Flori cu Elasticsearch: configurare Java

Cluster Elasticsearch 200 TB+

Pentru ca totul să funcționeze așa cum ne-am dorit inițial, am petrecut foarte mult timp depanând o mare varietate de lucruri din cluster.

Prima parte a problemelor descoperite a fost legată de modul în care Java este preconfigurat implicit în Elasticsearch.

Problema unu
Am văzut un număr foarte mare de rapoarte conform cărora la nivelul Lucene, atunci când se execută joburi în fundal, îmbinările segmentului Lucene eșuează cu o eroare. În același timp, era clar în jurnalele că aceasta a fost o eroare OutOfMemoryError. Am văzut din telemetrie că șoldul era liber și nu era clar de ce eșuează această operație.

S-a dovedit că îmbinările indicelui Lucene apar în afara șoldului. Iar containerele sunt destul de strict limitate din punct de vedere al resurselor consumate. Numai heap-ul s-ar putea încadra în aceste resurse (valoarea heap.size era aproximativ egală cu RAM), iar unele operațiuni off-heap s-au prăbușit cu o eroare de alocare a memoriei dacă, dintr-un motiv oarecare, nu s-au încadrat în ~500MB care au rămas înainte de limită.

Remedierea a fost destul de banală: cantitatea de RAM disponibilă pentru container a fost mărită, după care am uitat că chiar am avut astfel de probleme.

Problema doi
La 4-5 zile de la lansarea clusterului, am observat că nodurile de date au început să cadă periodic din cluster și să intre în el după 10-20 de secunde.

Când am început să ne dăm seama, s-a dovedit că această memorie off-heap din Elasticsearch nu este controlată în niciun fel. Când am oferit mai multă memorie containerului, am reușit să umplem pool-urile directe de buffer-uri cu diverse informații și a fost șters doar după ce GC-ul explicit a fost lansat de la Elasticsearch.

În unele cazuri, această operațiune a durat destul de mult și în acest timp clusterul a reușit să marcheze acest nod ca fiind deja ieșit. Această problemă este bine descrisă aici.

Soluția a fost următoarea: am limitat capacitatea Java de a utiliza cea mai mare parte a memoriei în afara heap-ului pentru aceste operațiuni. L-am limitat la 16 gigaocteți (-XX:MaxDirectMemorySize=16g), asigurându-ne că GC explicit a fost apelat mult mai des și procesat mult mai rapid, astfel încât să nu mai destabilizeze clusterul.

Problema trei
Dacă credeți că problemele cu „nodurile care părăsesc clusterul în cel mai neașteptat moment” s-au terminat, vă înșelați.

Când am configurat lucrul cu indecși, am ales mmapfs reduce timpul de căutare pe cioburi proaspete cu mare segmentare. Aceasta a fost destul de o gafă, deoarece atunci când folosiți mmapfs fișierul este mapat în RAM și apoi lucrăm cu fișierul mapat. Din această cauză, se dovedește că atunci când GC încearcă să oprească firele din aplicație, mergem la punctul de siguranță pentru o perioadă foarte lungă de timp, iar pe drumul către acesta, aplicația nu mai răspunde la solicitările masterului despre dacă este în viață . În consecință, master crede că nodul nu mai este prezent în cluster. După aceasta, după 5-10 secunde, colectorul de gunoi funcționează, nodul prinde viață, intră din nou în cluster și începe să inițializeze cioburi. Totul semăna foarte mult cu „producția pe care o meritam” și nu era potrivit pentru nimic serios.

Pentru a scăpa de acest comportament, am trecut mai întâi la niof-uri standard, iar apoi, când am migrat de la a cincea versiune de Elastic la a șasea, am încercat hibridf-uri, unde această problemă nu a fost reprodusă. Puteți citi mai multe despre tipurile de stocare aici.

Problema patru
Apoi a mai fost o problemă foarte interesantă pe care am tratat-o ​​timp record. L-am prins 2-3 luni pentru că tiparul lui era absolut de neînțeles.

Uneori, coordonatorii noștri mergeau la Full GC, de obicei cândva după prânz, și nu s-au întors niciodată de acolo. În același timp, la înregistrarea întârzierii GC, arăta așa: totul merge bine, bine, bine, și apoi dintr-o dată totul merge foarte prost.

La început am crezut că avem un utilizator rău care lansa un fel de cerere care l-a scos pe coordonator din modul de lucru. Am înregistrat solicitări foarte mult timp, încercând să ne dăm seama ce se întâmplă.

Drept urmare, s-a dovedit că în momentul în care un utilizator lansează o solicitare uriașă și ajunge la un anumit coordonator Elasticsearch, unele noduri răspund mai mult decât altele.

Și în timp ce coordonatorul așteaptă un răspuns de la toate nodurile, el acumulează rezultatele trimise de la nodurile care au răspuns deja. Pentru GC, aceasta înseamnă că modelele noastre de utilizare a heapului se schimbă foarte repede. Și GC pe care l-am folosit nu a putut face față acestei sarcini.

Singura remediere pe care am găsit-o pentru a schimba comportamentul cluster-ului în această situație este migrarea la JDK13 și utilizarea colectorului de gunoi Shenandoah. Așa a rezolvat problema, coordonatorii noștri au încetat să cadă.

Aici s-au încheiat problemele cu Java și au început problemele cu lățimea de bandă.

„Bace” cu Elasticsearch: debit

Cluster Elasticsearch 200 TB+

Problemele legate de debit înseamnă că clusterul nostru funcționează stabil, dar la vârfuri ale numărului de documente indexate și în timpul manevrelor, performanța este insuficientă.

Primul simptom întâlnit: în timpul unor „explozii” în producție, când se generează brusc un număr foarte mare de loguri, eroarea de indexare es_rejected_execution începe să clipească frecvent în Graylog.

Acest lucru s-a datorat faptului că thread_pool.write.queue pe un nod de date, până în momentul în care Elasticsearch este capabil să proceseze cererea de indexare și să încarce informațiile pe shard-ul de pe disc, este capabil să memoreze în cache doar 200 de solicitări în mod implicit. Si in Documentația Elasticsearch Se vorbește foarte puțin despre acest parametru. Sunt indicate doar numărul maxim de fire și dimensiunea implicită.

Desigur, am mers să răsucim această valoare și am aflat următoarele: în mod specific, în configurația noastră, până la 300 de solicitări sunt stocate în cache destul de bine, iar o valoare mai mare este plină de faptul că zburăm din nou în Full GC.

În plus, deoarece acestea sunt loturi de mesaje care ajung într-o singură solicitare, a fost necesar să se modifice Graylog, astfel încât să scrie nu des și în loturi mici, ci în loturi uriașe sau o dată la 3 secunde dacă lotul încă nu este complet. În acest caz, se dovedește că informațiile pe care le scriem în Elasticsearch devin disponibile nu în două secunde, ci în cinci (ceea ce ni se potrivește destul de bine), ci numărul de retrayuri care trebuie făcute pentru a împinge un mare teancul de informații este redus.

Acest lucru este deosebit de important în acele momente în care ceva s-a prăbușit undeva și raportează cu furie despre asta, pentru a nu obține un Elastic complet spam, iar după ceva timp - noduri Graylog care sunt inoperabile din cauza bufferelor înfundate.

În plus, când am avut aceleași explozii în producție, am primit plângeri de la programatori și testeri: în momentul în care aveau cu adevărat nevoie de aceste jurnale, li s-au dat foarte încet.

Au început să-și dea seama. Pe de o parte, era clar că atât interogările de căutare, cât și interogările de indexare erau procesate, în esență, pe aceleași mașini fizice și, într-un fel sau altul, ar exista anumite reduceri.

Dar acest lucru ar putea fi ocolit parțial datorită faptului că în cea de-a șasea versiune a Elasticsearch a apărut un algoritm care vă permite să distribuiți interogări între nodurile de date relevante, nu conform principiului aleatoriu round-robin (containerul care face indexarea și deține -shard poate fi foarte ocupat, nu va exista nicio modalitate de a răspunde rapid), ci să redirecționați această solicitare către un container mai puțin încărcat cu o replica-shard, care va răspunde mult mai rapid. Cu alte cuvinte, am ajuns la use_adaptive_replica_selection: true.

Imaginea de lectură începe să arate astfel:

Cluster Elasticsearch 200 TB+

Tranziția la acest algoritm a făcut posibilă îmbunătățirea semnificativă a timpului de interogare în acele momente în care aveam de scris un flux mare de jurnale.

În cele din urmă, principala problemă a fost îndepărtarea nedureroasă a centrului de date.

Ce ne-am dorit de la cluster imediat după ce ne-am pierdut conexiunea cu un DC:

  • Dacă avem un master curent în centrul de date eșuat, atunci acesta va fi re-selectat și mutat ca rol într-un alt nod dintr-un alt DC.
  • Maestrul va elimina rapid toate nodurile inaccesibile din cluster.
  • Pe baza celor rămase, va înțelege: în centrul de date pierdut am avut așa și așa shard-uri primare, va promova rapid replica-shard-uri complementare în centrele de date rămase, iar noi vom continua indexarea datelor.
  • Ca urmare, viteza de scriere și citire a clusterului se va degrada treptat, dar, în general, totul va funcționa, deși lent, dar stabil.

După cum sa dovedit, ne-am dorit ceva de genul acesta:

Cluster Elasticsearch 200 TB+

Și am primit următoarele:

Cluster Elasticsearch 200 TB+

Cum s-a întâmplat?

Când centrul de date a căzut, stăpânul nostru a devenit blocajul.

De ce?

Faptul este că masterul are un TaskBatcher, care este responsabil pentru distribuirea anumitor sarcini și evenimente în cluster. Orice ieșire de nod, orice promovare a unui shard de la replică la primar, orice sarcină pentru a crea un shard undeva - toate acestea merg mai întâi la TaskBatcher, unde este procesat secvenţial și într-un singur fir.

La momentul retragerii unui centru de date, s-a dovedit că toate nodurile de date din centrele de date supraviețuitoare considerau că este de datoria lor să-l informeze pe maestru „am pierdut așa și așa cioburi și așa și astfel de noduri de date”.

În același timp, nodurile de date supraviețuitoare au trimis toate aceste informații maestrului actual și au încercat să aștepte confirmarea că el a acceptat-o. Nu au așteptat acest lucru, deoarece maestrul primea sarcini mai repede decât putea răspunde. Nodurile au expirat cererile repetate, iar comandantul în acest moment nici măcar nu a încercat să le răspundă, ci a fost complet absorbit de sarcina de a sorta cererile în funcție de prioritate.

În formă de terminal, s-a dovedit că nodurile de date au trimis spam masterul până la punctul în care acesta a intrat în GC complet. După aceea, rolul nostru de maestru s-a mutat la un nod următor, i s-a întâmplat absolut același lucru și, ca urmare, clusterul s-a prăbușit complet.

Am făcut măsurători și, înainte de versiunea 6.4.0, în care acest lucru a fost remediat, a fost suficient să scoatem simultan doar 10 noduri de date din 360 pentru a închide complet clusterul.

Arăta cam așa:

Cluster Elasticsearch 200 TB+

După versiunea 6.4.0, unde a fost remediat acest bug teribil, nodurile de date au încetat să-l omoare pe maestru. Dar asta nu l-a făcut „mai inteligent”. Și anume: când scoatem 2, 3 sau 10 (orice număr, altul decât unul) noduri de date, comandantul primește un prim mesaj care spune că nodul A a plecat și încearcă să-i spună nodului B, nodului C despre acest lucru, nodului D.

Și în acest moment, acest lucru poate fi rezolvat doar prin stabilirea unui timeout pentru încercările de a spune cuiva despre ceva, egal cu aproximativ 20-30 de secunde, și astfel controlând viteza centrului de date care iese din cluster.

În principiu, acest lucru se încadrează în cerințele care au fost prezentate inițial produsului final ca parte a proiectului, dar din punctul de vedere al „științei pure” aceasta este o eroare. Care, apropo, a fost remediat cu succes de dezvoltatori în versiunea 7.2.

Mai mult, atunci când un anumit nod de date s-a oprit, s-a dovedit că diseminarea informațiilor despre ieșirea lui era mai importantă decât a spune întregului cluster că există astfel de fragmente primare pe el (pentru a promova o replica-shard în alte date). centru în primar, iar în informații ar putea fi scrise pe ele).

Prin urmare, atunci când totul s-a stins deja, nodurile de date eliberate nu sunt imediat marcate ca învechite. În consecință, suntem forțați să așteptăm până când toate ping-urile au expirat pentru nodurile de date lansate și numai după aceea clusterul nostru începe să ne spună că acolo, acolo și acolo trebuie să continuăm înregistrarea informațiilor. Puteți citi mai multe despre asta aici.

Drept urmare, operațiunea de retragere a unui centru de date astăzi ne ia aproximativ 5 minute în timpul orelor de vârf. Pentru un colos atât de mare și stângaci, acesta este un rezultat destul de bun.

Ca urmare, am ajuns la următoarea decizie:

  • Avem 360 de noduri de date cu discuri de 700 de gigaocteți.
  • 60 de coordonatori pentru rutarea traficului prin aceleași noduri de date.
  • 40 de maeștri pe care i-am lăsat ca un fel de moștenire încă de la versiunile anterioare 6.4.0 - pentru a supraviețui retragerii centrului de date, eram pregătiți mental să pierdem mai multe mașini pentru a fi garantat să avem cvorum de master chiar și în cel mai rău caz
  • Orice încercare de a combina roluri pe un container a fost întâlnită cu faptul că, mai devreme sau mai târziu, nodul s-ar rupe sub sarcină.
  • Întregul cluster folosește un heap.size de 31 de gigaocteți: toate încercările de a reduce dimensiunea au dus fie la uciderea unor noduri la interogări de căutare grele cu caracterul joker principal, fie la obținerea întreruptorului în Elasticsearch însuși.
  • În plus, pentru a asigura performanța de căutare, am încercat să menținem cât mai mic numărul de obiecte din cluster, pentru a procesa cât mai puține evenimente în blocajul pe care l-am primit în master.

În sfârșit, despre monitorizare

Pentru a ne asigura că toate acestea funcționează conform intenției, monitorizăm următoarele:

  • Fiecare nod de date raportează cloud-ului nostru că există și există astfel de fragmente pe el. Când stingem ceva undeva, clusterul raportează după 2-3 secunde că în centrul A am stins nodurile 2, 3 și 4 - asta înseamnă că în alte centre de date nu putem stinge sub nicio formă acele noduri pe care există doar un ciob. stânga.
  • Cunoscând natura comportamentului maestrului, ne uităm foarte atent la numărul de sarcini în așteptare. Pentru că chiar și o sarcină blocată, dacă nu expiră la timp, teoretic într-o situație de urgență poate deveni motivul pentru care, de exemplu, promovarea unui fragment de replica în primar nu funcționează, motiv pentru care indexarea nu va mai funcționa.
  • De asemenea, ne uităm foarte atent la întârzierile colectoarelor de gunoi, deoarece am avut deja mari dificultăți cu acest lucru în timpul optimizării.
  • Respinge prin fir pentru a înțelege în prealabil unde este blocajul.
  • Ei bine, metrici standard, cum ar fi heap, RAM și I/O.

La monitorizarea construcției, trebuie să țineți cont de caracteristicile Thread Pool din Elasticsearch. Documentația Elasticsearch descrie opțiunile de configurare și valorile implicite pentru căutare și indexare, dar este complet tăcut despre thread_pool.management. Aceste fire procesează, în special, interogări precum _cat/shards și altele similare, care sunt convenabile de utilizat la scrierea monitorizării. Cu cât clusterul este mai mare, cu atât se execută mai multe astfel de solicitări pe unitatea de timp, iar thread_pool.management menționat mai sus nu numai că nu este prezentat în documentația oficială, dar este și limitat implicit la 5 fire de execuție, de care se elimină foarte repede, după care monitorizare nu mai funcționează corect.

Ce vreau să spun în concluzie: am reușit! Am putut oferi programatorilor și dezvoltatorilor noștri un instrument care, în aproape orice situație, poate oferi rapid și fiabil informații despre ceea ce se întâmplă în producție.

Da, s-a dovedit a fi destul de complicat, dar, cu toate acestea, am reușit să ne potrivim dorințele în produsele existente, pe care nu a trebuit să le corectăm și să le rescriem singuri.

Cluster Elasticsearch 200 TB+

Sursa: www.habr.com

Adauga un comentariu