1. Información general
Cassandra es una base de datos NoSQL que proporciona alta disponibilidad y escalabilidad horizontal sin comprometer el rendimiento.
Para obtener el mejor rendimiento de Cassandra, debemos diseñar cuidadosamente el esquema en torno a los patrones de consulta específicos del problema empresarial en cuestión.
En este artículo, revisaremos algunos de los conceptos clave sobre cómo abordar el modelado de datos en Cassandra .
Antes de continuar, puede consultar nuestro artículo de Cassandra con Java para comprender los conceptos básicos y cómo conectarse a Cassandra mediante Java.
2. Clave de partición
Cassandra es una base de datos distribuida en la que los datos se particionan y almacenan en varios nodos dentro de un clúster.
La clave de partición se compone de uno o más campos de datos y el particionador la utiliza para generar un token mediante hash para distribuir los datos de manera uniforme en un clúster .
3. Clave de agrupación
Una clave de agrupación se compone de uno o más campos y ayuda a agrupar filas con la misma clave de partición y almacenarlas en orden ordenado.
Digamos que estamos almacenando datos de series de tiempo en Cassandra y queremos recuperar los datos en orden cronológico. Una clave de agrupamiento que incluya campos de datos de series de tiempo será muy útil para la recuperación eficiente de datos para este caso de uso.
Nota: La combinación de clave de partición y clave de agrupación constituye la clave principal e identifica de forma única cualquier registro en el clúster de Cassandra.
4. Directrices sobre los patrones de consulta
Antes de comenzar con el modelado de datos en Cassandra, debemos identificar los patrones de consulta y asegurarnos de que se adhieran a las siguientes pautas:
- Cada consulta debe obtener datos de una sola partición.
- Debemos realizar un seguimiento de la cantidad de datos que se almacenan en una partición, ya que Cassandra tiene límites en torno al número de columnas que se pueden almacenar en una sola partición.
- Está bien desnormalizar y duplicar los datos para admitir diferentes tipos de patrones de consulta sobre los mismos datos
Con base en las pautas anteriores, veamos algunos casos de uso del mundo real y cómo modelaríamos los modelos de datos de Cassandra para ellos.
5. Ejemplos de modelado de datos del mundo real
5.1. Publicaciones de Facebook
Supongamos que estamos almacenando publicaciones de Facebook de diferentes usuarios en Cassandra. Uno de los patrones de consulta más comunes será buscar las publicaciones ' N ' principales realizadas por un usuario determinado.
Por lo tanto, necesitamos almacenar todos los datos de un usuario en particular en una sola partición según las pautas anteriores.
Además, usar la marca de tiempo de la publicación como clave de agrupamiento será útil para recuperar las publicaciones ' N ' principales de manera más eficiente.
Definamos el esquema de tabla de 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);
Ahora, escriba una consulta para encontrar las 20 publicaciones principales para la usuaria Anna :
SELECT content FROM posts_facebook WHERE user_id = "Anna_id" LIMIT 20
5.2. Gimnasios en todo el país
Suponga que estamos almacenando los detalles de diferentes gimnasios asociados en las diferentes ciudades y estados de muchos países y nos gustaría buscar los gimnasios de una ciudad determinada.
Además, digamos que debemos devolver los resultados con gimnasios ordenados por fecha de apertura.
De acuerdo con las pautas anteriores, debemos almacenar los gimnasios ubicados en una ciudad determinada de un estado y país específico en una sola partición y usar la fecha de apertura y el nombre del gimnasio como clave de agrupación.
Definamos el esquema de la tabla Cassandra para este ejemplo:
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);
Ahora, veamos una consulta que busca los primeros diez gimnasios por su fecha de apertura para la ciudad de Phoenix dentro del estado estadounidense de Arizona:
SELECT * FROM gyms_by_city WHERE country_code = "us" AND state = "Arizona" AND city = "Phoenix" LIMIT 10
A continuación, veamos una consulta que busca los diez gimnasios abiertos más recientemente en la ciudad de Phoenix dentro del estado estadounidense de Arizona:
SELECT * FROM gyms_by_city WHERE country_code = "us" and state = "Arizona" and city = "Phoenix" ORDER BY opening_date DESC LIMIT 10
Nota: Como el orden de clasificación de la última consulta es opuesto al orden de clasificación definido durante la creación de la tabla, la consulta se ejecutará más lentamente ya que Cassandra primero obtendrá los datos y luego los clasificará en la memoria.
5.3. Clientes y productos de comercio electrónico
Digamos que tenemos una tienda de comercio electrónico y que almacenamos la información del cliente y del producto en Cassandra. Veamos algunos de los patrones de consulta comunes en torno a este caso de uso:
- Obtener información del cliente
- Obtener información del producto
- Obtenga todos los clientes a los que les guste un producto determinado
- Obtener todos los productos que le gustan a un cliente determinado
Comenzaremos usando tablas separadas para almacenar la información del Cliente y del Producto . Sin embargo, necesitamos introducir una cantidad considerable de desnormalización para admitir las consultas 3 y 4 que se muestran arriba.
We will create two more tables to achieve this – “Customer_by_Product” and “Product_by_Customer“.
Let's look at the Cassandra table schema for this example:
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));
Note: To support both the queries, recently-liked products by a given customer and customers who recently liked a given product, we have used the “liked_on” column as a clustering key.
Let's look at the query to find the ten Customers who most recently liked the product “Pepsi“:
SELECT * FROM Customer_By_Liked_Product WHERE title = "Pepsi" LIMIT 10
And let's see the query that finds the recently-liked products (up to ten) by a customer named “Anna“:
SELECT * FROM Product_Liked_By_Customer WHERE first_name = "Anna" LIMIT 10
6. Inefficient Query Patterns
Due to the way that Cassandra stores data, some query patterns are not at all efficient, including the following:
- Obtención de datos de múltiples particiones : esto requerirá que un coordinador obtenga los datos de múltiples nodos, los almacene temporalmente en un montón y luego agregue los datos antes de devolver los resultados al usuario
- Consultas basadas en combinaciones : debido a su naturaleza distribuida, Cassandra no admite combinaciones de tablas en consultas de la misma manera que lo hace una base de datos relacional y, como resultado, las consultas con combinaciones serán más lentas y también pueden generar problemas de inconsistencia y disponibilidad.
7. Conclusión
En este tutorial, hemos cubierto varias prácticas recomendadas sobre cómo abordar el modelado de datos en Cassandra.
Es necesario comprender los conceptos básicos e identificar los patrones de consulta por adelantado para diseñar un modelo de datos correcto que obtenga el mejor rendimiento de un clúster de Cassandra.