Оптимизация запросов¶
Запросы — узкое горлышко дашборда. Медленный запрос → дашборд тормозит → человек теряет терпение и уходит. Оптимизация запросов — инвестиция в надёжность себя самого в 3 часа ночи.
Prometheus / PromQL¶
- Всегда фильтруйте.
{job="api"}вместо гологоhttp_requests_total. - Избегайте кардинальности.
by (user_id)с миллионами уникальных id — смерть Prometheus'у. Используйтеtopk(5, ...). - Используйте Recording Rules для больших досок. Вместо сложного запроса
histogram_quantile(0.99, rate(...))предвычислите через recording rule:- record: job:api:latency_99pctи полегчает. - Не используйте
offsetбез крайней нужды. Этот оператор виртуально удваивает запросы. - Не ставьте неограниченные диапазоны.
$__range— полезно, но для большого окна в 7 дней это может означать "покажи мне всё". Prometheus это не пережуёт. Ограничь верхним пределом.
Loki / LogQL¶
- Label filters first. Loki индексирует метки, а не содержимое. Поэтому
{job="api"} |= "error"— быстро, а|= "error"— медленно. - json | line_format. Разбирайте JSON внутри логов — так вы получаете поля и к ним можно применять фильтры без regexp.
- Время имеет значение.
{job="api"}запрос на временной диапазон 5 минут — ок, на 7 дней без агрегации — не делайте.
SQL-базы¶
- Используйте временные индексы. Убедитесь, что
created_atилиtimestamp— проиндексированы в БД. Иначе каждый запрос дашборда — full scan таблицы. - Макросы времени Grafana.
$__timeFilter(created_at)— автоматически подставляет WHERE по времени. - Лимитируйте количество записей.
LIMIT 1000— дашборда с 10 000 строками смотреть неудобно.
Макросы и шаблоны времени¶
Всегда используйте:
$__timeFilter(...)
$__interval
$__rate_interval
Они подстраиваются под zoom и разрешение вашего дисплея. Например, $__interval будет 30s при просмотре 1h и может стать 5m при просмотре 1 week — Grafana сама подстраивает, чтобы поместилось в разрешение экрана. Не пишите фиксированное [5m].
Практический пример¶
Плохо:
rate(node_network_transmit_bytes_total{device!="lo"}[5m])
Хорошо:
rate(node_network_transmit_bytes_total{device!~"lo|docker.*|veth.*"}[$__rate_interval])
Далее: Стандартизация