O Mal : Particionamento
uma das coisas difíceis para se acostumar no início é que sem quaisquer consultas de índices que abrangem linhas pode (muito) ser ruim. Pensando no nosso modelo de Armazenamento, isso não é surpreendente. A estratégia que Cassandra usa para distribuir as linhas pelos anfitriões é chamada de particionamento.
particionamento é o ato de esculpir o intervalo de rowkeys atribuindo-os no “token ring”, que também atribui responsabilidade por um segmento (ou seja, partição) do intervalo rowkey para cada máquina. Provavelmente já viste isto quando inicializaste o teu grupo com um”token”. O token dá ao host uma localização ao longo do token ring, que atribui responsabilidade por uma seção do token range. Particionamento é o ato de mapear o rowkey no intervalo token.
existem dois divisores primários: Random and Order Preserving. Eles são devidamente nomeados. O RandomPartitioner coloca os rowkeys em fichas. Com o RandomPartitioner, o token é um hash da rowkey. Isto faz um bom trabalho de distribuir uniformemente os seus dados através de um conjunto de nós, mas torna incrivelmente difícil questionar uma gama do espaço rowkey. A partir de apenas um valor “start rowkey” e um valor “end rowkey”, Cassandra não pode determinar qual o intervalo do espaço token que você precisa. Ele essencialmente precisa realizar uma ” varredura de mesa “para responder à consulta, e uma” varredura de mesa ” em Cassandra é ruim, porque ele precisa ir para cada máquina (muito provavelmente todas as máquinas se você tem uma boa função de hash) para responder à consulta.
The Good : Secondary Indexes
Cassandra does provide a native indexing mechanism in Secondary Indexes. Os índices secundários funcionam a partir dos valores das colunas. Declara um índice secundário numa família de colunas. Datastax tem boa documentação sobre o uso. Sob o capô, Cassandra mantém uma “família de colunas ocultas” como o índice. (Veja a apresentação de Ed Anuff para detalhes) uma vez que Cassandra não mantém a informação do valor da coluna em qualquer nó, e os índices secundários estão no valor das colunas (em vez de rowkeys), uma consulta ainda precisa ser enviada para todos os nós. Além disso, não são recomendados índices secundários para conjuntos de alta cardinalidade. Ainda não procurei, mas presumo que seja por causa do modelo de dados usado na “família de colunas ocultas”. Se a família de colunas ocultas guarda uma linha por valor único (com rowkeys como colunas), então isso significaria digitalizar as linhas para determinar se elas estão dentro do intervalo na consulta.Da apresentação de Ed:
- não recomendado para valores de cardinalidade elevados (isto é,datas temporais,datas de nascimento,palavras-chave, etc.)
- Requer pelo menos uma comparação de igualdade em uma consulta, não é grande por menor que/maior que/intervalo de consultas
- não ordenada – resultados estão no token de ordem, não de consulta de ordem de valor
- Limitado a pesquisa sobre tipos de dados, Cassandra entende nativamente
Com tudo o que disse, índices secundários funcionar fora da caixa e tivemos um bom sucesso de utilizá-los em valores simples.
The Ugly: Do-It-Yourself (DIY) / Wide-Rows
agora, a beleza está nos olhos do observador. Uma das coisas bonitas sobre NoSQL é a simplicidade. As construções são simples: espaços de chaves, famílias de colunas, linhas e Colunas. Mantê-lo simples no entanto significa que às vezes você precisa tomar as coisas em suas próprias mãos.
este é o caso dos índices de fila larga. Utilizando o modelo de armazenamento de Cassandra, é fácil construir seus próprios índices, onde cada chave de linha se torna uma coluna no índice. Isto é às vezes difícil de obter a sua cabeça em torno de, mas vamos imaginar que temos um caso em que queremos selecionar todos os usuários em um código postal. A família principal de colunas de usuários é riscada no userid, zip code é uma coluna em cada linha de usuário. Podemos usar índices secundários, mas há alguns códigos postais. Em vez disso, poderíamos manter uma família de colunas com uma única linha chamada “idx_zipcode”. Poderíamos então escrever colunas nesta linha da forma “zipcode_userid”. Uma vez que as colunas são armazenadas em ordem ordenada, é rápido consultar para todas as colunas que começam com “18964” (e.g. poderíamos usar 18964_ e 18964_ZZZZZZ como valores iniciais e finais).
uma desvantagem óbvia desta abordagem é que as linhas são self-contained em um host. (novamente exceto para réplicas) isso significa que todas as consultas vão atingir um único nó. Ainda não encontrei uma boa resposta para isto.