Como funcionam os índices secundários em Cassandra?

Acho que tenho uma família de colunas.
CREATE TABLE update_audit (
  scopeid bigint,
  formid bigint,
  time timestamp,
  record_link_id bigint,
  ipaddress text,
  user_zuid bigint,
  value text,
  PRIMARY KEY ((scopeid, formid), time)
  ) WITH CLUSTERING ORDER BY (time DESC)

com dois índices secundários, em que record_link_id é uma coluna de alta cardinalidade:

CREATE INDEX update_audit_id_idx ON update_audit (record_link_id);

CREATE INDEX update_audit_user_zuid_idx ON update_audit (user_zuid);
De acordo com o meu conhecimento, a Cassandra criará duas famílias de colunas ocultas como esta.
CREATE TABLE update_audit_id_idx(
    record_link_id bigint,
    scopeid bigint,
    formid bigint,
    time timestamp
    PRIMARY KEY ((record_link_id), scopeid, formid, time)
);

CREATE TABLE update_audit_user_zuid_idx(
    user_zuid bigint,
    scopeid bigint,
    formid bigint,
    time timestamp
    PRIMARY KEY ((user_zuid), scopeid, formid, time)
);
Cassandra índices secundários são implementados como índices locais em vez de serem distribuídos como tabelas normais. Cada nó só armazena um índice para os dados que armazena.

considere a seguinte consulta:

select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897;
  1. Como esta consulta irá executar 'debaixo do capô' em Cassandra?
  2. Como é que um índice de coluna de alta cardinalidade (record_link_idafectará o seu desempenho? A Cassandra vai tocar em todos os nós para a consulta acima? Porquê?
  3. quais os critérios que serão executados em primeiro lugar, a tabela de base partition_key ou a tabela secundária partition_key? Como É que a Cassandra vai Intersectar estes dois resultados?
Author: adinas, 2015-04-17

2 answers

select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897;
Como a consulta acima funcionará internamente em cassandra?

Essencialmente, todos os dados para as partições scopeid=35 e formid=78005 serão devolvidos, e depois filtrados pelo índice record_link_id. Irá procurar o item record_link_id para 9897, e tentar corresponder aos itens que correspondem às linhas devolvidas onde scopeid=35 e formid=78005. A intersecção das linhas para as chaves de partição e as chaves de índice serão devolvidas.

Quão elevada é a coluna de cardinalidade (record_link_id)índice irá afetar o desempenho da consulta para a consulta acima?

Os índices de alta cardinalidade criam essencialmente uma linha para (quase) cada entrada na tabela principal. O desempenho é afetado, porque Cassandra é projetado para realizar leituras sequenciais para resultados de consulta. Uma consulta index essencialmente força Cassandra a realizar leiturasaleatórias . Como a cardinalidade de seu valor indexado aumenta, assim faz o tempo que leva para encontrar o valor questionado.

A cassandra vai tocar todos os nós para a consulta acima? Por quê?
Não. Ele só deve tocar um nó que é responsável pela partição scopeid=35 e formid=78005. Os índices também são armazenados localmente, apenas contêm entradas que são válidas para o nó local.

Criar um índice sobre colunas de alta cardinalidade será o modelo de dados mais rápido e melhor

O problema aqui é que a abordagem não escala, e será lenta se update_audit é um conjunto de dados grande. MVP Richard Low tem um grande artigo sobre índices secundários ( O ponto doce para a indexação Secundária de Cassandra ), e particularmente neste ponto:

Se a sua tabela fosse significativamente maior que a memória, uma consulta seria muito lenta até mesmo para devolver apenas alguns milhares de resultados. Retornar potencialmente milhões de usuários seria desastroso, mesmo que parecesse ser uma consulta eficiente.

...

Na prática, isto significa que a indexação é mais útil para devolver dezenas, talvez centenas de resultados. Ter isto em mente quando você considerar usar um índice secundário.
Agora, a sua abordagem de restringir primeiro por uma partição específica vai ajudar (como a sua partição certamente deve caber na memória). Mas eu sinto que a escolha mais acertada aqui seria fazer record_link_id Uma chave de agrupamento, em vez de depender de um índice secundário.

Editar

Como é que ter Índice de baixa cardinalidade, quando há milhões de utilizadores, escala mesmo quando fornecemos o chave primária

Vai depender da largura das fileiras. A coisa complicada sobre índices de cardinalidade extremamente baixos, é que o % das linhas retornadas é geralmente maior. Por exemplo, considere uma linha larga users tabela. Você restringe pela chave de partição em sua consulta, mas ainda existem 10 mil linhas retornadas. Se o seu índice estiver em algo como gender, a sua consulta terá de filtrar cerca de metade dessas linhas, o que não irá funcionar bem. Os índices secundários tendem a funcionar best on (for lack of a better description) "middle of the road" cardinality. Usando o exemplo acima de uma tabela de linhas largas users, um índice em country ou state deve ter um desempenho muito melhor do que um índice em gender (assumindo que a maioria desses utilizadores não vivem todos no mesmo país ou estado).

Editar 20180913

Para sua resposta à primeira pergunta, " Como a consulta acima funcionará internamente em cassandra?", você sabe qual é o comportamento quando consulta com paginação?

Considere o seguinte diagrama, extraído da documentação do controlador Java (v3. 6):

enter image description here

Basicamente, paging fará com que a consulta se separe e retorne ao cluster para a próxima iteração de resultados. Seria menos provável um tempo-limite, mas o desempenho tenderá para baixo, proporcional ao tamanho do conjunto de resultados totais e o número de nós no cluster.

TL; DR; quanto mais resultados solicitados se espalharem sobre mais nós, quanto mais tempo vai demorar.

 54
Author: Aaron, 2020-06-20 09:12:55

A consulta com apenas um índice secundário também é possível na Cassandra 2.x

Seleccione * de update_audit onde gravar_ link_ ID=9897;

Mas isto tem um grande impacto na obtenção de dados, porque lê todas as partições no ambiente distribuído. Os dados obtidos por esta consulta também não são consistentes e não puderam retransmitir nele.

Sugestão:
O uso do índice secundário é considerado uma pesquisa de sujeira da vista do modelo de dados de NoSQL.

To evitar índice secundário, poderíamos criar uma nova tabela e copiar dados para ele. Uma vez que esta é uma consulta da aplicação, as tabelas são derivadas de consultas.

 2
Author: Swam Guru, 2015-09-08 11:41:35