Prestazioni nelle relazioni genitore-figlio in Elasticsearch

Per questo post, utilizzeremo Elasticsearch ospitato su Qbox.io. Puoi registrarti o avviare il tuo cluster qui, o fare clic su “Inizia” nella navigazione dell’intestazione. Se hai bisogno di aiuto per la configurazione, fai riferimento a ” Provisioning di un cluster Qbox Elasticsearch.”

I vantaggi che genitore-figlio ha sugli oggetti nidificati sono i seguenti:

  • Il documento padre può essere aggiornato senza reindicizzare i figli.
  • I documenti figlio possono essere aggiunti, modificati o eliminati senza influire sul genitore o su altri figli. Ciò è particolarmente utile quando i documenti figlio sono di grandi dimensioni e devono essere aggiunti o modificati frequentemente.
  • I documenti figlio possono essere restituiti come risultati di una richiesta di ricerca.

La relazione genitore-figlio è simile in natura al modello nidificato: entrambi ci consentono di associare un’entità a un’altra. La differenza è che, con gli oggetti nidificati, tutte le entità vivono all’interno dello stesso documento mentre, con genitore-figlio, il genitore e i figli sono documenti completamente separati. Tuttavia, è anche associato ad alcune restrizioni:

Restrizioni padre – figlio

  • I tipi padre e figlio devono essere diversi o non è possibile stabilire relazioni padre-figlio tra documenti dello stesso tipo.
  • L’impostazione _parent.type può puntare solo a un tipo che non esiste ancora. Ciò significa che un tipo non può diventare un tipo padre dopo che è stato creato.
  • I documenti padre e figlio devono essere indicizzati sullo stesso frammento. L’ID genitore viene utilizzato come valore di routing per il figlio, per garantire che il figlio sia indicizzato sullo stesso shard del genitore. Ciò significa che lo stesso valore padre deve essere fornito quando si ottiene, si elimina o si aggiorna un documento figlio.

Le principali differenze tra relazioni genitore-figlio e relazioni annidate possono essere riassunte come segue:

Oggetto nidificato Genitore-Figlio
1. Gli oggetti nidificati vengono salvati nello stesso documento. Gli oggetti padre e figlio vengono salvati separatamente in documenti diversi.
2. Un oggetto figlio può avere più oggetti padre. Un oggetto figlio non può avere più oggetti padre.
3. L’interrogazione è relativamente veloce. L’interrogazione è lenta perché figlio e genitore sono memorizzati separatamente.
4. Può facilmente mantenere più livelli nidificati. Difficile mantenere più livelli nidificati.
5. L’interrogazione a livello nidificato è ben definita e semplice da utilizzare per qualsiasi numero di oggetti nidificati. Anche Query string può essere utilizzato per interrogare gli oggetti annidati. L’interrogazione si complica quando sono presenti più relazioni genitore-figlio.
6. Può recuperare tutti i dati poiché risiedono nello stesso oggetto. Impossibile recuperare i documenti figlio e padre in una singola query.
7. L’oggetto nidificato viene duplicato per ogni oggetto genitore. Nessuna duplicazione di dati coinvolta poiché la relazione è normalizzata.
8. Se un oggetto nidificato viene modificato, tutti gli oggetti padre devono essere ri-indicizzati. Non è necessario ri-indicizzare il genitore perché viene mantenuta solo una connessione tra di loro.

Gli oggetti nidificati possono essere preferiti rispetto a genitore-figlio per gestire le associazioni a causa dei seguenti motivi:

  • Quando i modelli di database contengono più associazioni nidificate in più livelli. Pertanto, possono essere gestiti facilmente con l’approccio dell’oggetto nidificato.
  • Nell’approccio padre-figlio, un oggetto figlio non può avere più oggetti padre.
  • Le query nidificate sono più facili da eseguire nell’approccio degli oggetti nidificati.
  • Impossibile recuperare i campi figlio e padre in una singola query.

