Я тестирую Кассандру как базу данных временных рядов.
Я создаю модель данных, как показано ниже:
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 и немного запутался по поводу ключа раздела и ключа кластеризации.
Большая часть моего запроса будет выглядеть так:
У меня будет около 2000 deviceid, у каждого deviceid будет 60 пар tagid / value. Я не уверен, будут ли это широкие строки deviceid, timestamp, tagid / value, tagid / value ….
Я новичок в 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
через год).
Других решений пока нет …