в debian, monitoring, mysql, prometheus, scripts

Знакомство с Prometheus. Часть 2: сбор метрик от MySQL-сервера

prometheus
В предыдущей части цикла знакомства с Prometheus мы успешно установили и выполнили базовую настройку системы мониторинга, теперь давайте разберемся со сбором и экспортом метрик от MySQL-сервера с помощью компонента MySQL Server Exporter.

Устанавливаем компонент mysqld_exporter:

cd /opt
git clone https://github.com/prometheus/mysqld_exporter.git
cd mysqld_exporter
make

В дальнейших инструкциях разработчики предлагают запускать mysqld_exporter так:

export DATA_SOURCE_NAME="login:password@(hostname:port)/dbname"
./mysqld_exporter 

или создать скрипт-обертку run_mysqld_exporter.sh с таким содержимым:

#!/bin/bash

export DATA_SOURCE_NAME=“dbuser:dbpassword@tcp(dbserver:3306)/dbname”; ./mysqld_exporter</pre>

Примечание. Подробнее о формате переменной DATA_SOURCE_NAME можно почитать тут.

Пользователь, определенный в переменной DATA_SOURCE_NAME, должен иметь права SUPER или REPLICATION CLIENT на базу данных MySQL, которую вы собираетесь мониторить. Лучше всего создать для этих целей нового пользователя следующим запросом:

GRANT REPLICATION CLIENT ON *.* TO prometheus@'%' IDENTIFIED BY '<ПАРОЛЬ>';

На мой взгляд, предлагаемые разработчиками варианты запуска компонента для сбора метрик не слишком удобны, поэтому копируем исполняемый файл mysqld_exporter в каталог /usr/sbin/:

cp mysqld_exporter /usr/sbin/

Создаем init-скрипт в каталоге /etc/init.d/:

touch /etc/init.d/mysqld_exporter

и делаем его исполняемым:

chmod +x /etc/init.d/mysqld_exporter

Содержимое скрипта будет следующим:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          mysqld-exporter
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

. /lib/lsb/init-functions

DESC=mysqld-exporter
NAME=mysqld-exporter
PIDFILE=/var/run/$NAME.pid
DAEMON=/usr/sbin/mysqld_exporter
SCRIPTNAME=/etc/init.d/$NAME

export DATA_SOURCE_NAME='prometheus:<ПАРОЛЬ>@(192.168.0.12:3306)/'

#
# Function that starts the daemon/service
#
do_start()
{
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
  || return 1
    start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON \
  || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    #   other if a failure occurred
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    # Wait for children to finish too if this is a daemon that forks
    # and if the daemon is only ever run from this initscript.
    # If the above conditions are not satisfied then add some other code
    # that waits for the process to drop all resources that could be
    # needed by services started subsequently.  A last resort is to
    # sleep for some time.
    start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
    [ "$?" = 2 ] && return 2
    # Many daemons don't delete their pidfiles when they exit.
    rm -f $PIDFILE
    return "$RETVAL"
}

case "$1" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
    do_start
    case "$?" in
  0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
  2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
  ;;
  stop)
    [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
    do_stop
    case "$?" in
  0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
  2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    esac
    ;;
  status)
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
    log_daemon_msg "Restarting $DESC" "$NAME"
    do_stop
    case "$?" in
      0|1)
  do_start
  case "$?" in
      0) log_end_msg 0 ;;
      1) log_end_msg 1 ;; # Old process is still running
      *) log_end_msg 1 ;; # Failed to start
  esac
  ;;
      *)
        # Failed to stop
  log_end_msg 1
  ;;
    esac
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
    exit 3
    ;;
esac

:

Теперь мы легко можем управлять (start|stop|status|restart|force-reload) компонентом mysqld_exporter для сбора метрик от MySQL-сервера. Запустим его:

/etc/init.d/mysqld_exporter start

Примечание. Не забудьте ввести свои значения переменной DATA_SOURCE_NAME.

После это требуется отредактировать конфигурационный файл /etc/prometheus/prometheus.yml, добавив в него:

...
- job_name: "mysql"
    honor_labels: true
    target_groups:
      - targets:
        - "localhost:9104"

и перезапустить Prometheus для применения изменений командой:

/etc/init.d/prometheus restart

Если все сделано правильно, то собранные метрики MySQL-сервера будут доступны из браузера по адресу http://[IP-адрес сервера]:9104/metrics, графики же можно строить по адресу http://[IP-адрес сервера]:9090/graph.

Большинство метрик, которые собирает mysqld_exporter имеют тип Counter — это означает, что значение метрики будет постоянно увеличиваться. Например, на графике метрика mysql_global_status_queries будет выглядеть так:
mysql_global_status_queries

Конечно же, есть смысл выводить не абсолютное значение метрики, а ее скорость изменения (rate of change). Например, скорость изменения данной метрики за последние 5 минут можно отобразить как rate(mysql_global_status_queries[5m]):
rate(mysql_global_status_queries[5m])

Вывести на графике 5 самых больших таблиц определенной базы данных можно так topk(5, sum(mysql_info_schema_table_size{schema='<ИМЯ_БД>'}) by (table)):
topk(5, sum(mysql_info_schema_table_size) by (table))

На этом все, со сбором метрик от MySQL-сервера в системе мониторинга Prometheus мы разобрались, осталось только определить важные метрики конкретно для вашего случая и следить за ними.

Добавить комментарий