Proverò a spiegare con un vero esempio poiché la risposta e le risposte che hai ricevuto non sembrano aiutarti.
Quando scarichi elasticsearch e lo avvii, crei un nodo elasticsearch che tenta di unirsi a un cluster esistente se disponibile o ne crea uno nuovo. Supponiamo che tu abbia creato il tuo nuovo cluster con un singolo nodo, quello che hai appena avviato. Non abbiamo dati, quindi abbiamo bisogno di creare un indice.
Quando si crea un indice (un indice viene creato automaticamente anche quando si indicizza anche il primo documento) è possibile definire quanti frammenti sarà composto. Se non specifichi un numero, avrà il numero predefinito di frammenti: 5 primarie. Cosa significa?
Significa che elasticsearch creerà 5 frammenti primari che conterranno i tuoi dati:
____ ____ ____ ____ ____
| 1 | | 2 | | 3 | | 4 | | 5 |
|____| |____| |____| |____| |____|
Ogni volta che indicizzi un documento, elasticsearch deciderà quale frammento primario dovrebbe contenere quel documento e indicizzerà lì. I frammenti primari non sono una copia dei dati, sono i dati! Avere più frammenti aiuta a sfruttare l'elaborazione parallela su una singola macchina, ma il punto è che se iniziamo un'altra istanza di elasticsearch sullo stesso cluster, i frammenti verranno distribuiti in modo uniforme sul cluster.
Il nodo 1 conterrà quindi ad esempio solo tre frammenti:
____ ____ ____
| 1 | | 2 | | 3 |
|____| |____| |____|
Poiché i restanti due frammenti sono stati spostati nel nodo appena avviato:
____ ____
| 4 | | 5 |
|____| |____|
Perché succede? Perché elasticsearch è un motore di ricerca distribuito e in questo modo è possibile utilizzare più nodi / macchine per gestire grandi quantità di dati.
Ogni indice elasticsearch è composto da almeno un frammento primario poiché è lì che vengono archiviati i dati. Ogni frammento ha un costo, tuttavia, quindi se hai un singolo nodo e nessuna crescita prevedibile, resta solo un singolo frammento primario.
Un altro tipo di frammento è una replica. Il valore predefinito è 1, il che significa che ogni frammento primario verrà copiato in un altro frammento che conterrà gli stessi dati. Le repliche vengono utilizzate per aumentare le prestazioni di ricerca e per il failover. Un frammento di replica non verrà mai allocato sullo stesso nodo in cui si trova il relativo primario (sarebbe praticamente come mettere un backup sullo stesso disco dei dati originali).
Nel nostro esempio, con 1 replica avremo l'intero indice su ciascun nodo, poiché 2 frammenti di replica saranno allocati sul primo nodo e conterranno esattamente gli stessi dati dei frammenti primari sul secondo nodo:
____ ____ ____ ____ ____
| 1 | | 2 | | 3 | | 4R | | 5R |
|____| |____| |____| |____| |____|
Lo stesso vale per il secondo nodo, che conterrà una copia dei frammenti primari sul primo nodo:
____ ____ ____ ____ ____
| 1R | | 2R | | 3R | | 4 | | 5 |
|____| |____| |____| |____| |____|
Con una configurazione come questa, se un nodo si arresta, hai ancora l'intero indice. I frammenti di replica diventeranno automaticamente primari e il cluster funzionerà correttamente nonostante l'errore del nodo, come segue:
____ ____ ____ ____ ____
| 1 | | 2 | | 3 | | 4 | | 5 |
|____| |____| |____| |____| |____|
Dato che hai "number_of_replicas":1
, le repliche non possono più essere assegnate in quanto non sono mai allocate sullo stesso nodo in cui si trova il loro primario. Ecco perché avrai 5 frammenti non assegnati, le repliche e lo stato del cluster saranno YELLOW
invece di GREEN
. Nessuna perdita di dati, ma potrebbe essere migliore in quanto alcuni frammenti non possono essere assegnati.
Non appena viene eseguito il backup del nodo rimasto, si unirà nuovamente al cluster e le repliche verranno assegnate di nuovo. Il frammento esistente sul secondo nodo può essere caricato ma devono essere sincronizzati con gli altri frammenti, poiché molto probabilmente le operazioni di scrittura sono avvenute mentre il nodo era inattivo. Al termine di questa operazione, lo stato del cluster diventerà GREEN
.
Spero che questo ti chiarisca le cose.