Как выбрать мой ключ Cassandra для правильной сортировки по умолчанию? - PullRequest
1 голос
/ 09 июля 2020

Моя таблица samples состоит из таких столбцов:

id : uuid
created : timestamp
device : ascii
reading : float

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

SELECT * FROM samples LIMIT 1024

Я также хотел бы иметь возможность эффективно извлекать самые последние n образцы для данного устройства :

SELECT * FROM samples WHERE device = 'abc' LIMIT 1024

Как должен ли я создать свой ключ раздела для достижения этой цели?

1 Ответ

1 голос
/ 10 июля 2020

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

SELECT * FROM samples LIMIT 1024

Для этого первого запроса самая большая проблема, которую я сразу вижу, заключается в том, что нет WHERE пункт. Это заставит Cassandra проверять каждый узел для построения набора результатов; определенно не хочу, чтобы это случилось. Но похоже, что вас больше всего заботят последние данные или данные по определенной c дате. Для этого нам нужно создать ключ раздела или «корзину» на основе компонента даты / времени.

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

Для этого важна мощность ваших данных. Вы выбираете 1024 лучших, так что часто бывает так много за один день? Или это больше недели? Сейчас я возьму «день» и добавлю столбец day_bucket.

CREATE TABLE samples_by_day (
  id uuid,
  created timestamp,
  device ascii,
  reading float,
  day_bucket bigint,
  PRIMARY KEY (day_bucket,created,id)
) WITH CLUSTERING ORDER BY (created DESC, id ASC);

Это определение первичного ключа будет разделять данные по дням (например: 20200710). Внутри этих разделов данные будут отсортированы по created в порядке убывания (чтобы самые свежие были наверху). Столбец id добавлен для обеспечения уникальности. Это будет поддерживать следующий запрос:

SELECT * FROM samples_by_day
WHERE day_bucket = 20200710 LIMIT 1024;

В течение нескольких дней вы можете выполнять несколько запросов. Вы можете даже «сегментировать» по неделям или месяцам, предполагая, что это не sh границы лимита в 2 миллиарда ячеек на раздел.

Поддержка этого запроса:

SELECT * FROM samples
WHERE device = 'abc' LIMIT 1024;

... намного проще.

CREATE TABLE samples_by_device (
  id uuid,
  created timestamp,
  device ascii,
  reading float,
  day_bucket bigint,
  PRIMARY KEY (device,created,id)
) WITH CLUSTERING ORDER BY (created DESC, id ASC);

Это работает, но, вероятно, столкнется с проблемой «несвязанного роста строк». В основном, если образцы устройств продолжают добавляться для каждого устройства, размер раздела в конечном итоге будет максимальным. Поэтому, вероятно, необходимо добавить day_bucket (или любой другой временной сегмент) в качестве дополнительного ключа раздела:

PRIMARY KEY ((device,day_bucket),created,id)

С этим изменением запрос также должен измениться:

SELECT * FROM samples_by_device
WHERE device = 'abc' AND day_bucket = 20200710 LIMIT 1024;
...