Я только начинаю узнавать о Cassandra
и углубляться, чтобы понять, что происходит за кулисами, что делает Кассандру слишком быстрой. Я просматриваю следующие docs1 и docs2, но все еще не могу выбрать правильный ключ раздела для моей таблицы.
Я разрабатываю модель для тестового приложения, такого как Slack, и создаю таблицу message
, например:
CREATE TABLE messages (
id uuid,
work_space_id text,
user_id text,
channel_id text,
body text,
edited boolean,
deleted boolean,
year text,
created_at TIMESTAMP,
PRIMARY KEY (..................)
);
Мой запрос состоит в том, чтобы получить все сообщения с помощью channel_id
и work_space_id
. Итак, на мой взгляд, следующие варианты выбора первичного ключа:
PRIMARY KEY ((work_space_id, year), channel_id, created_at)
PRIMARY KEY ((channel_id, work_space_id), created_at)
Если я выберу вариант 1, то каждое рабочее пространство будет иметь отдельный раздел на год. Это может создать Hotspot
, если в одном рабочем пространстве 100 миллионов сообщений, а в другом несколько сотен в год.
Если я выберу вариант 2, то каждый канал рабочей области будет иметь отдельный раздел. Что, если есть 1 миллион рабочих мест и каждое из них имеет 1000 каналов. Это создаст около 1B разделов. Я знаю, что лимит составляет 2 миллиарда.
Так как же выбрать правильный ключ раздела, который будет равномерно распределять данные и не создавать hotspots
в центре обработки данных?
Основное правило моделирования данных для Cassandra заключается в том, что вы должны создать таблицу для каждого запроса приложения. В вашем случае запрос приложения должен получить все сообщения на основе идентификаторов рабочей области и канала.
Две важные вещи из вашего запроса приложения, которые должны вам помочь:
Фильтр определяет ключ раздела для таблицы, который равен (workspace_id, channel_id)
, и поскольку каждый раздел содержит строки сообщений, мы будем использовать столбец created_at
в качестве ключа кластеризации, чтобы его можно было отсортировать в убывающем хронологическом порядке, поэтому мы имеем:
CREATE TABLE messages_by_workspace_channel_ids (
workspace_id text,
channel_id text,
created_at timestamp,
user_id text,
body text,
edited boolean,
deleted boolean,
PRIMARY KEY ((workspace_id, channel_id), created_at)
) WITH CLUSTERING ORDER BY (created_at DESC)
Обычно мы бы остановились на этом, но, как вы правильно заметили, каждый канал потенциально может иметь миллионы сообщений, что привело бы к очень большим разделам. Чтобы избежать этого, нам нужно сгруппировать сообщения в «сегменты», чтобы сделать разделы меньше.
Вы пытались сделать это, сгруппировав сообщения по годам, но этого может быть недостаточно. Общая рекомендация состоит в том, чтобы сохранить разделы размером до 100 МБ для оптимальной производительности — меньшие разделы быстрее читаются. Мы можем сделать разделы меньше, также сгруппировав их по месяцам:
CREATE TABLE messages_by_workspace_channel_ids_yearmonth (
workspace_id text,
channel_id text,
year int,
month int,
created_at timestamp,
...
PRIMARY KEY ((workspace_id, channel_id, year, month), created_at)
) WITH CLUSTERING ORDER BY (created_at DESC)
Вы можете сделать их еще меньше, сгруппировав их по датам:
CREATE TABLE messages_by_workspace_channel_ids_createdate (
workspace_id text,
channel_id text,
createdate date,
created_at timestamp,
...
PRIMARY KEY ((workspace_id, channel_id, createdate), created_at)
) WITH CLUSTERING ORDER BY (created_at DESC)
Чем больше «сегментов» вы используете, тем больше разделов у вас будет в таблице, что идеально, поскольку большее количество разделов означает большее распределение данных по кластеру. Ваше здоровье!
👉 Пожалуйста, поддержите сообщество Apache Cassandra, наведя указатель мыши на тег cassandra и нажав кнопку Watch tag
. 🙏 Спасибо!
Эрик сначала спасибо за это большое объяснение. Как вы упомянули group the messages into buckets
от months
или createdate
. Таким образом мы достигаем цели меньших разделов, но я все еще не понимаю равномерного распределения данных. Допустим, мы делаем разделы на основе createdate
, в худшем случае, если канал получил 1 миллион сообщений в тот же день и несколько сотен в другой день. Он не создает hotspot
для раздела этого дня?
Чтобы я знал, что мы говорим об одном и том же, как бы вы описали/охарактеризовали «горячую точку»? 🙂
Насколько я знаю, точка доступа создается, когда один раздел получает много запросов на чтение и запись для ключа раздела. Давайте поправим меня, если я ошибаюсь!🙂
Существует ограничение в 2 миллиарда ячеек в разделе, но не ограничение в 2 миллиарда разделов.