Dimensionamento Ottimale degli Shard: Bilanciare Prestazioni e Gestione del Cluster
Padroneggia il dimensionamento degli shard di Elasticsearch per ottimizzare le prestazioni del cluster. Questa guida esplora i compromessi tra numero e dimensione degli shard, coprendo considerazioni chiave come il volume dei dati, il carico di indicizzazione e i pattern di query. Impara le best practice per calcolare l'allocazione ottimale degli shard, sfruttare gli indici basati sul tempo e implementare Index Lifecycle Management (ILM) per costruire un cluster Elasticsearch scalabile ed efficiente.
Dimensionamento Ottimale degli Shard: Bilanciare Prestazioni e Gestione del Cluster
Il dimensionamento degli shard è una di quelle decisioni su Elasticsearch che sembra semplice finché il cluster non ha vissuto per qualche mese. Uno shard è solo un indice Lucene sotto il cofano, ma ogni shard ha un overhead. Troppi shard piccoli rendono il cluster impegnato a gestire metadati e piccoli target di ricerca. Troppi pochi shard grandi rendono la rilocazione, il recupero e alcune ricerche dolorosamente lente.
Non esiste una dimensione universale degli shard che funzioni per ogni cluster. Un cluster di logging con rollover giornaliero, un indice di ricerca prodotti e un cluster di analisi della sicurezza si comportano tutti in modo diverso. L'approccio utile è scegliere una dimensione target dello shard, progettare il rollover o la creazione dell'indice attorno ad essa, e poi aggiustare in base al comportamento reale di indicizzazione e query.
I Fondamenti degli Shard di Elasticsearch
Prima di immergerci nelle strategie di dimensionamento, è essenziale comprendere i concetti di base:
- Indice: Una raccolta di documenti. In Elasticsearch, un indice è suddiviso in più shard.
- Shard: Un'unità di distribuzione. Ogni shard è un indice Lucene autonomo. Un indice può contenere più shard, distribuiti su diversi nodi del cluster.
- Shard Primario: Quando viene creato un indice, gli viene assegnato un numero di shard primari. Questi shard sono dove vengono indicizzati i tuoi dati. Non puoi semplicemente modificare
number_of_shardssu un indice esistente, ma Elasticsearch fornisce operazioni di split e shrink in condizioni specifiche. Molti team considerano ancora il numero di shard primari come una decisione di progettazione perché modificarlo in seguito richiede pianificazione. - Shard Replica: Copie dei tuoi shard primari. Forniscono ridondanza e aumentano la produttività di lettura. Se uno shard primario fallisce, una replica può essere promossa a diventare il primario. Il numero di shard replica può essere modificato in qualsiasi momento.
Come gli Shard Influenzano le Prestazioni
- Prestazioni di Indicizzazione: Ogni shard richiede risorse per l'indicizzazione. Più shard significano più overhead per i nodi coordinatori che gestiscono le richieste. Tuttavia, se gli shard diventano troppo grandi, l'indicizzazione in un singolo shard può diventare un collo di bottiglia.
- Prestazioni delle Query: Le richieste di ricerca vengono distribuite a tutti gli shard primari rilevanti. Un numero maggiore di shard può aumentare il numero di richieste da elaborare, potenzialmente aumentando la latenza. Al contrario, shard molto grandi possono portare a tempi di ricerca più lunghi poiché Lucene deve lavorare su più dati all'interno di quello shard.
- Gestione del Cluster: Un gran numero di shard aumenta il carico sul nodo master, responsabile della gestione dello stato del cluster. Influisce anche sull'overhead di operazioni come la rilocazione degli shard, lo snapshot e il recupero.
- Utilizzo delle Risorse: Ogni shard consuma memoria e I/O del disco. Troppi shard possono esaurire le risorse del nodo, portando a prestazioni degradate o instabilità del nodo.
Considerazioni Chiave per il Dimensionamento degli Shard
La dimensione "ideale" dello shard non è un numero fisso; dipende dal tuo carico di lavoro specifico, dalle caratteristiche dei dati e dall'hardware. Tuttavia, diversi fattori dovrebbero guidare le tue decisioni:
1. Volume dei Dati e Tasso di Crescita
- Dimensione Attuale dei Dati: Quanti dati hai nel tuo indice in questo momento?
- Tasso di Crescita: Quanto velocemente stanno crescendo i tuoi dati? Questo aiuta a prevedere le dimensioni future degli shard.
- Politica di Conservazione dei Dati: Eliminerai i dati vecchi? Questo influisce sulla dimensione effettiva dei dati attivi.
2. Carico di Indicizzazione
- Tasso di Indicizzazione: Quanti documenti al secondo stai indicizzando?
- Dimensione del Documento: Quanto sono grandi in media i singoli documenti?
- Produttività di Indicizzazione: I tuoi nodi possono gestire il carico di indicizzazione con l'attuale configurazione degli shard?
3. Pattern di Query
- Complessità delle Query: Le tue query sono semplici ricerche per parole chiave o aggregazioni complesse?
- Frequenza delle Query: Quanto spesso vengono eseguite query sui tuoi dati?
- Requisiti di Latenza delle Query: Quali sono i tuoi tempi di risposta accettabili?
4. Topologia del Cluster e Risorse
- Numero di Nodi: Quanti nodi ci sono nel tuo cluster?
- Hardware del Nodo: CPU, RAM e disco (l'SSD è altamente raccomandato per Elasticsearch).
- Limiti degli Shard: Elasticsearch include limiti di sicurezza che impediscono a un nodo di contenere un numero eccessivo di shard aperti. Le versioni recenti usano comunemente
cluster.max_shards_per_nodecome guardrail a livello di cluster per gli indici aperti normali.cluster.routing.allocation.total_shards_per_nodeè diverso: limita quanti shard di un singolo indice, o ambito di allocazione corrispondente, possono essere allocati a un nodo. Controlla la tua versione di Elasticsearch prima di modificare una delle due impostazioni.
Best Practice per l'Allocazione degli Shard
1. Punta a una Dimensione Target dello Shard
Sebbene non esista un numero magico, molti cluster di produzione puntano a shard di circa da 10GB a 50GB per carichi di lavoro comuni di log e ricerca. Questo intervallo è un punto di partenza, non una regola. I sistemi ad altissima produttività o con conservazione a lungo termine possono scegliere shard più grandi dopo i test; gli indici di ricerca per piccole aziende possono funzionare meglio con un singolo shard piccolo.
- Troppo piccolo (< 10GB): Può portare a un overhead eccessivo. Ogni shard ha un'impronta di memoria e contribuisce al carico del nodo master. Gestire migliaia di shard minuscoli diventa un onere operativo significativo.
- Troppo grande (> 50GB): Può causare problemi di prestazioni. Le operazioni di unione dei segmenti, recupero e ribilanciamento richiedono più tempo. Se un grande shard fallisce, può richiedere una quantità considerevole di tempo per essere recuperato.
2. Considera gli Indici Basati sul Tempo
Per i dati di serie temporali (log, metriche, eventi), l'uso di indici basati sul tempo è una pratica standard e altamente efficace. Ciò comporta la creazione di nuovi indici per periodi di tempo specifici (es. giornaliero, settimanale, mensile).
- Esempio: Invece di un unico indice enorme, potresti avere
logs-2023.10.26,logs-2023.10.27, ecc. - Vantaggi: Gestione dei dati più semplice (eliminazione di vecchi indici tramite
Index Lifecycle Management - ILM), migliori prestazioni poiché le query spesso hanno come target i dati recenti e dimensioni degli shard controllate.
3. Implementa Index Lifecycle Management (ILM)
Le policy ILM ti consentono di automatizzare la gestione degli indici in base all'età, alla dimensione o al conteggio dei documenti. Puoi definire fasi per un indice (hot, warm, cold, delete) e specificare azioni per ogni fase, inclusa la modifica del numero di repliche, la riduzione degli indici o la loro eliminazione.
- Fase Hot: L'indice viene attivamente scritto e interrogato. Massimizza le prestazioni.
- Fase Warm: L'indice non viene più scritto ma ancora interrogato. Può essere spostato su hardware meno performante, potenzialmente con meno repliche o ridotto.
- Fase Cold: Interrogato raramente. I dati possono essere spostati su storage più economico o nodi a prestazioni inferiori, a seconda della licenza Elasticsearch, della versione e dell'architettura.
- Fase Delete: I dati non sono più necessari e vengono eliminati.
4. Evita l'Over-Sharding
L'over-sharding si verifica quando hai troppi shard per la dimensione del tuo cluster e il volume dei dati. Questa è una trappola comune che porta a scarse prestazioni e problemi di gestione.
- Sintomi: Elevato utilizzo della CPU sui nodi master, aggiornamenti lenti dello stato del cluster, tempi di recupero lunghi e lentezza generale.
- Mitigazione: Pianifica il numero di shard primari fin dall'inizio. Per gli indici basati sul tempo, inizia con un numero ragionevole di shard primari per indice (es. 1 o 3). Puoi sempre aggiungere repliche in seguito.
5. Non Creare Troppi Indici
Allo stesso modo, evita di creare un numero eccessivo di indici quando non necessario. Ogni indice aggiunge overhead. Per i dati non di serie temporali in cui non hai un meccanismo di partizionamento naturale, considera se un singolo indice con un numero appropriato di shard è sufficiente.
6. Considera l'Impostazione number_of_shards
Quando crei un indice, il parametro number_of_shards definisce il numero di shard primari. Questa impostazione è immutabile dopo la creazione dell'indice.
PUT my-index
{
"settings": {
"index": {
"number_of_shards": 3, // Esempio: 3 shard primari
"number_of_replicas": 1 // Esempio: 1 shard replica
}
}
}
- Suggerimento: Per indici più piccoli o con carico di indicizzazione/query molto basso, un singolo shard primario potrebbe essere sufficiente. Per indici più grandi e più attivi, 3 o 5 shard primari possono offrire una migliore distribuzione e resilienza, specialmente se prevedi di dividere l'indice in seguito (anche se la divisione è complessa).
7. Ribilanciamento e Rilocazione
Elasticsearch ribilancia automaticamente gli shard per garantire una distribuzione uniforme tra i nodi. Tuttavia, se gli shard sono troppo grandi, queste operazioni possono essere intensive in termini di risorse e lente. Shard più piccoli e più numerosi possono talvolta ribilanciarsi più velocemente, ma questo è contrastato dall'overhead di gestione di più shard.
8. Ottimizzazione delle Prestazioni delle Query
Se le prestazioni delle tue query sono scadenti, valuta la tua strategia sugli shard. Considera:
- Numero di Shard: Troppi shard possono aumentare l'overhead di coordinamento.
- Dimensione dello Shard: Shard molto grandi possono rallentare l'unione dei segmenti e la ricerca all'interno dello shard.
- Progettazione dell'Indice: Stai usando mapping e analyzer appropriati?
Calcolare il Tuo Numero Ottimale di Shard
Non esiste una formula unica, ma ecco un approccio comune:
- Stima il volume totale dei dati per indice durante il suo ciclo di vita.
- Determina la dimensione target dello shard (es. 30GB).
- Calcola il numero di shard primari necessari:
Volume Totale dei Dati / Dimensione Target dello Shard. - Arrotonda per eccesso al numero intero più vicino. Questo ti dà il tuo
number_of_shardsper l'indice.- Esempio: Se prevedi 90GB di dati e punti a shard da 30GB, avresti bisogno di
90GB / 30GB = 3shard primari.
- Esempio: Se prevedi 90GB di dati e punti a shard da 30GB, avresti bisogno di
- Considera resilienza e distribuzione: Per gli indici critici, considera l'uso di 3 o 5 shard primari per consentire una migliore distribuzione e opzioni di recupero, anche se il tuo volume di dati iniziale non lo richiede strettamente. Il compromesso è un aumento dell'overhead.
- Inizia in modo conservativo: In generale è più facile aggiungere repliche che modificare il numero di shard primari (che di solito richiede reindicizzazione o soluzioni complesse). In caso di dubbio, inizia con meno shard primari e monitora le prestazioni.
Scenario di Esempio: Analisi dei Log
Supponiamo che tu stia indicizzando log di applicazioni:
Volume dei Dati: Prevedi 1TB di log al mese.
Conservazione dei Dati: Conservi i log per 30 giorni.
Dimensione Target dello Shard: Punti a 20GB.
Indici Giornalieri: Crei indici giornalieri (
logstash-YYYY.MM.DD). Ogni indice giornaliero conterrà circa1TB / 30 giorni ≈ 33GBdi dati.Shard Primari per Indice: Dato il target di 20GB e il volume giornaliero di 33GB, potresti scegliere 2 shard primari per indice (
33GB / 20GB ≈ 1,65, arrotondato per eccesso a 2). Questo garantisce che i singoli shard rimangano entro la dimensione target.Repliche: Decidi 1 replica per l'alta disponibilità.
Shard Totali: Durante il periodo di conservazione di 30 giorni, avrai 30 indici, ciascuno con 2 shard primari e 2 replica, per un totale di 60 shard primari e 60 replica attivi in qualsiasi momento.
Questo approccio mantiene i singoli shard gestibili e consente un'efficiente eliminazione dei dati semplicemente cancellando i vecchi indici.
Cosa Di Solito Va Storto
Il problema più comune è l'over-sharding per abitudine. Qualcuno crea indici giornalieri con cinque primari e una replica perché un vecchio tutorial usava quella impostazione. All'inizio sembra innocuo. Poi il cluster ha centinaia di piccoli indici, migliaia di shard minuscoli e i nodi master passano troppo tempo sugli aggiornamenti dello stato del cluster. Anche le ricerche si diffondono su molti shard, il che aggiunge overhead di coordinamento prima ancora che inizi il lavoro di query effettivo.
Il problema opposto si manifesta durante il recupero. Alcuni shard enormi possono interrogarsi in modo accettabile in un giorno normale, ma quando un nodo fallisce o inizia un riavvio progressivo, la rilocazione richiede molto tempo. Anche snapshot e ripristini possono diventare più lenti perché ogni shard è una grande unità di lavoro. Se il tuo obiettivo di recupero è stretto, la dimensione dello shard conta anche quando la latenza delle query sembra a posto.
Gli shard caldi sono un altro problema pratico. Se tutte le nuove scritture vanno a uno shard primario, l'aggiunta di più nodi non distribuirà automaticamente quel carico di scrittura. Il rollover basato sul tempo aiuta perché i nuovi indici possono essere dimensionati per il modello di traffico corrente. Anche le scelte di routing contano. Il routing personalizzato può essere potente, ma una chiave di routing sbagliata può inviare troppi dati a uno shard.
Un Pattern di Rollover Migliore
Per i dati di serie temporali, il rollover basato sulla dimensione è spesso più facile da gestire rispetto agli indici giornalieri fissi. Invece di creare un indice al giorno indipendentemente da tutto, crei un alias di scrittura e lasci che ILM esegua il rollover quando l'indice raggiunge una dimensione target, un'età o un conteggio di documenti.
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_primary_shard_size": "30gb",
"max_age": "1d"
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
Con questo pattern, un fine settimana tranquillo potrebbe produrre meno indici, mentre un giorno impegnativo con incidenti può eseguire il rollover prima. Devi ancora scegliere il numero iniziale di primari, ma il rollover impedisce alla crescita degli shard di allontanarsi troppo dal target.
Come Ispezionare i Tuoi Shard Correnti
Prima di modificare qualsiasi cosa, guarda il cluster che hai:
GET _cat/shards?v&h=index,shard,prirep,state,docs,store,node&s=store:desc
GET _cat/indices?v&h=index,pri,rep,docs.count,store.size,pri.store.size&s=pri.store.size:desc
GET _cluster/health
Stai cercando pattern: molti shard minuscoli, alcuni shard enormi, shard non assegnati, posizionamento non uniforme dei nodi o indici la cui dimensione di archiviazione primaria è molto lontana dal tuo target previsto. Se un indice ha 100GB di dati primari e cinque shard primari, ogni primario è circa 20GB prima delle repliche. Se lo stesso indice ha 100GB e 50 primari, probabilmente hai creato un overhead inutile.
Note Finali
Un buon dimensionamento degli shard riguarda meno la ricerca di un numero perfetto e più il mantenere il cluster facile da gestire. Inizia con un target ragionevole, usa ILM o rollover dove il pattern dei dati si adatta, e osserva cosa succede effettivamente alla dimensione degli shard, alla diffusione delle query, al tempo di recupero e alla pressione sui nodi. Se il tuo cluster è già sovraccarico di shard, risolvilo gradualmente con nuovi template di indici, rollover, shrink o reindicizzazione, piuttosto che cercare di forzare ogni vecchio indice in una nuova forma in una volta sola.