Ключ раздела Cassandra для данных временных рядов

Я тестирую Кассандру как базу данных временных рядов.

Я создаю модель данных, как показано ниже:

CREATE KEYSPACE sm WITH replication = {
'class': 'SimpleStrategy',
'replication_factor': 1
};

USE sm;

CREATE TABLE newdata (timestamp timestamp,
deviceid int, tagid int,
decvalue decimal,
alphavalue text,
PRIMARY KEY (deviceid,tagid,timestamp));

В Первичном ключе я устанавливаю deviceid в качестве ключа раздела, что означает, что все данные с одинаковым идентификатором устройства будут записываться в один узел (означает ли это один компьютер или один раздел. Каждый раздел может иметь до 2 миллиардов строк), даже если я запрашиваю данные внутри тот же узел, поиск будет быстрым, я прав? Я новичок в Cassandra и немного запутался по поводу ключа раздела и ключа кластеризации.

Большая часть моего запроса будет выглядеть так:

  • выберите последнюю метку времени для идентификатора устройства и тега
  • Выберите десятичное значение известного deviceid, tagid и метку времени.
  • Выберите буквенное значение известного deviceid, tagid и метку времени
  • выберите * из известного deviceid и tagid с диапазоном времени
  • выберите * известного устройства с временным диапазоном

У меня будет около 2000 deviceid, у каждого deviceid будет 60 пар tagid / value. Я не уверен, будут ли это широкие строки deviceid, timestamp, tagid / value, tagid / value ….

3

Решение

Я новичок в Cassandra и немного запутался по поводу ключа раздела и ключа кластеризации.

Похоже, вы понимаете ключи разделов, поэтому я просто добавлю, что ваш ключ раздела помогает Cassandra выяснить, где (какой диапазон токенов) в кластере хранить ваши данные. Каждый узел отвечает за несколько основных диапазонов токенов (при условии vnodes). Когда ваши данные записываются в раздел данных, они сортируются по ключам кластеризации. Это также, как он хранится на диске, поэтому помните, что ваши ключи кластеризации определяют порядок, в котором ваши данные хранятся на диске.

Каждый раздел может иметь до 2 миллиардов строк

Это не совсем так. Каждый раздел может поддерживать до 2 миллиардов ячейки. Ячейка по сути является парой имя / значение столбца. И ваши ключи кластеризации складываются в одну ячейку сами по себе. Поэтому вычислите ваши ячейки, посчитав значения столбцов, которые вы сохраняете для каждой строки CQL, и добавьте еще одно, если вы используете кластерные столбцы.

В зависимости от вашей широкой структуры строк, вы, вероятно, будете иметь ограничение намного меньше, чем 2 миллиарда строк. Кроме того, это всего лишь ограничение хранения. Даже если вам удастся сохранить 1 миллион строк CQL в одном разделе, запрос этого раздела вернет столько данных, что это будет неуклюжим и, вероятно, истечет время ожидания.

если я сделаю запрос данных в том же узле, поиск будет быстрым, я прав?

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

Большая часть моего запроса будет выглядеть так:

select lastest timestamp of know deviceid and tagid
Select decvalue of known deviceid and tagid and timestamp
Select alphavalue of known deviceid and tagid and timestamp
select * of know deviceid and tagid with time range
select * of known deviceid with time range

Ваша текущая модель данных может поддерживать все эти запросы, кроме последнего. Для того, чтобы выполнить запрос диапазона на timestampвам нужно будет скопировать ваши данные в новую таблицу и создать ПЕРВИЧНЫЙ КЛЮЧ для поддержки этого шаблона запроса. Это называется «моделирование на основе запросов». Я хотел бы построить таблицу запросов следующим образом:

CREATE TABLE newdata_by_deviceid_and_time (
timestamp timestamp,
deviceid int,
tagid int,
decvalue decimal,
alphavalue text,
PRIMARY KEY (deviceid,timestamp));

Эта таблица может поддерживать запрос диапазона timestampпри разделении на deviceid,

Но самая большая проблема, которую я вижу с любой из этих моделей, заключается в «неограниченном росте строк». По сути, по мере того, как вы собираете все больше и больше значений для своих устройств, вы приближаетесь к пределу в 2 миллиарда ячеек на раздел (и снова, вероятно, до этого дела пойдут медленнее). Что вам нужно сделать, это использовать технику моделирования под названием «ведение времени».

В качестве примера скажу, что я определил, что распределение по месяцам будет держать меня под пределом в 2 миллиарда ячеек. а также учесть тот тип гибкости диапазона дат, который мне был нужен. Если это так, я бы добавил дополнительный ключ раздела monthbucket и моя (новая) таблица будет выглядеть так:

CREATE TABLE newdata_by_deviceid_and_time (
timestamp timestamp,
deviceid int,
tagid int,
decvalue decimal,
alphavalue text,
monthbucket text,
PRIMARY KEY ((deviceid,monthbucket),timestamp));

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

SELECT * FROM newdata_by_deviceid_and_time
WHERE deviceid='AA23' AND monthbucket='201603'
AND timestamp >= '2016-03-01 00:00:00-0500'
AND timestamp < '2016-03-16 00:00:00-0500';

Помните, monthbucket это просто пример. Для вас может иметь смысл использовать квартал или даже год (при условии, что вы не храните слишком много значений за deviceid через год).

8

Другие решения

Других решений пока нет …