Considerazioni sulle prestazioni: Ordinali globali

Ordinali globali è una struttura di dati in cima a fielddata e doc values, che mantiene una numerazione incrementale per ogni termine univoco in un ordine lessicografico. Ogni termine ha un numero univoco e il numero di termine A è inferiore al numero di termine B. Gli ordinali globali sono supportati solo nei campi di testo e parole chiave.

I valori Fielddata e doc hanno anche ordinali, che è una numerazione univoca per tutti i termini in un particolare segmento e campo. Gli ordinali globali si basano solo su questo, fornendo una mappatura tra gli ordinali del segmento e gli ordinali globali, questi ultimi unici nell’intero frammento.

Gli ordinali globali vengono utilizzati per le funzionalità che utilizzano gli ordinali dei segmenti, come l’ordinamento e l’aggregazione dei termini, per migliorare il tempo di esecuzione. Un’aggregazione di termini si basa esclusivamente sugli ordinali globali per eseguire l’aggregazione a livello di shard, quindi converte gli ordinali globali nel termine reale solo per la fase di riduzione finale, che combina i risultati di diversi shard.

Interessato a Kubernetes? Controlla il nostro Supporto Enterprise Kubernetes

Parent-child utilizza gli ordinali globali per accelerare i join. Gli ordinali globali devono essere ricostruiti dopo ogni modifica a uno shard. Più valori id padre sono memorizzati in uno shard, più tempo ci vuole per ricostruire gli ordinali globali per il campo _parent.

Gli ordinali globali, per impostazione predefinita, vengono creati con entusiasmo: se l’indice è cambiato, gli ordinali globali per il campo _parent verranno ricostruiti come parte di refresh. Questo può aggiungere tempo significativo l’aggiornamento. Tuttavia, la maggior parte delle volte questo è il giusto compromesso, altrimenti gli ordinali globali vengono ricostruiti quando viene utilizzata la prima query o aggregazione genitore-figlio. Ciò può introdurre un picco di latenza significativo per gli utenti e di solito questo è peggiore in quanto più ordinali globali per il campo _parent possono essere tentati di ricostruire entro un singolo intervallo di aggiornamento quando si verificano molte scritture.

Quando il genitore/figlio è usato di rado, e scrive che si verificano di frequente, potrebbe essere utile disabilitare desideroso di caricamento:

La quantità di heap globale ordinali può essere verificata come segue:

Conclusione

La capacità di unire più generazioni (come Grandparents and Grandchildren) sembra interessante fino a quando si pensa ai costi:

  • più si unisce a voi hanno, la peggio saranno le prestazioni.
  • Ogni generazione di genitori deve avere i campi string _id memorizzati in memoria, che possono consumare molta RAM.

Mentre consideri i tuoi schemi di relazione e se genitore-figlio è giusto per te, considera questo consiglio sulle relazioni genitore-figlio:

  • Usa le relazioni genitore-figlio con parsimonia e solo quando ci sono molti più figli dei genitori.
  • Evitare di utilizzare più join padre-figlio in una singola query.
  • Evita il punteggio utilizzando il filtro has_child o la query has_child con score_mode impostato su nessuno.
  • Mantieni gli ID genitore brevi, in modo che comprimano meglio i valori doc e utilizzino meno memoria quando vengono caricati transitoriamente.

Dagli un vortice!

È facile creare un cluster Elasticsearch ospitato standard su uno qualsiasi dei nostri 47 data center Rackspace, Softlayer o Amazon. E ora puoi eseguire il provisioning dei tuoi crediti AWS su Qbox Private Hosted Elasticsearch.

Domande? Mandaci una nota e ti daremo una pronta risposta.

Non ti stai ancora godendo i vantaggi di una ricerca enterprise ELK-stack ospitata su Qbox? Ti invitiamo a creare un account oggi e scoprire quanto sia facile gestire e scalare il tuo ambiente Elasticsearch nel nostro servizio di hosting cloud.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.