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

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

1. обзор

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

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

В этой статье мы рассмотрим некоторые ключевые концепцииhow to approach data modeling in Cassandra.

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

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

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

Ключ раздела состоит из одного или нескольких полей данных и равенused by the partitioner to generate a token via hashing to distribute the data uniformly across a cluster.

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

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

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

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

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

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

  1. Каждый запрос должен извлекать данные из одного раздела

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

  3. Можно денормализовать и продублировать данные для поддержки различных типов шаблонов запросов для одних и тех же данных.

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

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

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

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

Таким образом,we need tostore all data for a particular user on a single partition в соответствии с приведенными выше рекомендациями.

Кроме того, использование метки времени публикации в качестве ключа кластеризации будет полезно для более эффективного извлечения самых популярных публикаций «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 самых популярных сообщений для пользователяAnna:

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. Клиенты и продукты электронной коммерции

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

  1. Получить информацию оCustomer

  2. Получить информацию оProduct

  3. Получить всехCustomers, которым нравится данныйProduct

  4. Получить всеProducts лайков для данногоCustomer

Мы начнем с использования отдельных таблиц для хранения информацииCustomer иProduct. Тем не менее, нам нужно ввести достаточное количество денормализации для поддержки 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» в качестве ключа кластеризации.

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

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

И давайте посмотрим на запрос, который находит продукты, которые недавно понравились (до десяти) от клиента с именем "Anna":

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

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

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

  • Fetching data from multiple partitions - для этого потребуется, чтобы координатор извлекал данные из нескольких узлов, временно сохранял их в куче, а затем агрегировал данные перед возвратом результатов пользователю

  • Join-based queries - из-за своей распределенной природы Cassandra не поддерживает объединения таблиц в запросах так же, как это делает реляционная база данных, и в результатеqueries withjoins will be slower and can also lead to inconsistency and availability issues

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

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

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