Миграция схемы данных PM
Описание
После добавления меток Labes
#1492 необходимо мигрировать схему данных для работы с ними. При необходимо учесть несколько моментов:
- Обратная совместимость с запросами. Т.е. запросы использующие
path
смогли бы продолжать работать с новой схемой - Хорошо было бы сразу учесть отсутствие значений - (#1357 (closed))
- Возможность обращения по меткам к значениям предыдущего периода для
На текущий момент метрики используются в следующих компонентах системы:
-
web
- вывод данных наweathermap
, Исторический отчёт -
card
- выводи последних значений в карточку оборудования -
nbi
-API
для запроса значений за интервал времени (не больше 3 часов)
Из них только исторический отчёт обращается к данным из предыдущих периодов.
Сложности
Для обратной совместимости есть несколько вариантов решения.
- Использовать запросы к полям во
view
:
- Для обратной совместимости с path во
view
для новых данных её можно транслировать из колонкиlabels
применив конструкциюif
:if(labels, [arrayFirst(x -> startsWith(x, 'chassis'), labels), arrayFirst(x -> startsWith(x, 'slot'), labels), arrayFirst(x -> startsWith(x, 'module'), labels), arrayFirst(x -> startsWith(x, 'port'), labels), arrayFirst(x -> startsWith(x, 'unit'), labels)], path)
as path` - Для доступа к старым данным (до появления
labels
) можно добавить колонкуlabels_path
и формировать её изpath
:if(labels, labels, [arrayStringConcat(['chassis', path[1]], '::'), arrayStringConcat(['slot', path[2]], '::'), arrayStringConcat(['module', path[3]], '::'), arrayStringConcat(['port', path[4]], '::')] as labels_path
- Модифицировать запросы на использование
OR
:path[3] == 'FastEthernet0/1' OR has(labels, 'port::FastEthernet0/1')
а для группировки использовать условие из пункта 2
Это позволит прозрачно мигрировать запросы к данным и не проводить конвертацию перед отправкой в базу.
Предложение
Исходя из описания предлогалось разбить схему на 2 части - raw
таблицы и view
Схема для таблицы raw
- date
- ts
- metric_type - LowCardinality(
String
) текстовое имяMetric Type
-
managed_object -
UInt64
bi_id
ManagedObject
, на который собиралась метрика -
object -
UInt64
-bi_id
объекта на который собиралась метрика -
labels -
Array(LowCardinality(String))
-
labels_n -
Nested (scope LowCardinality(String), value LowCardinality(String)
Полезно для удобства запросов раскладыватьpath
на компоненты (scope
иvalue
). Данную колонку можно формировать какmaterialized column
изlabels
- name
- value
- time_delta
- колонки со
значениями
- с выставленным значением по умолчанию -
PRIMARY KEY -
(managed_object, object, date)
-
ORDER BY -
(managed_object, object, date, arrayFirst(x -> startsWith(x, 'port'), labels))
Пример запроса на создание:
Схема для view
При создании view
значения тэгов раскладывают на отдельные столбцы, для столбцов с данными из запроса исключаются значения по умолчанию:
-
path
-if(labels, [arrayFirst(x -> startsWith(x, 'chassis'), labels), arrayFirst(x -> startsWith(x, 'slot'), labels), arrayFirst(x -> startsWith(x, 'module'), labels), arrayFirst(x -> startsWith(x, 'port'), labels), arrayFirst(x -> startsWith(x, 'unit'), labels)], path)
as path -
arrayFirst(x -> startsWith(x, 'port'), labels) AS ifname
- выделение отдельногоlabel
при запросе -
packets_in
-if(packets_in != 1844674407370955153, packets_in, NULL) AS packets_in
- фильтрацияпустых
значений
Вопросы
- Влияение
arrayFirst
на производительность запросов -
labels_n
работа с тэгами безscope