Modelagem de Dados em Cassandra

Modelagem de Dados em Cassandra

1. Visão geral

Cassandra é um banco de dados NoSQL que fornece alta disponibilidade e escalabilidade horizontal sem comprometer o desempenho.

Para obter o melhor desempenho do Cassandra, precisamos projetar cuidadosamente o esquema em torno de padrões de consulta específicos para o problema de negócios em questão.

Neste artigo, revisaremos alguns dos conceitos-chave em torno dehow to approach data modeling in Cassandra.

Antes de continuar, você pode ler nosso artigoCassandra with Java para entender o básico e como se conectar ao Cassandra usando Java.

2. Chave de Partição

Cassandra é um banco de dados distribuído no qual os dados são particionados e armazenados em vários nós em um cluster.

A chave de partição é composta por um ou mais campos de dados e éused by the partitioner to generate a token via hashing to distribute the data uniformly across a cluster.

3. Chave de clustering

Uma chave de cluster é composta de um ou mais campos e ajuda a agrupar ou agrupar linhas com a mesma chave de partição e armazená-las na ordem classificada.

Digamos que estejamos armazenando dados de série temporal no Cassandra e queremos recuperar os dados em ordem cronológica. Uma chave de armazenamento em cluster que inclua campos de dados de séries temporais será muito útil para a recuperação eficiente de dados para este caso de uso.

Nota: A combinação de chave de partição e chave de cluster constitui a chave primária e identifica exclusivamente qualquer registro no cluster Cassandra.

4. Diretrizes sobre os padrões de consulta

Antes de iniciar a modelagem de dados no Cassandra, devemos identificar os padrões de consulta e garantir que eles sigam as seguintes diretrizes:

  1. Cada consulta deve buscar dados de uma única partição

  2. Devemos acompanhar a quantidade de dados que estão sendo armazenados em uma partição, pois o Cassandra tem limites em torno do número de colunas que podem ser armazenadas em uma única partição

  3. Não há problema em desnormalizar e duplicar os dados para oferecer suporte a diferentes tipos de padrões de consulta nos mesmos dados

Com base nas diretrizes acima, vamos dar uma olhada em alguns casos de uso do mundo real e como modelaríamos os modelos de dados do Cassandra para eles.

5. Exemplos de modelagem de dados do mundo real

5.1. Postagens do Facebook

Suponha que estamos armazenando postagens no Facebook de diferentes usuários no Cassandra. Um dos padrões de consulta comuns buscará as primeiras publicações 'N' feitas por um determinado usuário.

Assim,we need tostore all data for a particular user on a single partition de acordo com as diretrizes acima.

Além disso, usar o carimbo de data / hora da postagem como a chave de agrupamento será útil para recuperar as principais postagens de ‘N’ com mais eficiência.

Vamos definir o esquema da tabela Cassandra para este caso de uso:

CREATE TABLE posts_facebook (
  user_id uuid,
  post_id timeuuid,
  content text,
  PRIMARY KEY (user_id, post_id) )
WITH CLUSTERING ORDER BY (post_id DESC);

Agora, vamos escrever uma consulta para encontrar as 20 principais postagens do usuárioAnna:

SELECT content FROM posts_facebook WHERE user_id = "Anna_id" LIMIT 20

5.2. Ginásios em todo o país

Suponha que estamos armazenando os detalhes de diferentes academias parceiras nas diferentes cidades e estados de muitos países e gostaríamos de buscar as academias para uma determinada cidade.

Além disso, digamos que precisamos retornar os resultados com as academias classificadas por sua data de abertura.

Com base nas diretrizes acima, devemos armazenar as academias localizadas em uma determinada cidade de um estado e país específico em uma única partição e usar a data de abertura e o nome da academia como chave de cluster.

Vamos definir o esquema da tabela Cassandra para este exemplo:

