Выбор схемы хранения посекундных данных телеметрии (PostgreSQL/Django/Grafana) [закрыто]
Мое приложение каждую секунду получает пакеты телеметрии от оборудования в операционный центр. Каждый пакет идентифицируется фиксированным идентификатором SID, который определяет структуру данных, включая:
- SID 1: температура оборудования 1, 2, 3, 4
- SID 2: напряжение батарей 1, 2, 3
Решение Generic EAV уже реализовано и запущено в производство, но оно генерирует очень большой объем данных.
Переписывание уровня хранилища было бы очень дорогостоящим как при разработке, так и при обслуживании.
В Django я могу отображать последнее значение каждого параметра с точностью до наносекунды без проблем.
Однако в Grafana любая попытка создать историческую панель мониторинга (например, данные о температуре за один месяц) требует огромных ресурсов (процессор/память) для выполнения запросов.
Цели:
- Сохраняйте отображение последних значений в Django в режиме реального времени
- Позволяет эффективно строить временные ряды за несколько месяцев в Grafana без исчерпания ресурсов
Решение 1 - Универсальный EAV, находящийся в производстве:
В одной модели Django каждый параметр хранится в таблице
Entity–Attribute–Value
:# models.py class ParameterHK(models.Model): id = models.BigAutoField(primary_key=True, db_index=True) date_hk_reception = models.DateTimeField(auto_now_add=True, db_index=True) sid = models.IntegerField(db_index=True) equipment = models.CharField(max_length=500) label_parameter = models.CharField(max_length=500, db_index=True) unit = models.CharField(max_length=500) value = models.IntegerField() date_hk_obc = models.IntegerField()
По одной строке на параметр в секунду.
Отлично работает для запросов Django, но вызывает:
- огромное количество строк
- очень большие индексы
- ресурсоемкие запросы агрегации в Grafana
Решение: 2 широкие таблицы для каждого SID:
Создайте отдельную таблицу для каждого SID с одним столбцом на параметр. Пример для SID 1:
CREATE TABLE hk_sid1 ( ts TIMESTAMPTZ NOT NULL, equip1_temp INTEGER, equip2_temp INTEGER, equip3_temp INTEGER, equip4_temp INTEGER );
Прямое считывание каждого столбца временного ряда без сложной фильтрации.
Более высокая производительность чтения с помощью Grafana.
Недостатки: жесткая схема, требует миграции при изменении протокола и управления несколькими таблицами.
Каков дизайн для посекундного потока данных, хранящегося в течение нескольких месяцев, при сохранении решения 1 в рабочем состоянии из-за высокой стоимости полной перезаписи?
Решение 1 не требует перезаписи, но ограничено в производительности исторических запросов.
Решение 2 обеспечивает более быстрое считывание, но является дорогостоящим в разработке и обслуживании.
Какие альтернативы (секционирование, непрерывные агрегаты, понижающая выборка, политики автоматического хранения и т.д.) ограничивают использование ресурсов при сохранении гибкости?