Cluster Elasticsearch da 200 TB+

Cluster Elasticsearch da 200 TB+

Molte persone hanno problemi con Elasticsearch. Ma cosa succede quando si desidera utilizzarlo per archiviare i log “in un volume particolarmente grande”? Ed è anche indolore sperimentare il guasto di uno qualsiasi dei numerosi data center? Che tipo di architettura dovresti realizzare e in quali insidie ​​ti imbatterai?

Noi di Odnoklassniki abbiamo deciso di utilizzare elasticsearch per risolvere il problema della gestione dei log e ora condividiamo la nostra esperienza con Habr: sia sull'architettura che sulle insidie.

Sono Pyotr Zaitsev, lavoro come amministratore di sistema presso Odnoklassniki. Prima di allora, ero anche un amministratore, lavoravo con Manticore Search, Sphinx search, Elasticsearch. Forse, se appare un'altra ricerca, probabilmente lavorerò anch'io con quella. Partecipo anche a numerosi progetti open source su base volontaria.

Quando sono arrivato a Odnoklassniki, durante il colloquio ho detto incautamente che avrei potuto lavorare con Elasticsearch. Dopo aver capito come funziona e aver completato alcune semplici attività, mi è stato affidato il grande compito di riformare il sistema di gestione dei log esistente a quel tempo.

Requisiti

I requisiti di sistema sono stati formulati come segue:

  • Graylog doveva essere utilizzato come frontend. Poiché l'azienda aveva già esperienza nell'uso di questo prodotto, programmatori e tester lo sapevano, era familiare e conveniente per loro.
  • Volume di dati: in media 50-80mila messaggi al secondo, ma se qualcosa si rompe, il traffico non è limitato da nulla, possono essere 2-3 milioni di linee al secondo
  • Dopo aver discusso con i clienti i requisiti per la velocità di elaborazione delle query di ricerca, ci siamo resi conto che lo schema tipico di utilizzo di un sistema del genere è questo: le persone cercano i log della loro applicazione negli ultimi due giorni e non vogliono aspettare più di un secondo per il risultato di una query formulata.
  • Gli amministratori hanno insistito affinché il sistema fosse facilmente scalabile se necessario, senza richiedere loro di approfondire il suo funzionamento.
  • Pertanto l'unica attività di manutenzione che questi sistemi richiedono periodicamente è la modifica di parte dell'hardware.
  • Inoltre, Odnoklassniki ha un'eccellente tradizione tecnica: qualsiasi servizio che lanciamo deve sopravvivere a un guasto del data center (improvviso, non pianificato e assolutamente in qualsiasi momento).

L'ultimo requisito nell'attuazione di questo progetto ci è costato di più, di cui parlerò più in dettaglio.

mercoledì

Lavoriamo in quattro data center, mentre i nodi dati Elasticsearch possono essere localizzati solo in tre (per una serie di ragioni non tecniche).

Questi quattro data center contengono circa 18mila diverse fonti di log: hardware, contenitori, macchine virtuali.

Caratteristica importante: il cluster inizia in contenitori Podman non su macchine fisiche, ma su proprio prodotto cloud one-cloud. Ai container sono garantiti 2 core, simili a 2.0Ghz v4, con possibilità di riciclare i core rimanenti se inattivi.

In altre parole:

Cluster Elasticsearch da 200 TB+

Topologia

Inizialmente ho visto la forma generale della soluzione come segue:

  • 3-4 VIP si trovano dietro l'A-record del dominio Graylog, questo è l'indirizzo a cui vengono inviati i log.
  • ogni VIP è un bilanciatore LVS.
  • Successivamente, i registri vanno alla batteria Graylog, alcuni dati sono in formato GELF, altri in formato syslog.
  • Quindi tutto questo viene scritto in grandi lotti da una batteria di coordinatori di Elasticsearch.
  • E questi, a loro volta, inviano richieste di scrittura e lettura ai nodi dati rilevanti.

Cluster Elasticsearch da 200 TB+

terminologia

Forse non tutti comprendono nel dettaglio la terminologia, quindi vorrei soffermarmi un po' su di essa.

