Кассандра Data моделирования IoT лучшие практики - PullRequest
0 голосов
/ 15 ноября 2018

Я довольно новичок в Кассандре и пытаюсь понять, как спроектировать мои таблицы для датчиков IoT.

Идея состоит в том, чтобы иметь несколько устройств, каждое из которых подключено к нескольким датчикам, которые периодически отправляют данные (до 200000 значений на устройство в день на датчик)

Я бы хотел иметь возможность запросить последнее значение датчика для определенного списка датчиков и устройств в более или менее реальном времени. Также устройства не всегда отправляют данные и могут быть недоступны в течение длительных периодов времени.

После долгих чтений я придумал что-то вроде этого

CREATE TABLE "sensor_data" (
    deviceid TEXT,
    sensorid TEXT,
    ts timestamp,
    value TEXT,
    PRIMARY KEY ((deviceid, sensorid), ts)
) WITH CLUSTERING ORDER BY (ts DESC);

Идея заключается в том, чтобы выполнить один запрос на устройство и датчик, например

Select deviceid, sensorid, ts, value where deviceid = "device1" and sensorid = "temperature" limit 1

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

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

Я думаю, что, возможно, было бы хорошей идеей добавить что-то вроде даты в таблицу (как это видно в некоторых блогах и руководствах)

CREATE TABLE "sensor_data" (
    deviceid TEXT,
    sensorid TEXT,
    date TEXT
    ts timestamp,
    value TEXT,
    PRIMARY KEY ((deviceid, sensorid, date), ts)
) WITH CLUSTERING ORDER BY (ts DESC);

А затем запрос как

Select deviceid, sensorid, date, ts, value where deviceid = "device1" and sensorid = "temperature" and date = "2018-11-14" limit 1

Это вообще имеет смысл? Такое ощущение, что это может смягчить проблемы с хранилищем и упростить архивирование старых данных в будущем, однако, как мне поступить, запрашивая последнее значение для конкретного датчика и устройства, если это устройство не работало в течение дня или более? Действительно ли мне нужно запросить за 1 день, если ничего не найдено, запросить за предыдущий день и т. Д. (Возможно, ограничить его только последними несколькими днями или около того)?

Есть ли лучшие способы справиться с этим на Кассандре или я в правильном направлении?

1 Ответ

0 голосов
/ 16 ноября 2018

Частично проблема, с которой вы столкнетесь, состоит в том, что каждый датчик будет иметь 200 тыс. Показаний в день.Как правило, вы хотите, чтобы каждый раздел находился под 100k строк .Итак, у вашей второй идеи (имеющей дату как часть PK) могут быть проблемы с перфектом.

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

Чтобы по-настоящему помочь с этим, нам понадобится немного больше информации:

  • Сколько у вас устройств?Будет ли это число расти или оно будет конечным?
  • На простом английском языке, каков пример запросов, на которые вы пытаетесь ответить?

Включение этого в основанный на ответена ваши ответы (ниже):

Хорошо, вот потенциальная идея ...

Мы ДЕЙСТВИТЕЛЬНО заботимся о группировании, хотя стараемся держаться вокруг оптимальных строк 100k / разбиения враздел.

Вам понадобятся две таблицы:

  1. Таблица поиска
  2. Таблица датчиков

Таблица поиска будет выглядетьчто-то вроде:

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);
  1. Поскольку каждый датчик получит 200kЧтения / день И мы хотим, чтобы каждый раздел занимал менее 100 тыс. строк, что означает, что мы хотим делать два раздела для каждого датчика каждый день
  2. Как бы вы могли выделить данные?Вы должны сделать это в двух частях: вам нужно ежедневно делать ведро;каждый датчик получает новый раздел каждый день (reading_date) и делит каждый день на два (из-за ожидаемого количества показаний);До или после полудня;AM равняется интервалу 1, PM равняется интервалу 2. Или используйте 24-часовое время, когда 0-1200 равняется 1, 1300-2399 равняется 2
  3. В пределах вашего приложения укажите конкретные sensorid и time_bucket извремя, когда вы фактически запрашиваете запрос (например, если время составляет 1135 часов, то time_bucket = 1) и reading_date придет с фактического дня, когда вы запрашиваете
  4. , поскольку вы кластеризуете с ts DESCтогда он получит последнее чтение для данного sensorid.Таким образом, это выглядело бы как SELECT * from sensor_data WHERE reading_date = 12/31/2017 AND sensorid = 1234 AND time_bucket = 1 LIMIT 1;
  5. Поддерживая 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) - отличный курс!

...