масштабирование statsd с несколькими серверами

Я выкладываю архитектуру, в которой мы будем использовать statsd и графит. Я понимаю, как работает graphite и как один сервер statsd может общаться с ним. Мне интересно, как архитектура и настройка будут работать для масштабирования серверов statsd. У вас было бы несколько серверов StatsD узла, а затем один центральный сервер statsd, нажимающий на графит? Я не мог найти ничего о масштабировании statsd, и любые идеи о том, как иметь несколько серверов statsd были бы оцененный.

3 ответов


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

но есть несколько вариантов использования statsd в среде, которая должна масштабироваться:

  • используйте выборку на стороне клиента для метрик счетчика, как описано в документации statsd (т. е. вместо отправки каждого событие в statsd, отправить только каждое 10-е событие и сделать statsd умножить его на 10). Недостатком является то, что вам нужно вручную установить соответствующую частоту дискретизации для каждой из ваших метрик. Если вы выборите слишком мало значений, ваши результаты будут неточными. Если вы пробуете слишком много, вы убьете свой (одиночный) экземпляр statsd.

  • создайте пользовательский балансировщик нагрузки, который разбивает по имени метрики на разные statsds, тем самым обходя проблему разбитой агрегации. Каждый из них мог пишите непосредственно на графит.

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

  • изменение последней точки что я реализовал с большим успехом в производстве: используйте первый слой нескольких (в моем случае локальных) statsds, которые, в свою очередь, объединяются в один центральный statsd, который затем разговаривает с графитом. Первый слой statsds должен иметь гораздо меньшее время промывки, чем второй. Для этого вам понадобится бэкэнд statsd-to-statsd. Поскольку я столкнулся именно с этой проблемой, я написал тот, который пытается быть максимально эффективным в сети: https://github.com/juliusv/ne-statsd-backend

Как есть, statsd, к сожалению, не был разработан для масштабирования управляемым способом (нет, я не вижу настройки частоты дискретизации вручную как "управляемый"). Но обходные пути выше должны помочь, если вы застряли с ним.


большинство реализаций, которые я видел, использовали для метрик сервера, например:<env>.applications.<app>.<server>.<metric>

при таком подходе вы можете иметь локальные экземпляры statsd на каждом поле, выполнять работу UDP локально и позволить statsd публиковать свои агрегаты в graphite.

Если вам действительно не нужны показатели сервера, у вас есть два варианта:

  1. объединение связанных метрик в слое визуализации (например:путем настройки graphiti для этого)
  2. использование углерода агрегация в позаботьтесь об этом

Если у вас есть доступ к аппаратному балансировщику нагрузки, такому как F5 BigIP (я бы предположил, что есть программные реализации OSS, которые делают это), и у вас есть имя хоста каждого хоста в ваших метриках (т. е. вы подсчитываете такие вещи, как "appname.имя сервера.foo.бар.баз " и агрегирование их на уровне графита) вы можете использовать балансировку нагрузки сродства адресов источников - она отправляет весь трафик с одного адреса источника на один и тот же узел назначения (в пределах разумного тайм-аута). Итак, пока каждое имя метрики исходит только от одного исходного хоста, это позволит достичь желаемого результата.