Я новичок в 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
в год).
17.03.2016