Предлагаю на примере Apache Kafka рассмотреть, какие есть подводные камни при сборе и использовании метрик. Не пугайтесь, если вы не знакомы с Kafka — эти идеи могут всплыть при мониторинге абсолютно любой системы.

Для справки скажу, что ZooKeeper (если вы еще от него ушли) и брокеры Kafka по умолчанию репортят длинный список метрик через JMX (Java Management Extensions), но также можно подключать собственные репортеры (обычный java-класс), изменяя настройку metrics.reporter из конфигурации.

1. Сетевая нагрузка

При использовании JMX и Prometheus JMX Exporter для сбора метрик Kafka стоит помнить, что каждая метрика запрашивается отдельным сетевым запросом. Обычно это не доставляет проблем, но если для вас остро стоит вопрос утилизации ресурсов, то этой хороший поинт, чтобы провести НТ и выполнить оптимизацию (подключив, например, собственный репортер метрик).

2. Агрегации

2.1. Узнайте используемый алгоритм

Стоит сказать, что для каждой из метрик Kafka обычно есть несколько вариантов ее агрегации.

для метрики BytesInPerSec, например, есть шесть вариантов ее агрегации

для метрики BytesInPerSec, например, есть шесть вариантов ее агрегации

Показатель Count – монотонно возрастающая последовательность. Здесь все предельно просто.

Показатели с постфиксом Rate рассчитываются, как экспоненциально взвешенная скользящая средняя (EWMA), а не как отношение разницы конечного и начального значений к указанному промежутку времени, приведенное к секундам.

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

Также вы можете найти такие варианты агрегаций для метрики:

Count аналогично предыдущему – монотонно возрастающая последовательность. Как рассчитываются остальные агрегации? Kafka рассчитана на обработку большого числа запросов в короткие промежутки времени. Это означает, что считать перцентили, используя сырые данные было бы очень накладно. Поэтому используется сэмплирование, а именно алгоритм EDR (exponentially decaying reservoir), что, как несложно догадаться, снижает точность. При использовании агрегаций с постфиксом Percentile вы можете столкнуться с, на первый взгляд, странным поведением, когда значение метрики (как, например, размер запроса на скрине ниже) остается постоянной в течение продолжительного времени:

Это связано с тем, что текущее значение высчитывается на основе исторических данных даже в случае, когда новые значения не попадают в EDR.

2.2. Атомарность

Kafka под капотом использует библиотеку yammer-metrics для целей откидывания метрик. Каждая из метрик (Count, *Rate и *Percentile) выставляется независимо (к сожалению, оригинальный репозиторий с примером недоступен, но мы можем посмотреть на код библиотеки преемника здесь и здесь). Это свидетельствует об отсутствии атомарности сбора логически связанных данных, поэтому значения по ним в одном ответе от jmx exporter могут не сойтись.

Здесь стоит обратить внимание на более серьезную проблему: снимок EDR создается для получения каждого агрегата, что может сильно ударить по производительности.

Вывод