Perché Cassandra sconsiglia di creare un indice su colonne con cardinalità elevata?


10

La documentazione di Cassandra afferma che

Non utilizzare un indice in queste situazioni:

  • Su colonne con cardinalità elevata perché esegui una query su un enorme volume di record per un numero limitato di risultati. Vedere Problemi con l'utilizzo di un indice di colonna con cardinalità elevata di seguito.

Si prosegue,

Se si crea un indice su una colonna con cardinalità elevata, che ha molti valori distinti, una query tra i campi comporterà molte ricerche per ottenere pochissimi risultati. Nella tabella con un miliardo di canzoni, cercare le canzoni dello scrittore (un valore che in genere è unico per ogni canzone) anziché dal loro artista, è probabilmente molto inefficiente. Probabilmente sarebbe più efficiente mantenere manualmente la tabella come una forma di un indice invece di usare l'indice incorporato di Cassandra. Per le colonne che contengono dati univoci, a volte è consigliabile utilizzare un indice per comodità, purché il volume di query nella tabella con una colonna indicizzata sia moderato e non sotto carico costante.

Ma non risponde mai veramente alla domanda: perché è inefficiente? Non ho idea di cosa significhi "mantenere manualmente la tabella come forma di un indice". Ma poi si contraddice in qualche modo con "... a volte è utile usare un indice per comodità purché il volume delle query sia moderato ..."

Sta solo cercando di dirmi di usare il PK quando e dove posso? Qual è l'inefficienza? La mia comprensione è che una query che colpirebbe un indice avrebbe bisogno di interrogare ogni nodo¹ del cluster, e quindi ogni nodo farebbe una ricerca nel suo indice locale e i risultati verrebbero quindi aggregati. Questo non è necessariamente costoso (ogni ricerca di indice dovrebbe essere abbastanza economica) tranne per il fatto che paghiamo in latenza di rete, poiché dobbiamo attendere il nodo più lento del lotto. Mi manca qualcosa qui?

Ma se ho una collezione che ha un bajillion di articoli che - in rare occasioni - deve essere cercata da un attributo diverso ma quasi unico ... questo è un uso appropriato, giusto?

¹Every? IDK se la replica significa che questo può colpire 1/3 del cluster per un fattore di replica di 3 o no?

Risposte:


6

Con un indice Cassandra ( ovvero un "indice secondario", al contrario delle chiavi primarie), ogni nodo deve interrogare i propri dati locali per rispondere a una query (vedere le Domande frequenti sugli indici secondari Cassandra ). Questi indici vengono inoltre creati utilizzando un processo in background . Questo background significa che l'indice può restituire falsi negativi in ​​termini di hit (o falsi positivi in ​​termini di miss).

Ciò significa che in una colonna ad alta cardinalità, il tasso di variazione ( cioè aggiunte / eliminazioni) da quella colonna può essere piuttosto elevato. E quindi se quel tasso di cambiamento è più veloce dell'aggiornamento dell'indice tramite il processo in background, l'utilizzo di un indice è "inefficiente" (l'indice sta eseguendo più lavoro di quanto sia necessario dall'applicazione, che spesso potrebbe ottenere la risposta sbagliata) .

Un approccio più efficiente , in termini di accuratezza delle query , potrebbe essere quello di mantenere una seconda tabella , piuttosto che un indice secondario. Le tabelle, al contrario degli indici , vengono trattate come qualsiasi altra tabella. Essi sono più propensi a dare la vostra applicazione i risultati della query che si aspetta . Il rovescio della medaglia è che il mantenimento di una tabella come indice , rispetto a un "indice secondario" di Cassandra, ora sono vincoli dell'applicazione ( cioè il codice dell'applicazione ora deve sapere per inserire / eliminare le righe da quella tabella "indice", e mantenere sincronizzate le due tabelle tramite la "riconciliazione" a livello di applicazione).

Spero che sia di aiuto!


Che gli indici siano creati usando un processo in background è un po '... brutto. I falsi positivi sono visibili all'utente, presumo? (Non vedo come non sarebbero.) L'unica parte che ancora mi chiedo è dove dici: "Ciò significa che in una colonna ad alta cardinalità, il tasso di cambiamento (cioè aggiunte / eliminazioni) da quella colonna può essere piuttosto alto ". - Capisco perché il tasso di cambiamento, in relazione alla costruzione dell'indice bg, sarebbe negativo, ma non vedo ancora che cosa abbia a che fare l'alta cardinalità. (Sicuramente, anche una colonna a bassa cardinalità subirebbe lo stesso destino, no?)
Thanatos

Sì, una colonna a bassa cardinalità subirebbe lo stesso destino. Il mio pensiero era un po 'confuso lì, lo ammetto. Sono stato presupposto che un alto indice di cardinalità sarebbe più probabilità di avere un più alto tasso di cambiamento (quindi più probabile che mostra i falsi positivi / risultati negativi); è il tasso di cambiamento (relativo al processo di indicizzazione in background) che è più rilevante, non la cardinalità.
Castaglia,

2

Alcuni termini: la tabella padre è la tabella su cui viene creato un indice. La tabella dell'indice secondario è la tabella creata per mantenere un indice su un'altra tabella.

I dati della tabella di indice secondaria sono archiviati sullo stesso nodo dei dati della tabella principale. Il partizionatore Cassandra non esegue il partizionamento e la distribuzione dei dati della tabella dell'indice. Pertanto, se si desidera eseguire la ricerca su una colonna di indice, vengono interrogati tutti i nodi, non solo i nodi di replica contenenti i dati. (il nodo coordinatore non sa dove risiedono i dati) https://www.datastax.com/dev/blog/cassandra-native-secondary-index-deep-dive

Per colonne con cardinalità elevata come ssn o qualche altro ID univoco, ci sarà un mapping uno a uno con la chiave primaria. Se si crea un indice su tale colonna, i dati risiedono sul numero del fattore di replica dei nodi, ma la chiamata di ricerca viene eseguita su tutti i nodi. Nel migliore dei casi, il coordinatore colpisce direttamente i nodi che contengono dati e, una volta raggiunto il livello di coerenza, si ottiene il risultato. Peggio ancora, se i dati che stai cercando non sono presenti nell'indice, aspetti fino a quando tutti i nodi rispondono per scoprire che i dati non sono presenti. Quindi, per ogni chiamata di ricerca su una tabella di indice secondaria, vengono colpiti tutti i nodi. Confronta questo con solo il numero del fattore di replica dei nodi che vengono colpiti per ogni chiamata di ricerca, nel caso in cui la tabella sia una normale tabella C *.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.