Elasticsearch ha diversi tipi di nodi: master, coordinatore, nodo dati. Esistono altri due tipi per diverse trasformazioni di log e comunicazioni tra diversi cluster, ma abbiamo utilizzato solo quelli elencati.

Maestro
Esegue il ping di tutti i nodi presenti nel cluster, mantiene una mappa del cluster aggiornata e la distribuisce tra i nodi, elabora la logica degli eventi ed esegue vari tipi di pulizia dell'intero cluster.

dell'esame
Esegue un'unica attività: accetta richieste di lettura o scrittura dai client e instrada questo traffico. Nel caso in cui ci sia una richiesta di scrittura, molto probabilmente, chiederà al master in quale frammento dell'indice pertinente inserirla e reindirizzerà ulteriormente la richiesta.

Nodo dati
Memorizza dati, esegue query di ricerca provenienti dall'esterno ed esegue operazioni sugli shard che si trovano su di esso.

graylog
Questo è qualcosa come una fusione di Kibana con Logstash in uno stack ELK. Graylog combina sia un'interfaccia utente che una pipeline di elaborazione dei log. Dietro le quinte, Graylog esegue Kafka e Zookeeper, che forniscono connettività a Graylog come cluster. Graylog può memorizzare nella cache i log (Kafka) nel caso in cui Elasticsearch non sia disponibile e ripetere richieste di lettura e scrittura non riuscite, raggruppare e contrassegnare i log in base alle regole specificate. Come Logstash, Graylog ha funzionalità per modificare le righe prima di scriverle su Elasticsearch.

Inoltre, Graylog dispone di un servizio di rilevamento integrato che consente, sulla base di un nodo Elasticsearch disponibile, di ottenere l'intera mappa del cluster e filtrarla tramite un tag specifico, che rende possibile indirizzare le richieste a contenitori specifici.

Visivamente assomiglia a questo:

Cluster Elasticsearch da 200 TB+

Questo è uno screenshot di un'istanza specifica. Qui creiamo un istogramma basato sulla query di ricerca e visualizziamo le righe pertinenti.

Indici

Tornando all'architettura del sistema, vorrei soffermarmi più in dettaglio su come abbiamo costruito il modello di indice in modo che tutto funzionasse correttamente.

Nel diagramma sopra, questo è il livello più basso: nodi dati Elasticsearch.

Un indice è una grande entità virtuale composta da frammenti Elasticsearch. Di per sé, ciascuno dei frammenti non è altro che un indice Lucene. E ogni indice Lucene, a sua volta, è composto da uno o più segmenti.

Cluster Elasticsearch da 200 TB+

Durante la progettazione, abbiamo pensato che per soddisfare i requisiti di velocità di lettura su una grande quantità di dati, dovevamo "diffondere" questi dati in modo uniforme tra i nodi di dati.

Ciò ha portato al fatto che il numero di frammenti per indice (con repliche) dovrebbe essere rigorosamente uguale al numero di nodi dati. Innanzitutto per garantire un fattore di replica pari a due (ovvero possiamo perdere metà del cluster). E, in secondo luogo, per elaborare le richieste di lettura e scrittura su almeno la metà del cluster.

Innanzitutto abbiamo determinato il tempo di conservazione in 30 giorni.

La distribuzione dei frammenti può essere rappresentata graficamente come segue:

Cluster Elasticsearch da 200 TB+

L'intero rettangolo grigio scuro è un indice. Il quadrato rosso a sinistra è il frammento primario, il primo nell'indice. E il quadrato blu è un frammento di replica. Si trovano in diversi data center.

Quando aggiungiamo un altro frammento, questo va al terzo data center. E, alla fine, otteniamo questa struttura, che rende possibile perdere DC senza perdere la coerenza dei dati:

Cluster Elasticsearch da 200 TB+

