Por que Cassandra recomenda não criar um índice em colunas de alta cardinalidade?

10

A documentação do Cassandra declara,

Não use um índice nestas situações:

  • Nas colunas de alta cardinalidade, você consulta um grande volume de registros para obter um pequeno número de resultados. Consulte Problemas usando um índice de coluna de alta cardinalidade abaixo.

Continua

Se você criar um índice em uma coluna de alta cardinalidade, que possui muitos valores distintos, uma consulta entre os campos incorrerá em muitas buscas por muito poucos resultados. Na tabela com um bilhão de músicas, procurar músicas por compositor (um valor que é normalmente único para cada música) em vez de por seu artista, provavelmente será muito ineficiente. Provavelmente seria mais eficiente manter a tabela manualmente como uma forma de índice, em vez de usar o índice interno Cassandra. Para colunas que contêm dados exclusivos, às vezes é bom usar o índice por conveniência, desde que o volume da consulta na tabela que possui uma coluna indexada seja moderado e não esteja sob carga constante.

Mas nunca realmente responde à pergunta: por que é ineficiente? Não tenho idéia do que significa "manter manualmente a tabela como uma forma de índice". Mas então se contradiz com "... às vezes é bom usar o índice por conveniência, desde que o volume da consulta seja moderado ..."

Isso está apenas tentando me dizer para usar o PK quando e onde posso? Qual é a ineficiência? Meu entendimento é que uma consulta que atingisse um índice precisaria consultar todos os nós no cluster e, em seguida, cada nó faria uma pesquisa em seu índice local e os resultados seriam agregados. Isso não é necessariamente caro (cada pesquisa de índice deve ser bastante barata), exceto que pagamos na latência da rede, pois precisamos esperar pelo nó mais lento do lote. Estou perdendo alguma coisa aqui?

Mas se eu tenho uma coleção que possui vários bilhões de itens que - em raras ocasiões - precisam ser procurados por um atributo diferente, mas quase único ... esse é um uso apropriado, certo?

“Todo mundo? IDK se replicação significa que isso pode atingir 1/3 do cluster por um fator de replicação 3 ou não?

Thanatos
fonte

Respostas:

6

Com um índice Cassandra ( ou seja, um "índice secundário", em oposição às chaves primárias), cada nó deve consultar seus próprios dados locais para responder a uma consulta (consulte as Perguntas frequentes sobre os índices secundários do Cassandra ). Esses índices também são criados usando um processo em segundo plano . Esse pano de fundo significa que o índice pode retornar falsos negativos em termos de ocorrências (ou falsos positivos em termos de faltas).

Isso significa que em uma coluna de alta cardinalidade, a taxa de alteração ( ou seja, adições / exclusões) dessa coluna pode ser bastante alta. E, assim, se essa taxa de mudança é mais rápida do que a actualização do índice via o processo de fundo, em seguida, usando um índice é "ineficiente" (o índice está realizando mais trabalho do que é necessário para a aplicação, que pode muitas vezes obter a resposta errada) .

A mais eficiente abordagem, em termos de consulta precisão , poderia ser a de manter uma segunda mesa , em vez de um índice secundário. As tabelas, ao contrário dos índices , são tratadas como qualquer outra tabela. É mais provável que eles dêem ao seu aplicativo os resultados da consulta que ele espera . A desvantagem é que a manutenção de uma tabela como um índice , em comparação com um "índice secundário" do Cassandra, agora são restrições de aplicativos ( ou seja, seu código de aplicativo agora precisa saber para inserir / excluir linhas dessa tabela "de índices" e para manter as duas tabelas sincronizadas por meio da "reconciliação" no nível do aplicativo).

Espero que isto ajude!

Castaglia
fonte
Que os índices são criados usando um processo em segundo plano é um pouco ... feio. Falsos positivos são visíveis para o usuário, presumo? (Não vejo como eles não seriam.) A única parte que ainda questiono é onde você diz: "Isso significa que, em uma coluna de alta cardinalidade, a taxa de alteração (ou seja, adições / exclusões) dessa coluna pode ser bastante alto ". - Entendo por que a taxa de mudança, em relação à criação de índices BG, seria ruim, mas ainda não vejo o que a alta cardinalidade tem a ver com isso. (Certamente, até mesmo uma coluna de baixa cardinalidade sofreria o mesmo destino, não?)
Thanatos
Sim, uma coluna de baixa cardinalidade sofreria o mesmo destino. Meu pensamento estava um pouco confuso lá, eu admito. Eu estava assumindo que um alto índice de cardinalidade teria maior probabilidade de ter uma taxa de mudança mais alta (portanto, mais provável de exibir os resultados falso-positivos / negativos); é a taxa de alteração (relativa ao processo de indexação em segundo plano) que é mais relevante, não a cardinalidade.
Castaglia
2

Alguma terminologia: Tabela pai é a tabela na qual um índice é criado. Tabela de índice secundário é a tabela criada para manter um índice em outra tabela.

Os dados da tabela de índice secundário são armazenados no mesmo nó que os dados da tabela pai. O particionador Cassandra não particiona e distribui os dados da tabela de índice. Portanto, se você deseja executar uma pesquisa em uma coluna de índice, todos os nós são consultados, não apenas os nós de réplica que contêm os dados. (o nó do coordenador não sabe onde estão os dados) https://www.datastax.com/dev/blog/cassandra-native-secondary-index-deep-dive

Para colunas de alta cardinalidade, como ssn ou algum outro ID exclusivo, haverá um mapeamento de um para um com a chave primária. Se você criar um índice nessa coluna, os dados residirão no número de nós do fator de replicação, mas a chamada de pesquisa será executada em todos os nós. Na melhor das hipóteses, o coordenador atinge diretamente os nós que contêm dados e, uma vez atingido o nível de consistência, você obtém o resultado. Pior, se os dados que você está procurando, não estiverem presentes no índice, aguarde até que todos os nós respondam para descobrir que os dados não estão lá. Portanto, para cada chamada de pesquisa em uma tabela de índice secundária, todos os nós são atingidos. Compare isso com apenas o número do fator de replicação de nós sendo atingido para cada chamada de pesquisa, caso a tabela seja uma tabela C * normal.

Pramod Sivaraju
fonte