Частично проблема, с которой вы столкнетесь, состоит в том, что каждый датчик будет иметь 200 тыс. Показаний в день.Как правило, вы хотите, чтобы каждый раздел находился под 100k строк .Итак, у вашей второй идеи (имеющей дату как часть PK) могут быть проблемы с перфектом.
На самом деле то, что вы хотите сделать, это то, что мы называем «группированием»;как сгруппировать вещи так, чтобы запросы были полезны и производительны.
Чтобы по-настоящему помочь с этим, нам понадобится немного больше информации:
- Сколько у вас устройств?Будет ли это число расти или оно будет конечным?
- На простом английском языке, каков пример запросов, на которые вы пытаетесь ответить?
Включение этого в основанный на ответена ваши ответы (ниже):
Хорошо, вот потенциальная идея ...
Мы ДЕЙСТВИТЕЛЬНО заботимся о группировании, хотя стараемся держаться вокруг оптимальных строк 100k / разбиения враздел.
Вам понадобятся две таблицы:
- Таблица поиска
- Таблица датчиков
Таблица поиска будет выглядетьчто-то вроде:
CREATE TABLE lookup-table (
deviceid TEXT,
sensor-map MAP,
PRIMARY KEY (deviceid)
);
deviceid
- это уникальный идентификатор для каждого устройства sensor-map
- это JSON карта датчиков данного устройстваимеет и соответствующий уникальный идентификатор для этого конкретного датчика (например, {температура: 183439, влажность: 84543292, другой датчик: бла}) - Таким образом, каждое устройство имеет сопоставление датчиков, доступных для него
- Примером запроса будет:
SELECT * FROM lookup-table WHERE deviceid = 1234;
- Другой подход заключается вдве колонки для каждого типа датчика и уникальный идентификатор для каждого датчика в виде значения
Таблица датчиков будет выглядеть следующим образом:
CREATE TABLE sensor_data (
sensorid TEXT,
sensor_value (whatever data type fits what you need),
ts TIMESTAMP,
reading_date date,
time_bucket int,
PRIMARY KEY ((reading_date, sensorid, time_bucket), ts)
) WITH CLUSTERING ORDER BY (ts DESC);
- Поскольку каждый датчик получит 200kЧтения / день И мы хотим, чтобы каждый раздел занимал менее 100 тыс. строк, что означает, что мы хотим делать два раздела для каждого датчика каждый день
- Как бы вы могли выделить данные?Вы должны сделать это в двух частях: вам нужно ежедневно делать ведро;каждый датчик получает новый раздел каждый день (
reading_date
) и делит каждый день на два (из-за ожидаемого количества показаний);До или после полудня;AM равняется интервалу 1, PM равняется интервалу 2. Или используйте 24-часовое время, когда 0-1200 равняется 1, 1300-2399 равняется 2 - В пределах вашего приложения укажите конкретные
sensorid
и time_bucket
извремя, когда вы фактически запрашиваете запрос (например, если время составляет 1135 часов, то time_bucket = 1
) и reading_date
придет с фактического дня, когда вы запрашиваете - , поскольку вы кластеризуете с
ts DESC
тогда он получит последнее чтение для данного sensorid
.Таким образом, это выглядело бы как SELECT * from sensor_data WHERE reading_date = 12/31/2017 AND sensorid = 1234 AND time_bucket = 1 LIMIT 1;
- Поддерживая
ts
в качестве столбца кластеризации, вы сможете сохранить все показания для данного датчика;Ни один из них не будет перезаписан
Важно знать : это прекрасно работает, если равномерное распределение показаний датчиков в течение 24-часового дня.Однако, если вы интенсивно читаете по утрам, а не по вечерам, то это не чётко, и нам придётся придумать другой путь к ведру.Но я думаю, что вы понимаете, что происходит.
На запрос:
- Будет один запрос для получения всех
sensorid
, которые есть у устройства;если у вас есть эти sensorid
, вы можете использовать их для следующего шага - Будет n запросов для каждого
sensor_value
для каждого sensorid
- Поскольку мы собираем данные (через
time_bucket
), у вас должно быть равномерное распределение по всем разделам
Наконец: дайте мне самую последнюю sensorid
на заданное значение Для этого есть несколько способов ...
- Запустить задание Spark: для этого вам нужно будет поднять и сдвинуть данные, чтобы выполнить запрос Spark
- Использование DataStax Enterprise: с DSE у вас есть интегрированный компонент Analytics на основе Spark, поэтому вы можете запускать задания Spark без необходимости управления отдельным кластером Spark.Раскрытие информации: я работаю там, кстати
- Создайте дополнительную таблицу Cassandra (C *) и выполните несколько параллельных записей
Для дополнительной таблицы C *:
CREATE TABLE sensor_by_value (
sensor-value INT,
ts TIMESTAMP,
sensorid TEXT,
reading_date DATE,
time_bucket INT,
PRIMARY KEY ((sensor-value, reading_date), ts)
) WITH CLUSTERING ORDER BY (ts DESC);
Вам определенно придется сделать некоторое времяздесь:
- Помните, нам не нужно больше 100 000 строк на раздел
- Вам нужно понять возможные значения (диапазон)
- Частота каждого чтения
- Если у вас есть 100 устройств, 100 датчиков, и каждый датчик считывает до 200 КБ в день, то у вас есть потенциал для показаний датчиков до 2 В в день ...
- Как правило, мои клиенты проводят анализ своих данных, чтобы понять эти биты информации, так что вы можете быть уверены, что учли их
- От того, сколько у вас есть корзины, будет зависетьчастота
- Удачи!: -)
Окончательный совет
Рассмотрим стратегии сжатия: в частности стратегия сжатия во временном окне (TWCS) и добавление default_time_to_live
Ваши данные кажутся неизменными после начальной вставки
TWCS значительно сократит эксплуатационные накладные расходы на сжатие, поскольку вы настраиваете их длянеобходимое вам временное окно
A default_ttl
также поможет с операционными накладными расходами на удаление данных, когда они вам больше не нужны.
Отвечает ли это и / или удовлетворяет те запросы, на которые вы пытаетесь ответить?Если нет, дайте мне знать, и мы сможем повторить.
Чтобы узнать все это, перейдите в DataStax Academy и получите массу бесплатного обучения.Моделирование данных (DS 220) - отличный курс!