Rotazione degli indici, ad es. creando un nuovo indice ed eliminando quello più vecchio, lo abbiamo reso pari a 48 ore (secondo lo schema di utilizzo dell'indice: le ultime 48 ore vengono cercate più spesso).

Questo intervallo di rotazione dell'indice è dovuto ai seguenti motivi:

Quando una richiesta di ricerca arriva a uno specifico nodo di dati, dal punto di vista delle prestazioni è più vantaggioso interrogare un frammento se la sua dimensione è paragonabile alla dimensione dell’anca del nodo. Ciò consente di mantenere la parte "attiva" dell'indice in un heap e di accedervi rapidamente. Quando ci sono molte “parti calde”, la velocità della ricerca nell’indice diminuisce.

Quando un nodo inizia a eseguire una query di ricerca su uno shard, alloca un numero di thread pari al numero di core hyperthreading della macchina fisica. Se una query di ricerca interessa un numero elevato di shard, il numero di thread cresce proporzionalmente. Ciò ha un impatto negativo sulla velocità di ricerca e influisce negativamente sull'indicizzazione di nuovi dati.

Per fornire la necessaria latenza di ricerca, abbiamo deciso di utilizzare un SSD. Per elaborare rapidamente le richieste, le macchine che ospitavano questi contenitori dovevano avere almeno 56 core. La cifra 56 è stata scelta come valore condizionatamente sufficiente che determina il numero di thread che Elasticsearch genererà durante il funzionamento. In Elasitcsearch, molti parametri del pool di thread dipendono direttamente dal numero di core disponibili, che a sua volta influisce direttamente sul numero richiesto di nodi nel cluster secondo il principio "meno core - più nodi".

Di conseguenza, abbiamo scoperto che in media uno shard pesa circa 20 gigabyte e ci sono 1 shard per indice. Di conseguenza, se li ruotiamo una volta ogni 360 ore, ne avremo 48. Ogni indice contiene dati per 15 giorni.

Circuiti di scrittura e lettura dati

Scopriamo come vengono registrati i dati in questo sistema.

Supponiamo che qualche richiesta arrivi da Graylog al coordinatore. Ad esempio, vogliamo indicizzare 2-3mila righe.

Il coordinatore, ricevuta una richiesta da Graylog, interroga il master: "Nella richiesta di indicizzazione abbiamo specificato specificatamente un indice, ma in quale frammento scriverlo non è stato specificato".

Il master risponde: "Scrivi queste informazioni sullo shard numero 71", dopodiché vengono inviate direttamente al nodo dati pertinente, dove si trova lo shard primario numero 71.

Dopodiché il registro delle transazioni viene replicato su un frammento di replica, che si trova in un altro data center.

Cluster Elasticsearch da 200 TB+

Una richiesta di ricerca arriva da Graylog al coordinatore. Il coordinatore lo reindirizza in base all'indice, mentre Elasticsearch distribuisce le richieste tra lo shard primario e lo shard di replica utilizzando il principio round-robin.

Cluster Elasticsearch da 200 TB+

I 180 nodi rispondono in modo non uniforme e, mentre rispondono, il coordinatore accumula informazioni che sono già state “sputate” dai nodi dati più veloci. Successivamente, quando tutte le informazioni sono arrivate o la richiesta ha raggiunto un timeout, fornisce tutto direttamente al cliente.

L'intero sistema elabora in media le query di ricerca per le ultime 48 ore in 300-400 ms, escludendo quelle query con un carattere jolly iniziale.

Fiori con Elasticsearch: installazione Java

Cluster Elasticsearch da 200 TB+

Per far funzionare tutto come volevamo originariamente, abbiamo dedicato molto tempo al debug di un'ampia varietà di cose nel cluster.

La prima parte dei problemi rilevati riguardava il modo in cui Java è preconfigurato di default in Elasticsearch.

Il primo problema
Abbiamo riscontrato un numero molto elevato di report secondo cui a livello di Lucene, quando sono in esecuzione processi in background, le unioni dei segmenti Lucene non riescono con un errore. Allo stesso tempo, nei registri era chiaro che si trattava di un errore OutOfMemoryError. Dalla telemetria abbiamo visto che l'anca era libera e non era chiaro il motivo per cui l'operazione falliva.

Si è scoperto che le fusioni dell'indice di Lucene avvengono al di fuori dell'anca. E i container sono abbastanza strettamente limitati in termini di risorse consumate. Solo l'heap poteva adattarsi a queste risorse (il valore heap.size era approssimativamente uguale alla RAM) e alcune operazioni off-heap si bloccavano con un errore di allocazione della memoria se per qualche motivo non rientravano nei ~500 MB rimasti prima del limite.

La correzione è stata piuttosto banale: la quantità di RAM disponibile per il contenitore è stata aumentata, dopodiché ci siamo dimenticati di avere tali problemi.

Problema due
4-5 giorni dopo il lancio del cluster, abbiamo notato che i nodi di dati hanno iniziato a uscire periodicamente dal cluster e ad accedervi dopo 10-20 secondi.

Quando abbiamo iniziato a capirlo, si è scoperto che questa memoria off-heap in Elasticsearch non è controllata in alcun modo. Quando abbiamo dato più memoria al contenitore, siamo stati in grado di riempire i pool di buffer diretti con varie informazioni, che sono state cancellate solo dopo che il GC esplicito è stato lanciato da Elasticsearch.

In alcuni casi, questa operazione ha richiesto molto tempo e durante questo periodo il cluster è riuscito a contrassegnare questo nodo come già terminato. Questo problema è ben descritto ecco.

La soluzione è stata la seguente: abbiamo limitato la capacità di Java di utilizzare la maggior parte della memoria esterna all'heap per queste operazioni. Lo abbiamo limitato a 16 gigabyte (-XX:MaxDirectMemorySize=16g), garantendo che il GC esplicito venisse chiamato molto più spesso ed elaborato molto più velocemente, senza quindi più destabilizzare il cluster.

Problema tre
Se pensi che i problemi con "i nodi che lasciano il cluster nel momento più inaspettato" siano finiti, ti sbagli.

Quando abbiamo configurato il lavoro con gli indici, abbiamo scelto mmapfs to ridurre i tempi di ricerca su cocci freschi con grande segmentazione. Questo è stato un grosso errore, perché quando si usa mmapfs il file viene mappato nella RAM e quindi lavoriamo con il file mappato. Per questo motivo, si scopre che quando il GC tenta di interrompere i thread nell'applicazione, andiamo al safepoint per un tempo molto lungo e, nel percorso verso di esso, l'applicazione smette di rispondere alle richieste del master se è vivo . Di conseguenza, il master ritiene che il nodo non sia più presente nel cluster. Successivamente, dopo 5-10 secondi, il Garbage Collector funziona, il nodo prende vita, entra nuovamente nel cluster e inizia a inizializzare i frammenti. Sembrava tutto “la produzione che meritavamo” e non era adatta a nulla di serio.

Per eliminare questo comportamento, siamo prima passati a niofs standard e poi, quando siamo migrati dalla quinta versione di Elastic alla sesta, abbiamo provato hybridfs, dove questo problema non è stato riprodotto. Puoi leggere ulteriori informazioni sui tipi di archiviazione qui.

Problema quattro
Poi c’è stato un altro problema molto interessante che abbiamo trattato per un tempo record. L'abbiamo catturato per 2-3 mesi perché il suo schema era assolutamente incomprensibile.

A volte i nostri coordinatori andavano al Full GC, di solito dopo pranzo, e da lì non tornavano più. Allo stesso tempo, durante la registrazione del ritardo GC, sembrava così: tutto sta andando bene, bene, bene, e poi all'improvviso tutto sta andando molto male.

All'inizio pensavamo che ci fosse un utente malvagio che stava lanciando una sorta di richiesta che metteva fuori gioco il coordinatore. Abbiamo registrato le richieste per molto tempo, cercando di capire cosa stesse succedendo.

Di conseguenza, si è scoperto che nel momento in cui un utente lancia una richiesta enorme e arriva a uno specifico coordinatore Elasticsearch, alcuni nodi rispondono più a lungo di altri.

E mentre il coordinatore attende una risposta da tutti i nodi, accumula i risultati inviati dai nodi che hanno già risposto. Per GC, ciò significa che i nostri modelli di utilizzo dell'heap cambiano molto rapidamente. E il GC che abbiamo utilizzato non è stato in grado di far fronte a questo compito.

L'unica soluzione che abbiamo trovato per modificare il comportamento del cluster in questa situazione è la migrazione a JDK13 e l'uso del Garbage Collector di Shenandoah. Ciò ha risolto il problema, i nostri coordinatori hanno smesso di cadere.

Qui sono finiti i problemi con Java e sono iniziati i problemi di larghezza di banda.

"Berries" con Elasticsearch: throughput

Cluster Elasticsearch da 200 TB+

Problemi di throughput fanno sì che il nostro cluster funzioni stabilmente, ma nei picchi di numero di documenti indicizzati e durante le manovre le prestazioni sono insufficienti.

Il primo sintomo riscontrato: durante alcune “esplosioni” in produzione, quando viene generato improvvisamente un numero molto elevato di log, l'errore di indicizzazione es_rejected_execution inizia a lampeggiare frequentemente in Graylog.

Ciò è dovuto al fatto che thread_pool.write.queue su un nodo dati, fino al momento in cui Elasticsearch è in grado di elaborare la richiesta di indicizzazione e caricare le informazioni sullo shard su disco, è in grado di memorizzare nella cache solo 200 richieste per impostazione predefinita. E dentro Documentazione elasticsearch Si dice molto poco su questo parametro. Sono indicati solo il numero massimo di thread e la dimensione predefinita.

Naturalmente, abbiamo modificato questo valore e abbiamo scoperto quanto segue: in particolare, nella nostra configurazione, fino a 300 richieste vengono memorizzate nella cache abbastanza bene e un valore più alto è irto del fatto che voliamo di nuovo in Full GC.

Inoltre, poiché si tratta di batch di messaggi che arrivano all'interno di una richiesta, è stato necessario modificare Graylog in modo che scriva non spesso e in piccoli batch, ma in batch enormi o una volta ogni 3 secondi se il batch non è ancora completo. In questo caso, si scopre che l'informazione che scriviamo in Elasticsearch diventa disponibile non in due secondi, ma in cinque (il che ci va abbastanza bene), ma il numero di retray che devono essere effettuati per far passare un grande lo stack di informazioni è ridotto.

Ciò è particolarmente importante in quei momenti in cui qualcosa si è schiantato da qualche parte e lo segnala furiosamente, in modo da non ricevere un Elastic completamente spammato e, dopo un po ', nodi Graylog che sono inutilizzabili a causa di buffer intasati.

Inoltre, quando abbiamo avuto queste stesse esplosioni in produzione, abbiamo ricevuto lamentele da programmatori e tester: nel momento in cui avevano davvero bisogno di questi log, li hanno forniti molto lentamente.

Hanno iniziato a capirlo. Da un lato, era chiaro che sia le query di ricerca che quelle di indicizzazione venivano elaborate, essenzialmente, sulle stesse macchine fisiche, e in un modo o nell’altro ci sarebbero stati alcuni svantaggi.

Ma questo potrebbe essere parzialmente aggirato perché nella sesta versione di Elasticsearch è apparso un algoritmo che consente di distribuire le query tra i nodi di dati rilevanti non secondo il principio random round-robin (il contenitore che esegue l'indicizzazione e contiene i dati primari -shard può essere molto occupato, non ci sarà modo di rispondere rapidamente), ma inoltrare questa richiesta a un contenitore meno caricato con un replica-shard, che risponderà molto più velocemente. In altre parole, siamo arrivati ​​a use_adaptive_replica_selection: true.

L'immagine di lettura inizia ad assomigliare a questa:

Cluster Elasticsearch da 200 TB+

Il passaggio a questo algoritmo ha permesso di migliorare sensibilmente i tempi di query in quei momenti in cui avevamo un grande flusso di log da scrivere.

Infine, il problema principale è stata la rimozione indolore del data center.

Cosa volevamo dal cluster immediatamente dopo aver perso la connessione con un controller di dominio:

  • Se disponiamo di un master attuale nel data center guasto, verrà riselezionato e spostato come ruolo su un altro nodo in un altro controller di dominio.
  • Il master rimuoverà rapidamente tutti i nodi inaccessibili dal cluster.
  • Sulla base di quelli rimanenti, capirà: nel data center perduto avevamo questi e quei frammenti primari, promuoverà rapidamente frammenti di replica complementari nei restanti data center e continueremo a indicizzare i dati.
  • Di conseguenza, la velocità di scrittura e lettura del cluster si ridurrà gradualmente, ma in generale tutto funzionerà, anche se lentamente, ma stabilmente.

A quanto pare, volevamo qualcosa del genere:

Cluster Elasticsearch da 200 TB+

E abbiamo ottenuto quanto segue:

Cluster Elasticsearch da 200 TB+

Come è successo?

Quando il data center è crollato, il nostro padrone è diventato il collo di bottiglia.

Perché?

Il fatto è che il master ha un TaskBatcher, che è responsabile della distribuzione di determinate attività ed eventi nel cluster. Qualsiasi uscita del nodo, qualsiasi promozione di un frammento dalla replica a primario, qualsiasi attività per creare un frammento da qualche parte: tutto questo va prima a TaskBatcher, dove viene elaborato in sequenza e in un thread.

Al momento del ritiro di un data center, si è scoperto che tutti i nodi dati nei data center sopravvissuti consideravano loro dovere informare il master "abbiamo perso questi e quei frammenti e questi e quei nodi dati".

Allo stesso tempo, i nodi dati sopravvissuti hanno inviato tutte queste informazioni all'attuale master e hanno cercato di attendere la conferma che le avesse accettate. Non lo aspettavano, poiché il maestro riceveva compiti più velocemente di quanto potesse rispondere. I nodi hanno esaurito le richieste ripetute e il master in questo momento non ha nemmeno provato a rispondere, ma è stato completamente assorbito dal compito di ordinare le richieste in base alla priorità.

In forma terminale, si è scoperto che i nodi dati hanno spammato il master al punto che è andato in GC completo. Successivamente, il nostro ruolo principale è passato a un nodo successivo, gli è successa assolutamente la stessa cosa e di conseguenza il cluster è completamente crollato.

Abbiamo effettuato delle misurazioni e prima della versione 6.4.0, dove questo problema è stato risolto, ci bastava produrre contemporaneamente solo 10 nodi di dati su 360 per spegnere completamente il cluster.

Sembrava qualcosa del genere:

Cluster Elasticsearch da 200 TB+

Dopo la versione 6.4.0, in cui questo terribile bug è stato corretto, i nodi dati hanno smesso di uccidere il master. Ma questo non lo ha reso “più intelligente”. Vale a dire: quando produciamo 2, 3 o 10 (qualsiasi numero diverso da uno) nodi di dati, il master riceve un primo messaggio che dice che il nodo A se n'è andato e cerca di dirlo al nodo B, nodo C, nodo D.

E al momento questo può essere risolto solo impostando un timeout per i tentativi di dire qualcosa a qualcuno, pari a circa 20-30 secondi, e quindi controllare la velocità con cui il data center esce dal cluster.

In linea di principio, questo rientra nei requisiti inizialmente presentati al prodotto finale come parte del progetto, ma dal punto di vista della “scienza pura” questo è un bug. Che, tra l'altro, è stato risolto con successo dagli sviluppatori nella versione 7.2.

Inoltre, quando un certo nodo di dati usciva, si scoprì che diffondere informazioni sulla sua uscita era più importante che dire all'intero cluster che c'erano questi e quei frammenti primari su di esso (al fine di promuovere un frammento di replica in un altro nodo di dati centro nelle primarie e nelle informazioni potrebbe essere scritta su di essi).

Pertanto, quando tutto è già morto, i nodi dati rilasciati non vengono immediatamente contrassegnati come obsoleti. Di conseguenza, siamo costretti ad attendere fino allo scadere di tutti i ping sui nodi di dati rilasciati, e solo dopo ciò il nostro cluster inizia a dirci che lì, lì e lì dobbiamo continuare a registrare le informazioni. Puoi leggere di più a riguardo qui.

Di conseguenza, l'operazione di ritiro di un data center oggi richiede circa 5 minuti nelle ore di punta. Per un colosso così grande e goffo, questo è un risultato abbastanza buono.

Di conseguenza, siamo giunti alla seguente decisione:

  • Abbiamo 360 nodi dati con dischi da 700 gigabyte.
  • 60 coordinatori per instradare il traffico attraverso questi stessi nodi dati.
  • 40 master che abbiamo lasciato come una sorta di eredità dalle versioni precedenti alla 6.4.0 - per sopravvivere al ritiro del data center eravamo mentalmente preparati a perdere diverse macchine per avere la garanzia di avere un quorum di master anche in lo scenario peggiore
  • Qualsiasi tentativo di combinare i ruoli su un contenitore si è scontrato con il fatto che prima o poi il nodo si sarebbe rotto sotto carico.
  • L'intero cluster utilizza una heap.size di 31 gigabyte: tutti i tentativi di ridurre le dimensioni hanno portato all'uccisione di alcuni nodi su query di ricerca pesanti con il carattere jolly iniziale o all'attivazione dell'interruttore automatico in Elasticsearch stesso.
  • Inoltre, per garantire le prestazioni di ricerca, abbiamo cercato di mantenere il numero di oggetti nel cluster il più piccolo possibile, in modo da elaborare il minor numero possibile di eventi nel collo di bottiglia che abbiamo ottenuto nel master.

Infine sul monitoraggio

Per garantire che tutto funzioni come previsto, monitoriamo quanto segue:

  • Ogni nodo dati segnala al nostro cloud che esiste e che su di esso sono presenti tali e tali frammenti. Quando spegniamo qualcosa da qualche parte, il cluster segnala dopo 2-3 secondi che nel centro A abbiamo spento i nodi 2, 3 e 4 - ciò significa che in altri data center non possiamo in nessun caso spegnere quei nodi su cui c'è solo un frammento Sinistra.
  • Conoscendo la natura del comportamento del master, osserviamo con molta attenzione il numero di attività in sospeso. Poiché anche un'attività bloccata, se non scade in tempo, teoricamente in qualche situazione di emergenza può diventare la ragione per cui, ad esempio, la promozione di un frammento di replica nel primario non funziona, motivo per cui l'indicizzazione smetterà di funzionare.
  • Osserviamo molto attentamente anche i ritardi del garbage collector, perché abbiamo già avuto grandi difficoltà durante l'ottimizzazione.
  • Rifiuta per thread per capire in anticipo dove si trova il collo di bottiglia.
  • Bene, metriche standard come heap, RAM e I/O.

Quando crei il monitoraggio, devi tenere in considerazione le funzionalità di Thread Pool in Elasticsearch. Documentazione elasticsearch descrive le opzioni di configurazione e i valori predefiniti per la ricerca e l'indicizzazione, ma tace completamente su thread_pool.management.Questi thread elaborano, in particolare, query come _cat/shards e altre simili, che sono comode da usare quando si scrive il monitoraggio. Quanto più grande è il cluster, tanto più tali richieste vengono eseguite per unità di tempo, e il suddetto thread_pool.management non solo non è presentato nella documentazione ufficiale, ma è anche limitato per impostazione predefinita a 5 thread, che viene eliminato molto rapidamente, dopo quale monitoraggio smette di funzionare correttamente.

Quello che voglio dire in conclusione: ce l'abbiamo fatta! Siamo stati in grado di fornire ai nostri programmatori e sviluppatori uno strumento che, in quasi ogni situazione, può fornire informazioni in modo rapido e affidabile su ciò che sta accadendo in produzione.

Sì, si è rivelato piuttosto complicato, ma siamo comunque riusciti a adattare i nostri desideri ai prodotti esistenti, che non abbiamo dovuto patchare e riscrivere da soli.

Cluster Elasticsearch da 200 TB+

Fonte: habr.com

Aggiungi un commento