¿Por qué Cassandra recomienda no crear un índice en columnas de alta cardinalidad?

10

La documentación de Cassandra dice:

No use un índice en estas situaciones:

  • En columnas de alta cardinalidad porque luego consulta un gran volumen de registros para obtener una pequeña cantidad de resultados. Consulte Problemas al utilizar un índice de columna de alta cardinalidad a continuación.

Continúa

Si crea un índice en una columna de alta cardinalidad, que tiene muchos valores distintos, una consulta entre los campos generará muchas búsquedas para obtener muy pocos resultados. En la tabla con mil millones de canciones, buscar canciones por escritor (un valor que generalmente es único para cada canción) en lugar de por su artista, es probable que sea muy ineficiente. Probablemente sería más eficiente mantener manualmente la tabla como una forma de índice en lugar de utilizar el índice integrado de Cassandra. Para las columnas que contienen datos únicos, a veces es bueno usar un índice por conveniencia, siempre que el volumen de consulta a la tabla que tiene una columna indexada sea moderado y no bajo carga constante.

Pero nunca responde realmente la pregunta: ¿por qué es ineficiente? No tengo idea de lo que significa "mantener manualmente la tabla como una forma de índice". Pero luego se contradice de alguna manera con "... a veces es bueno usar un índice por conveniencia siempre que el volumen de la consulta sea moderado ..."

¿Esto solo está tratando de decirme que use el PK cuando y donde pueda? ¿Qué es la ineficiencia? Según tengo entendido, una consulta que alcanzaría un índice necesitaría consultar todos los nodos del clúster, y luego cada nodo haría una búsqueda en su índice local y los resultados se agregarían. Esto no es necesariamente costoso (cada búsqueda de índice debería ser bastante barata), excepto que pagamos en latencia de red, ya que debemos esperar al nodo más lento del lote. ¿Me estoy perdiendo algo aquí?

Pero si tengo una colección que tiene miles de millones de artículos que, en raras ocasiones, deben ser buscados por un atributo diferente pero casi único ... este es un uso apropiado, ¿verdad?

VeryTodos? ¿IDK si la replicación significa que esto puede alcanzar 1/3 del clúster para un factor de replicación de 3 o no?

Thanatos
fuente

Respuestas:

6

Con un índice de Cassandra ( es decir, un "índice secundario", a diferencia de las claves primarias), cada nodo tiene que consultar sus propios datos locales para responder a una consulta (consulte las preguntas frecuentes sobre índices secundarios de Cassandra ). Estos índices también se crean utilizando un proceso en segundo plano . Este trasfondo significa que el índice puede devolver falsos negativos en términos de aciertos (o falsos positivos en términos de errores).

Esto significa que en una columna de alta cardinalidad, la tasa de cambio ( es decir, adiciones / eliminaciones) de esa columna puede ser bastante alta. Y, por lo tanto, si esa tasa de cambio es más rápida que la actualización del índice a través del proceso en segundo plano, entonces usar un índice es "ineficiente" (el índice está realizando más trabajo del que necesita la aplicación, lo que a menudo puede obtener la respuesta incorrecta) .

Un enfoque más eficiente , en términos de precisión de la consulta , podría ser mantener una segunda tabla , en lugar de un índice secundario. Las tablas, a diferencia de los índices , se tratan como cualquier otra tabla. Es más probable que le den a su aplicación los resultados de la consulta que espera . La desventaja es que mantener una tabla como índice , frente a un "índice secundario" de Cassandra, ahora son restricciones de la aplicación ( es decir, el código de la aplicación ahora debe saber insertar / eliminar filas de esa tabla "índice", y para mantener las dos tablas sincronizadas mediante la "reconciliación" a nivel de aplicación

¡Espero que esto ayude!

Castaglia
fuente
Que los índices se crean utilizando un proceso en segundo plano es un poco ... feo. Los falsos positivos son visibles para el usuario, supongo. (No veo cómo no serían). La única parte que aún cuestiono es dónde dices: "Esto significa que en una columna de alta cardinalidad, la tasa de cambio (es decir, adiciones / eliminaciones) de esa columna puede estar bastante alto ". - Entiendo por qué la tasa de cambio, en relación con la creación de índice bg, sería mala, pero todavía no veo qué tiene que ver la alta cardinalidad con ella. (Seguramente, incluso una columna de baja cardinalidad sufriría el mismo destino, ¿no?)
Thanatos
Sí, una columna de baja cardinalidad sufriría el mismo destino. Mi pensamiento era un poco confuso allí, lo admito. Estaba suponiendo que un índice de cardinalidad alto sería más probable que tuviera una tasa de cambio más alta (por lo tanto, sería más probable que exhibiera resultados falsos positivos / negativos); es la tasa de cambio (en relación con el proceso de indexación en segundo plano) lo que es más relevante, no la cardinalidad.
Castaglia
2

Alguna terminología: la tabla primaria es la tabla en la que se crea un índice. La tabla de índice secundaria es la tabla que se crea para mantener un índice en otra tabla.

Los datos de la tabla de índice secundario se almacenan en el mismo nodo que los datos de la tabla primaria. El particionador Cassandra no particiona y distribuye los datos de la tabla de índice. Entonces, si desea realizar una búsqueda en una columna de índice, se consultan todos los nodos, no solo los nodos de réplica que contienen los datos. (el nodo coordinador no sabe dónde residen los datos) https://www.datastax.com/dev/blog/cassandra-native-secondary-index-deep-dive

Para columnas de alta cardinalidad como ssn o alguna otra identificación única, habrá un mapeo uno a uno con la clave primaria. Si crea un índice en dicha columna, los datos residen en el número de nodos del factor de replicación, pero la llamada de búsqueda se ejecuta en todos los nodos. En el mejor de los casos, el coordinador golpea directamente los nodos que contienen datos y una vez que se alcanza el nivel de consistencia, obtiene su resultado. Peor aún, si los datos que está buscando no están presentes en el índice, debe esperar hasta que todos los nodos respondan para descubrir que los datos no están allí. Entonces, por cada llamada de búsqueda en una tabla de índice secundaria, todos los nodos se ven afectados. Compare eso con solo el número de factor de replicación de los nodos que son afectados por cada llamada de búsqueda, en caso de que la tabla sea una tabla C * normal.

Pramod Sivaraju
fuente