Перейти к основному содержимому

Моделирование данных в Cassandra

· 6 мин. чтения

1. Обзор

Cassandra — это база данных NoSQL, которая обеспечивает высокую доступность и горизонтальную масштабируемость без ущерба для производительности.

Чтобы получить максимальную производительность от Cassandra, нам нужно тщательно спроектировать схему на основе шаблонов запросов, специфичных для рассматриваемой бизнес-задачи.

В этой статье мы рассмотрим некоторые ключевые концепции подхода к моделированию данных в Cassandra .

Прежде чем продолжить, вы можете прочитать нашу статью о Cassandra с Java , чтобы понять основы и узнать, как подключиться к Cassandra с помощью Java.

2. Ключ раздела

Cassandra — это распределенная база данных, в которой данные разделены и хранятся на нескольких узлах внутри кластера.

Ключ раздела состоит из одного или нескольких полей данных и используется разделителем для создания маркера посредством хэширования для равномерного распределения данных по кластеру .

3. Ключ кластеризации

Ключ кластеризации состоит из одного или нескольких полей и помогает кластеризовать или группировать вместе строки с одним и тем же ключом секции и хранить их в отсортированном порядке.

Допустим, мы храним данные временных рядов в Cassandra и хотим получить данные в хронологическом порядке. Ключ кластеризации, включающий поля данных временных рядов, будет очень полезен для эффективного извлечения данных для этого варианта использования.

Примечание. Комбинация ключа секции и ключа кластеризации составляет первичный ключ и однозначно идентифицирует любую запись в кластере Cassandra.

4. Рекомендации по шаблонам запросов

Прежде чем приступить к моделированию данных в Cassandra, мы должны определить шаблоны запросов и убедиться, что они соответствуют следующим рекомендациям:

  1. Каждый запрос должен извлекать данные из одного раздела
  2. Мы должны отслеживать, сколько данных хранится в разделе, поскольку у Cassandra есть ограничения на количество столбцов, которые могут храниться в одном разделе.
  3. Можно денормализировать и дублировать данные для поддержки различных типов шаблонов запросов к одним и тем же данным.

Основываясь на приведенных выше рекомендациях, давайте рассмотрим некоторые реальные варианты использования и то, как мы будем моделировать для них модели данных Cassandra.

5. Примеры моделирования данных реального мира

5.1. Сообщения в Facebook

Предположим, что мы храним посты Facebook разных пользователей в Cassandra. Одним из распространенных шаблонов запросов будет получение первых « N » сообщений, сделанных данным пользователем.

Таким образом, нам нужно хранить все данные для конкретного пользователя в одном разделе в соответствии с приведенными выше рекомендациями.

Кроме того, использование временной метки сообщения в качестве ключа кластеризации будет полезно для более эффективного извлечения первых « N » сообщений.

Давайте определим схему таблицы Cassandra для этого варианта использования:

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);

Теперь давайте напишем запрос, чтобы найти 20 лучших сообщений пользователя Анны :

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

5.2. Спортзалы по всей стране

Предположим, что мы храним информацию о различных партнерских тренажерных залах в разных городах и штатах многих стран, и мы хотели бы получить спортивные залы для данного города.

Кроме того, допустим, нам нужно вернуть результаты, отсортировав спортивные залы по дате их открытия.

Основываясь на приведенных выше рекомендациях, мы должны хранить спортзалы, расположенные в данном городе определенного штата и страны, в одном разделе и использовать дату открытия и название спортзала в качестве ключа кластеризации.

Давайте определим схему таблицы Cassandra для этого примера:

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);

Теперь давайте посмотрим на запрос, который извлекает первые десять спортивных залов по дате их открытия для города Феникс в американском штате Аризона:

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

Далее давайте посмотрим на запрос, который извлекает десять недавно открытых спортивных залов в городе Феникс в американском штате Аризона:

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

Примечание. Поскольку порядок сортировки последнего запроса противоположен порядку сортировки, заданному при создании таблицы, запрос будет выполняться медленнее, поскольку Cassandra сначала извлекает данные, а затем сортирует их в памяти.

5.3. Клиенты и продукты электронной коммерции

Допустим, у нас есть магазин электронной коммерции и мы храним информацию о покупателе и продукте в Cassandra. Давайте рассмотрим некоторые распространенные шаблоны запросов для этого варианта использования:

  1. Получить информацию о клиенте
  2. Получить информацию о продукте
  3. Получить всех клиентов , которым нравится данный продукт
  4. Получить все продукты , которые нравятся данному клиенту

Мы начнем с использования отдельных таблиц для хранения информации о клиентах и продуктах . Однако нам нужно ввести достаточное количество денормализации для поддержки 3-го и 4-го запросов, показанных выше.

Для этого мы создадим еще две таблицы — « Customer_by_Product » и « Product_by_Customer ».

Давайте посмотрим на схему таблицы Cassandra для этого примера:

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));

Примечание. Чтобы поддерживать как запросы, недавно понравившиеся продукты данному клиенту, так и клиенты, которым недавно понравился данный продукт, мы использовали столбец « liked_on » в качестве ключа кластеризации.

Давайте посмотрим на запрос, чтобы найти десять Клиентов, которым последний раз нравился продукт « Пепси »:

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

И давайте посмотрим на запрос, который находит недавно понравившиеся товары (до десяти) от клиента по имени « Анна »:

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

6. Неэффективные шаблоны запросов

Из-за того, как Cassandra хранит данные, некоторые шаблоны запросов неэффективны, в том числе следующие:

  • Извлечение данных из нескольких разделов — для этого потребуется, чтобы координатор извлекал данные из нескольких узлов, временно сохранял их в куче, а затем агрегировал данные перед возвратом результатов пользователю.
  • Запросы на основе соединений — из-за своего распределенного характера Cassandra не поддерживает соединения таблиц в запросах так же, как это делает реляционная база данных, и в результате запросы с соединениями будут выполняться медленнее, а также могут привести к несогласованности и проблемам с доступностью.

7. Заключение

В этом руководстве мы рассмотрели несколько передовых методов моделирования данных в Cassandra.

Понимание основных концепций и предварительное определение шаблонов запросов необходимо для разработки правильной модели данных, обеспечивающей наилучшую производительность кластера Cassandra.