CREATE TABLE gyms_by_city (
 country_code text,
 state text,
 city text,
 gym_name text,
 opening_date timestamp,
 PRIMARY KEY (
   (country_code, state_province, city),
   (opening_date, gym_name))
 WITH CLUSTERING ORDER BY (opening_date ASC, gym_name ASC);

Agora, vejamos uma consulta que busca as dez primeiras academias até a data de inauguração para a cidade de Phoenix, nos EUA. estado do Arizona:

SELECT * FROM gyms_by_city
  WHERE country_code = "us" AND state = "Arizona" AND city = "Phoenix"
  LIMIT 10

Em seguida, vamos ver uma consulta que busca os dez ginásios mais recentemente abertos na cidade de Phoenix nos EUA. estado do Arizona:

SELECT * FROM gyms_by_city
  WHERE country_code = "us" and state = "Arizona" and city = "Phoenix"
  ORDER BY opening_date DESC
  LIMIT 10

Observação: como a ordem de classificação da última consulta é oposta à ordem de classificação definida durante a criação da tabela, a consulta será executada mais lentamente, pois o Cassandra primeiro buscará os dados e, em seguida, os classificará na memória.

5.3. Clientes e produtos de comércio eletrônico

Digamos que estejamos administrando uma loja de comércio eletrônico e armazenando as informações deCustomereProduct dentro do Cassandra. Vejamos alguns dos padrões de consulta comuns em torno deste caso de uso:

  1. Obter informações deCustomer

  2. Obter informações deProduct

  3. Obtenha todos osCustomers que gostam de um determinadoProduct

  4. Obter todos osProducts de um determinadoCustomer curtidas

Começaremos usando tabelas separadas para armazenar as informações deCustomereProduct. No entanto, precisamos introduzir uma quantidade razoável de desnormalização para dar suporte às 3ª e 4ª consultas mostradas acima.

Criaremos mais duas tabelas para conseguir isso - “Customer_by_Product” e “Product_by_Customer“.

Vejamos o esquema da tabela Cassandra para este exemplo:

CREATE TABLE Customer (
  cust_id text,
  first_name text,
  last_name text,
  registered_on timestamp,
  PRIMARY KEY (cust_id));

CREATE TABLE Product (
  prdt_id text,
  title text,
  PRIMARY KEY (prdt_id));

CREATE TABLE Customer_By_Liked_Product (
  liked_prdt_id text,
  liked_on timestamp,
  title text,
  cust_id text,
  first_name text,
  last_name text,
  PRIMARY KEY (prdt_id, liked_on));

CREATE TABLE Product_Liked_By_Customer (
  cust_id text,
  first_name text,
  last_name text,
  liked_prdt_id text,
  liked_on timestamp,
  title text,
  PRIMARY KEY (cust_id, liked_on));

Observação: para dar suporte às consultas, produtos curtidos recentemente por um determinado cliente e clientes que gostaram recentemente de um determinado produto, usamos a coluna “liked_on” como uma chave de cluster.

Vejamos a consulta para encontrar os dez clientes que mais recentemente gostaram do produto “Pepsi“:

SELECT * FROM Customer_By_Liked_Product WHERE title = "Pepsi" LIMIT 10

E vamos ver a consulta que encontra os produtos curtidos recentemente (até dez) por um cliente chamado “Anna“:

SELECT * FROM Product_Liked_By_Customer
  WHERE first_name = "Anna" LIMIT 10

6. Padrões de consulta ineficientes

Devido à maneira como o Cassandra armazena dados, alguns padrões de consulta não são de todo eficientes, incluindo o seguinte:

  • Fetching data from multiple partitions - isso exigirá que um coordenador busque os dados de vários nós, armazene-os temporariamente no heap e, em seguida, agregue os dados antes de retornar os resultados ao usuário

  • Join-based queries - devido à sua natureza distribuída, o Cassandra não suporta junções de tabelas em consultas da mesma forma que um banco de dados relacional e, como resultado,queries withjoins will be slower and can also lead to inconsistency and availability issues

7. Conclusão

Neste tutorial, abordamos várias práticas recomendadas sobre como abordar a modelagem de dados no Cassandra.

É necessário entender os conceitos principais e identificar os padrões de consulta com antecedência para projetar um modelo de dados correto que obtenha o melhor desempenho de um cluster Cassandra.