[PMM] #180 MySQL 데이터 모니터링 – Prometheus MySQL Exporter

MySQL 데이터 모니터링 – Prometheus MySQL Expoter



지난 포스팅까지 차근차근 따라온 독자분들이라면 이 시점 즈음해서 한 가지 원하는 기능이 있을 수 있다.

“MySQL 서버에 SQL을 질의한 결과를 Prometheus에 쌓는다면, 이를 Grafana에서 대시보드로 구성할 수 있지 않을까?”

충분히 가능하다.

다시 말해, MySQL에 적재되어 있는 테이블 데이터에 SELECT SQL을 질의한 결과를 Prometheus에 적재할 수 있다면, Grafana의 다양한 그래프를 이용해서 실시간 데이터 변경 추이를 시각적으로 조회 할 수 있다.

자 시작해보자.


010. Prometheus MySQL Exporter 소개
- prometheus-mysql-exporter(Github) : https://github.com/Braedon/prometheus-mysql-exporter

Prometheus MySQL Exporter Python언어로 개발된 툴이다. MySQL 데이터베이스에 미리 설정한 쿼리를 주기적으로 질의하고 이 결과값을 Prometheus gauge metric으로 추출한다.

Prometheus MySQL Exporter를 설치하기 위해서는 다음과 같은 Python 관련 패키지를 미리 설치해야 한다.

-       Python 3.X 설치 : Python으로 개발한 프로그램을 설치하기 위해 필요.
-       mysqlclient-python 설치 : Python MySQL 클라이언트로 MySQL에 접속하기 위해 필요.
-       Prometheus Python Client 설치 : Prometheus 연동을 위한 Python 클라이언트


020. Python 3.5.2 설치

prometheus-mysql-exporter 를 설치하기 위해서는 Python 3 버전이 미리 설치되어 있어야 한다. 허나 RHEL, CentOS 등의 범용 리눅스 6.X 버전에서는 Python 2.X 버전이 설치되어 있을 가능성이 크다. 그러므로 Python 3.X 버전을 추가로 설치해야 하며, 이때 2.X 버전은 삭제하지 않고 3.X 버전을 추가로 설치한다.(2.X버전을 3.X 버전으로 대체한다면 기존의 2.X 버전을 연동하는 프로그램에 영향이 있을 수 있다.)

먼저 pmmclient 호스트의 현재 Python의 버전을 확인한다. 다음과 같이 2.6 버전이 설치되어 있다.
1
2
[root@pmmclient ~]# python -V
Python 2.6.6
cs

Python 공식 다운로드 경로(앞서 명시)에서 Python-3.5.2.tgz(리눅스용 소스버전)을 다운로드 받아 /home/mysql/DBA/programs/PMM105/Client/ 디렉토리에 옮겨 둔다. 다음과 같이 설치한다. 설치 후, “python3.5 -V" 명령어를 실행하여 설치버전을 확인해본다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[root@pmmclient ~]# cd /home/mysql/DBA/programs/PMM105/client
[root@pmmclient client]# tar -xvzf Python-3.5.2.tgz
[root@pmmclient client]# cd Python-3.5.2
[root@pmmclient Python-3.5.2]# ./configure
............
config.status: creating Makefile.pre
config.status: creating Modules/Setup.config
config.status: creating Misc/python.pc
config.status: creating Misc/python-config.sh
config.status: creating Modules/ld_so_aix
config.status: creating pyconfig.h
creating Modules/Setup
creating Modules/Setup.local
creating Makefile
[root@pmmclient Python-3.5.2]# make
............
# Substitution happens here, as the completely-expanded BINDIR
# is not available in configure
sed -"s,@EXENAME@,/usr/local/bin/python3.5m," < ./Misc/python-config.in >python-config.py
# Replace makefile compat. variable references with shell script compat. ones;  ->
sed -'s,\$(\([A-Za-z0-9_]*\)),\$\{\1\},g' < Misc/python-config.sh >python-config
# On Darwin, always use the python version of the script, the shell
# version doesn't use the compiler customizations that are provided
# in python (_osx_support.py).
if test `uname -s` = Darwin; then \
                cp python-config.py python-config; \
        fi
[root@pmmclient Python-3.5.2]# make altinstall
............
Ignoring indexes: https://pypi.python.org/simple
Collecting setuptools
Collecting pip
Installing collected packages: setuptools, pip
Successfully installed pip-8.1.1 setuptools-20.10.1
[root@pmmclient Python-3.5.2]# python3.5 -V
Python 3.5.2
cs


Python 3.5가 설치된 경로를 다음과 같이 확인해 본다. 그리고 Python 3.5의 실행파일을 “python3” 이라는 이름의 파일로 심볼릭링크를 생성하여 명령어를 짧게 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@pmmclient Python-3.5.2]# ls -al /usr/local/bin/
합계 18900
drwxr-xr-x.  2 root root    4096 2016-11-17 14:58 .
drwxr-xr-x. 13 root root    4096 2016-06-10 11:59 ..
..............
-rwxr-xr-x   1 root root     241 2016-11-17 14:58 easy_install-3.5
-rwxr-xr-x   1 root root      99 2016-11-17 14:58 idle3.5
-rwxr-xr-x   1 root root     213 2016-11-17 14:58 pip3.5
-rwxr-xr-x   1 root root      84 2016-11-17 14:58 pydoc3.5
-rwxr-xr-x   2 root root 9630033 2016-11-17 14:58 python3.5
-rwxr-xr-x   2 root root 9630033 2016-11-17 14:58 python3.5m
-rwxr-xr-x   1 root root    3066 2016-11-17 14:58 python3.5m-config
-rwxr-xr-x   1 root root     236 2016-11-17 14:58 pyvenv-3.5
..............
[root@pmmclient Python-3.5.2]# ls -al /usr/local/lib/
합계 15480
drwxr-xr-x.  4 root root     4096 2016-11-17 14:58 .
drwxr-xr-x. 13 root root     4096 2016-06-10 11:59 ..
..............
-r-xr-xr-x   1 root root 15833504 2016-11-17 14:58 libpython3.5m.a
drwxr-xr-x   2 root root     4096 2016-11-17 14:58 pkgconfig
drwxr-xr-x  36 root root     4096 2016-11-17 14:58 python3.5
..............
[root@pmmclient Python-3.5.2]# ls -al /usr/local/include/
합계 12
drwxr-xr-x.  3 root root 4096 2016-11-17 14:58 .
drwxr-xr-x. 13 root root 4096 2016-06-10 11:59 ..
..............
drwxr-xr-x   2 root root 4096 2016-11-17 14:58 python3.5m
..............
[root@pmmclient Python-3.5.2]# python3.5 -V
Python 3.5.2
[root@pmmclient Python-3.5.2]# ln -s /usr/local/bin/python3.5 /usr/local/bin/python3
[root@pmmclient Python-3.5.2]# python3 -V
Python 3.5.2
cs



030. mysqlclient-python 설치
mysqlclient-python github에 접속하여 소스를 다운로드 받아 /home/mysql/DBA/programs/PMM105/Client/ 디렉토리로 옮겨 둔다. 다운로드받은 소스를 압축 해제 후, “python3 setup.py install” 명령어로 설치한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@pmmclient ~]# cd /home/mysql/DBA/programs/PMM105/client/
[root@pmmclient client]# unzip mysqlclient-python-master.zip
Archive:  mysqlclient-python-master.zip
4050c747e540cc8029e95bf416ec1cc697337b19
   creating: mysqlclient-python-master/
  inflating: mysqlclient-python-master/.gitignore
  inflating: mysqlclient-python-master/.travis.yml
...............
  inflating: mysqlclient-python-master/tests/test_MySQLdb_capabilities.py
  inflating: mysqlclient-python-master/tests/test_MySQLdb_dbapi20.py
  inflating: mysqlclient-python-master/tests/test_MySQLdb_nonstandard.py
  inflating: mysqlclient-python-master/tests/test_MySQLdb_times.py
  inflating: mysqlclient-python-master/tests/test_cursor.py
  inflating: mysqlclient-python-master/tests/travis.cnf
  inflating: mysqlclient-python-master/tox.ini
[root@pmmclient client]# cd mysqlclient-python-master
[root@pmmclient mysqlclient-python-master]# python3 setup.py install
running install
running bdist_egg
running egg_info
creating mysqlclient.egg-info
writing mysqlclient.egg-info/PKG-INFO
writing top-level names to mysqlclient.egg-info/top_level.txt
writing dependency_links to mysqlclient.egg-info/dependency_links.txt
writing manifest file 'mysqlclient.egg-info/SOURCES.txt'
............
Installed /usr/local/lib/python3.5/site-packages/mysqlclient-1.3.9-py3.5-linux-x86_64.egg
Processing dependencies for mysqlclient==1.3.9
Finished processing dependencies for mysqlclient==1.3.9
cs



040. Prometheus Python Client 설치
Prometheus Python Client github에 접속하여 소스를 다운로드 받아 /home/mysql/DBA/programs/PMM105/Client/ 디렉토리로 옮겨 둔다. 다운로드받은 소스를 압축 해제 후, “python3 setup.py install” 명령어로 설치한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@pmmclient ~]# cd /home/mysql/DBA/programs/PMM105/client/
[root@pmmclient client]# unzip client_python-master.zip
Archive:  client_python-master.zip
9cf02149af31fcf9e0e647433619ad97028e50e2
   creating: client_python-master/
  inflating: client_python-master/.coveragerc
  inflating: client_python-master/.gitignore
  inflating: client_python-master/.travis.yml
  inflating: client_python-master/AUTHORS.md
  inflating: client_python-master/CONTRIBUTING.md
  inflating: client_python-master/LICENSE
  inflating: client_python-master/NOTICE
  inflating: client_python-master/README.md
   creating: client_python-master/prometheus_client/
..............
  inflating: client_python-master/tox.ini
[root@pmmclient client]# cd client_python-master
[root@pmmclient client_python-master]# python3 setup.py install
/usr/local/lib/python3.5/distutils/dist.py:261: UserWarning: Unknown distribution option: 'extras_requires'
  warnings.warn(msg)
running install
running bdist_egg
running egg_info
creating prometheus_client.egg-info
writing dependency_links to prometheus_client.egg-info/dependency_links.txt
writing top-level names to prometheus_client.egg-info/top_level.txt
writing prometheus_client.egg-info/PKG-INFO
writing manifest file 'prometheus_client.egg-info/SOURCES.txt'
..............
Installed /usr/local/lib/python3.5/site-packages/prometheus_client-0.0.16-py3.5.egg
Processing dependencies for prometheus-client==0.0.16
Finished processing dependencies for prometheus-client==0.0.16
cs


Prometheus MySQL Exporter 설치를 위하여 미리 설치해야 하는 패키지를 모두 설치하였다. 단순히 압축 해제 후, 설치하는 것이므로 큰 문제없이 설치되었을 것이다.


050. Prometheus MySQL Exporter 설치

Prometheus MySQL Exporter를 설치할때에는 몇가지 수정해야 할 사항이 있다.
먼저, Prometheus MySQL Exporter github에 접속하여 소스를 다운로드 받아 /home/mysql/DBA/programs/PMM105/Client/ 디렉토리로 옮겨 둔다.

. 다운로드받은 소스를 압축 해제한다.
. ./prometheus-mysql-exporter-master/prometheus_mysql_exporter/__init__.py 파일을 수정한다.
. MySQL 연결 설정 부분에 “charset = ‘utf8’”, “use_unicode = True” 값을 추가한다.
. 추가한 옵션은 SELECT 결과의 한글깨짐을 방지하기 위하여 추가한 것이다.
. ./prometheus-mysql-exporter-master/ 디렉토리로 이동하여 “python3 setup.py install” 명령어를 실행하여 설치한다.
      라. “prometheus-mysql-exporter --help" 명령어를 실행하여 정상 실행되는지 확인한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
[root@pmmclient ~]# cd /home/mysql/DBA/programs/PMM105/client/
[root@pmmclient client]# unzip prometheus-mysql-exporter-master.zip
Archive:  prometheus-mysql-exporter-master.zip
7668d39742481bd91d60445a999ec98aeb185797
   creating: prometheus-mysql-exporter-master/
  inflating: prometheus-mysql-exporter-master/.gitignore
  inflating: prometheus-mysql-exporter-master/Dockerfile
  inflating: prometheus-mysql-exporter-master/LICENSE
  inflating: prometheus-mysql-exporter-master/MANIFEST.in
  inflating: prometheus-mysql-exporter-master/README.md
  inflating: prometheus-mysql-exporter-master/exporter.cfg
   creating: prometheus-mysql-exporter-master/prometheus_mysql_exporter/
  inflating: prometheus-mysql-exporter-master/prometheus_mysql_exporter/__init__.py
  inflating: prometheus-mysql-exporter-master/prometheus_mysql_exporter/__main__.py
  inflating: prometheus-mysql-exporter-master/prometheus_mysql_exporter/parser.py
  inflating: prometheus-mysql-exporter-master/setup.py
[root@pmmclient client]# cd ./prometheus-mysql-exporter-master/prometheus_mysql_exporter
[root@pmmclient prometheus_mysql_exporter]# vi __init__.py
.................
    for name, (interval, query, value_columns) in queries.items():
        mysql_client = MySQLdb.connect(
            host = mysql_host,
            port = mysql_port,
            user = username,
            passwd = password,
            autocommit = True,
            charset = 'utf8',
            use_unicode = True,
        )
        run_scheduler(scheduler, mysql_client, dbs, name, interval, query, value_columns)
    try:
        scheduler.run()
    except KeyboardInterrupt:
        pass
    logging.info('Shutting down')
[root@pmmclient prometheus_mysql_exporter]# cd /home/mysql/DBA/programs/PMM105/client/prometheus-mysql-exporter-master/
[root@pmmclient prometheus-mysql-exporter-master]# python3 setup.py install
running install
running bdist_egg
running egg_info
creating prometheus_mysql_exporter.egg-info
writing entry points to prometheus_mysql_exporter.egg-info/entry_points.txt
writing requirements to prometheus_mysql_exporter.egg-info/requires.txt
writing top-level names to prometheus_mysql_exporter.egg-info/top_level.txt
................
Using /usr/local/lib/python3.5/site-packages/prometheus_client-0.0.16-py3.5.egg
Searching for mysqlclient==1.3.9
Best match: mysqlclient 1.3.9
Processing mysqlclient-1.3.9-py3.5-linux-x86_64.egg
mysqlclient 1.3.9 is already the active version in easy-install.pth
Using /usr/local/lib/python3.5/site-packages/mysqlclient-1.3.9-py3.5-linux-x86_64.egg
Finished processing dependencies for prometheus-mysql-exporter==0.2.0.dev1
[root@pmmclient prometheus-mysql-exporter-master]# prometheus-mysql-exporter --help
usage: prometheus-mysql-exporter [-h] [-p PORT] [-c CONFIG_FILE]
                                 [-s MYSQL_SERVER] -d MYSQL_DATABASES
                                 [-u MYSQL_USER] [-P MYSQL_PASSWORD] [-v]
Export MySQL query results to Prometheus.
optional arguments:
  -h, --help            show this help message and exit
  -p PORT, --port PORT  port to serve the metrics endpoint on. (default: 8080)
  -c CONFIG_FILE, --config-file CONFIG_FILE
                        path to query config file. Can be absolute, or
                        relative to the current working directory. (default:
                        exporter.cfg)
  -s MYSQL_SERVER, --mysql-server MYSQL_SERVER
                        address of a MySQL server to run queries on. A port
                        can be provided if non-standard (3306) e.g. mysql:3333
                        (default: localhost)
  -d MYSQL_DATABASES, --mysql-databases MYSQL_DATABASES
                        databases to run queries on. Database names should be
                        separated by commas e.g. db1,db2.
  -u MYSQL_USER, --mysql-user MYSQL_USER
                        MySQL user to run queries as. (default: root)
  -P MYSQL_PASSWORD, --mysql-password MYSQL_PASSWORD
                        password for the MySQL user, if required. (default: no
                        password)
  -v, --verbose         turn on verbose logging.
cs


만일 /etc/ld.so.conf MySQL 라이브러리 경로가 추가되지 않았다면 다음과 같이 에러가 발생할 수 있다. 이 때에는 설치되어있는 MySQL서버의 라이브러리 경로를 해당 파일에 추가해주면 된다. (pmmclient 호스트는 MySQL 서버가 운영되고 있는 데이터베이스 서버이므로 MySQL 서버 관련 패키지는 이미 설치가 되어 있다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
--============================================================================
-- 다음과 같이 에러가 발생한다면, 
--  /etc/ld.so.conf 에 MySQL 라이브러리가 등록되었는지 확인하여 추가해준다.
--============================================================================
[root@pmmclient mysqlclient-1.3.9-py3.5-linux-x86_64.egg]# prometheus-mysql-exporter --help
Traceback (most recent call last):
  File "/usr/local/bin/prometheus-mysql-exporter", line 9, in <module>
    load_entry_point('prometheus-mysql-exporter==0.2.0.dev1''console_scripts''prometheus-mysql-exporter')()
  File "/usr/local/lib/python3.5/site-packages/pkg_resources/__init__.py", line 542, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/local/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2569, in load_entry_point
    return ep.load()
  File "/usr/local/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2229, in load
    return self.resolve()
  File "/usr/local/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2235, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/local/lib/python3.5/site-packages/prometheus_mysql_exporter-0.2.0.dev1-py3.5.egg/prometheus_mysql_exporter/__init__.py", line 7, in <module>
  File "/usr/local/lib/python3.5/site-packages/mysqlclient-1.3.9-py3.5-linux-x86_64.egg/MySQLdb/__init__.py", line 19, in <module>
    import _mysql
ImportError: libmysqlclient.so.18: cannot open shared object file: No such file or directory
[root@pmmclient constants]# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/lib64
[root@pmmclient constants]# echo /home/mysql/MySQL/lib >> /etc/ld.so.conf && ldconfig
[root@pmmclient constants]# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/lib64
/home/mysql/MySQL/lib
cs


여기까지, MySQL 서버의 데이터 모니터링을 위해 설치해야하는 모든 패키지는 설치를 완료하였다. 이제, Prometheus MySQL Exporter를 기동해야 하지만 Prometheus MySQL Exporter MySQL 서버에 접속하여 데이터를 추출하는 SQL이 유효해야(에러가 없어야) 정상기동한다. 그러므로 모니터링 해볼 테스트용 테이블을 생성하고 추출용 SQL을 먼저 확인한다.


055. 모니터링 데이터 생성

테스트 해볼 데이터는 5명의 후보자에 투표를 하는 단순한 시나리오로 진행한다.
- 데이터베이스 : votedb
- 테이블 : vote_candidate(후보), vote_hist(투표이력)
- 모니터링 내용(추출 SQL)
. vote_total - 후보별 현재 득표수 조회
. vote_5second - 최근 5초간 후보별 득표수 조회


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
mysql > show databases;
mysql > create database votedb;
--==============================================================================
-- 테이블 생성
--==============================================================================
mysql > use votedb;
mysql > create table vote_candidate
        (
              candidate_id    int           not null auto_increment
            , candidate_name  varchar(100)  not null
            , votes_cnt       bigint        not null
            , primary key(candidate_id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='후보';
mysql > create table vote_hist
        (
              vote_hist_seq   bigint        not null auto_increment
            , candidate_id    int           not null
            , vote_date       datetime      not null
            , primary key(vote_hist_seq)
            , key vote_hist_idx01(vote_date, candidate_id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='투표이력';
--==============================================================================
-- 후보데이터 입력
--==============================================================================
mysql > insert into vote_candidate(candidate_name) values('A후보');
mysql > insert into vote_candidate(candidate_name) values('B후보');
mysql > insert into vote_candidate(candidate_name) values('C후보');
mysql > insert into vote_candidate(candidate_name) values('D후보');
mysql > insert into vote_candidate(candidate_name) values('E후보');
mysql > select * from vote_candidate order by candidate_id;
+--------------+----------------+-----------+
| candidate_id | candidate_name | votes_cnt |
+--------------+----------------+-----------+
|            1 | A후보          |         0 |
|            2 | B후보          |         0 |
|            3 | C후보          |         0 |
|            4 | D후보          |         0 |
|            5 | E후보          |         0 |
+--------------+----------------+-----------+
5 rows in set (0.00 sec)
--==============================================================================
-- vote_total - 후보별 현재 득표수 조회
--==============================================================================
SELECT candidate_id, candidate_name, votes_cnt as cnt FROM votedb.vote_candidate;
+--------------+----------------+-----+
| candidate_id | candidate_name | cnt |
+--------------+----------------+-----+
|            1 | A후보          |   0 |
|            2 | B후보          |   0 |
|            3 | C후보          |   0 |
|            4 | D후보          |   0 |
|            5 | E후보          |   0 |
+--------------+----------------+-----+
--==============================================================================
-- vote_5second - 최근 5초간 후보별 득표수 조회
--==============================================================================
select
  vc.candidate_id, vc.candidate_name, ifnull(taba.cnt,0) as cnt
from votedb.vote_candidate vc
        left join
        (
            select candidate_id, count(*) as cnt
            from votedb.vote_hist
            where vote_date between date_add(now(), interval -5 second) and now()
            group by candidate_id
        ) taba on vc.candidate_id = taba.candidate_id;
+--------------+----------------+-----+
| candidate_id | candidate_name | cnt |
+--------------+----------------+-----+
|            1 | A후보          |   0 |
|            2 | B후보          |   0 |
|            3 | C후보          |   0 |
|            4 | D후보          |   0 |
|            5 | E후보          |   0 |
+--------------+----------------+-----+
cs


060. Prometheus MySQL Exporter 설정 및 기동
Prometheus MySQL Exporter에서 사용하는 MySQL 데이터 추출용 SQL은 별도의 쿼리 설정 파일로 설정한다. 이 파일을 “exporter.cfg”로 명명하고 별도의 디렉토리에 생성하여 다음과 같이 추출 SQL을 등록한다.

- [query_vote_total]
: 쿼리헤더. 반드시 “query_”로 시작해야 한다.
- QueryIntervalSecs = 5
: 쿼리 실행 주기()
- QueryStatement = SELECT candidate_id, candidate_name, votes_cnt as cnt FROM votedb.vote_candidate;
        : 데이터 추출용 쿼리, Like 연산자 등에서 ‘%’글자를 사용한다면 이스케이프 문자를 포함해야 한다.
- QueryValueColumns = cnt
    : 쿼리 결과값에 대한 컬럼명

다음의 스크립트를 참고하여 Prometheus MySQL Exporter 를 구동한다. 기본 포트는 8090이며 port 옵션을 추가하여 임의의 포트로도 설정할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[mysql@pmmclient ~]$ mkdir /data/pmm_client/prometheus-mysql-exporter
[mysql@pmmclient ~]$ mkdir /data/pmm_client/prometheus-mysql-exporter/3306/
[mysql@pmmclient ~]$ ln -/data/pmm_client/prometheus-mysql-exporter/3306 /home/mysql/prometheus-mysql-exporter_3306
[mysql@pmmclient ~]$ cd /home/mysql/prometheus-mysql-exporter_3306/
[mysql@pmmclient prometheus-mysql-exporter_3306]$ touch exporter.cfg
[mysql@pmmclient prometheus-mysql-exporter_3306]$ chmod 640 exporter.cfg
[mysql@pmmclient prometheus-mysql-exporter_3306]$ vi exporter.cfg
[query_vote_total]
QueryIntervalSecs = 5
QueryStatement = SELECT candidate_id, candidate_name, votes_cnt as cnt FROM votedb.vote_candidate;
QueryValueColumns = cnt
[query_vote_5second]
QueryIntervalSecs = 5
QueryStatement = select vc.candidate_id, vc.candidate_name, ifnull(taba.cnt,0) as cnt from votedb.vote_candidate vc left join (select candidate_id, count(*) as cnt from votedb.vote_hist where vote_date between date_add(now(), interval -5 second) and now() group by candidate_id) taba on vc.candidate_id = taba.candidate_id;
QueryValueColumns = cnt
[mysql@pmmclient prometheus-mysql-exporter_3306]$ cd /home/mysql/prometheus-mysql-exporter_3306/
[mysql@pmmclient prometheus-mysql-exporter_3306]$ nohup prometheus-mysql-exporter --port=8090 --mysql-server="127.0.0.1:3306" --mysql-user="pmmclient" --mysql-password="pmmclient2@" --mysql-databases="votedb" --config-file="/home/mysql/prometheus-mysql-exporter_3306/exporter.cfg" > /home/mysql/prometheus-mysql-exporter_3306/prometheus-mysql-exporter.log 2>&1 &
[mysql@pmmclient prometheus-mysql-exporter_3306]$ ps -ef | grep prometheus-mysql-exporter
[mysql@pmmclient prometheus-mysql-exporter_3306]$ cat /home/mysql/prometheus-mysql-exporter_3306/prometheus-mysql-exporter.log
nohup: ignoring input
[2016-11-17 17:20:50,000] root.INFO MainThread Starting server...
[2016-11-17 17:20:50,000] root.INFO MainThread Server started on port 8090
cs




만일 exporter.cfg 에 등록한 쿼리가 문법 오류등으로 에러가 발생한다면 해당 에러가 로깅이 되면서 Prometheus MySQL Exporter 프로세스는 기동하지 않음을 참고한다.

070. Prometheus 설정 파일 변경(클라이언트 추가)
pmmerver Prometheus 설정 파일에 “mysqlqueryresult” job_name을 추가하고 해당 클라이언트를 추가해준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
[pmm@pmmserver ~]$ cd prometheus
[pmm@pmmserver prometheus]$ vi prometheus.yml
# my global config
global:
  scrape_interval:     5s # By default, scrape targets every 15 seconds.
  evaluation_interval: 5s # By default, scrape targets every 15 seconds.
  # scrape_timeout is set to the global default (10s).
  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
      monitor: 'codelab-monitor'
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first.rules"
  # - "second.rules"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'
    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s
    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'linux'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.0.11:9100']
        labels:
          alias"pmmclient:3306"
      - targets: ['192.168.0.11:9100']
        labels:
          alias"pmmclient:3307"
      - targets: ['192.168.0.11:9100']
        labels:
          alias"pmmclient:3308"
  - job_name: 'mysql'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.0.11:9104']
        labels:
          alias"pmmclient:3306"
      - targets: ['192.168.0.11:9105']
        labels:
          alias"pmmclient:3307"
      - targets: ['192.168.0.11:9106']
        labels:
          alias"pmmclient:3308"
  - job_name: 'mysqlqueryresult'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.0.11:8090']
        labels:
          alias"pmmclient:3306"
cs




080. Prometheus 재 기동
prometheus.yml 파일을 수정하였다면 Prometheus 프로세스를 재 기동해준다.


1
2
3
4
5
6
7
8
[pmm@pmmserver ~]$ cd prometheus
[pmm@pmmserver prometheus]$ ps -ef | grep prometheus
pmm      13952     1  0 11:36 pts/0    00:00:03 /home/pmm/prometheus/prometheus -config.file=/home/pmm/prometheus/prometheus.yml -storage.local.retention=8760h -log.level=info
[pmm@pmmserver prometheus]$ kill 13952
[pmm@pmmserver prometheus]$ nohup /home/pmm/prometheus/prometheus -config.file=/home/pmm/prometheus/prometheus.yml -storage.local.retention=8760h -log.level=info > /home/pmm/prometheus/prometheus.log 2>&1 &
[163570
[pmm@pmmserver prometheus]$ ps -ef | grep prometheus
pmm      63570 59220  0 11:55 pts/0    00:00:00 /home/pmm/prometheus/prometheus -config.file=/home/pmm/prometheus/prometheus.yml -storage.local.retention=8760h -log.level=info
cs




090. Prometheus 웹 서비스 접속 및 확인
Prometheus를 정상적으로 재 기동하였다면, Prometheus 웹 서비스에 접속하여, 추가한 pmmclient가 정상적으로 등록되었는지 확인해본다.

Job name "mysqlqueryresult" pmmclient(192.168.0.11:8090) 노드가 추가되었고, state UP(정상)이라면 Prometheus pmmclient 서버를 정상적으로 인식한것이다.


mysqlqueryresult
Endpoint
State
Labels
Last Scrape
Error
UP
alias="pmmclient:3306"
1.243s ago
 



metrics 를 주소를 클릭하면 다음과 같이 정상적으로 pmmclient의 데이터를 등록한 쿼리에 의해서 추출됨을 확인할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# HELP vote_5second_cnt
# TYPE vote_5second_cnt gauge
vote_5second_cnt{candidate_id="3",candidate_name="C후보",db="votedb"0.0
vote_5second_cnt{candidate_id="1",candidate_name="A후보",db="votedb"0.0
vote_5second_cnt{candidate_id="2",candidate_name="B후보",db="votedb"0.0
vote_5second_cnt{candidate_id="4",candidate_name="D후보",db="votedb"0.0
vote_5second_cnt{candidate_id="5",candidate_name="E후보",db="votedb"0.0
# HELP vote_total_cnt
# TYPE vote_total_cnt gauge
vote_total_cnt{candidate_id="3",candidate_name="C후보",db="votedb"0.0
vote_total_cnt{candidate_id="1",candidate_name="A후보",db="votedb"0.0
vote_total_cnt{candidate_id="2",candidate_name="B후보",db="votedb"0.0
vote_total_cnt{candidate_id="4",candidate_name="D후보",db="votedb"0.0
vote_total_cnt{candidate_id="5",candidate_name="E후보",db="votedb"0.0
...................
cs

여기까지 MySQL서버의 특정 테이블의 데이터를 쿼리를 이용하여 주기적으로 추출하고, 그 데이터를 Prometheus에 적재하는 것까지 진행하였다. 이제부터는 수집한 메트릭을 Grafana에 대시보드로 구성하는 것을 진행해본다.



100. 투표현황 대시보드 구성

신규 대시보드를 생성한다.



새로 생성한 대시보드의 설정메뉴에서 Templating을 열어 Interval 변수를 다음과 같이 설정한다.


그리고 반드시 저장한다. “[테스트] 투표 현황이라고 명명하였다.


대시보드가 생성되었으면, 추출한 데이터를 표현할 그래프를 생성한다. 행 메뉴의 패널 추가 버전을 클릭한다.


그래프 버튼을 클릭하여 신규 그래프를 생성한다.


그래프 타이틀의 Edit 버튼을 클릭하여 그래프 설정화면으로 이동한다.


먼저 후보별 특표현황(누적)” 그래프를 만들어 본다. General 탭에 다음과 같이 그래프 타이틀 등을 입력한다.


Metrics 탭에 Query등을 다음과 같이 입력한다. Query의 메트릭 이름이나 각 파라미터 값들은 Prometheus Metrics에서 확인한 내용을 참고하면 그 rule을 간단히 알 수 있다.


Legend 탭을 다음과 같이 설정하여 각 후보의 이름과 아이디가 그래프 지표이름으로 그래프 우측에 표시되도록 설정한다. 그리고 반드시 저장한다.


이번엔 후보별 득표현황(누적)”그래프 메뉴에서 복제(Duplicate)를 클릭하여 그래프를 복사한다.
이 복사한 그래프는 설정값을 변경하여 후보별 득표현황(5초증가량)”을 보여주는 그래프로 설정한다.


복제한 그래프의 설정화면으로 진입하여, Graph 탭의 Title 등을 다음과 같이 수정한다.



Metrics 탭의 Query등을 다음과 같이 수정한다. Metric 명을 “vote_5second_cnt"로 설정해준다.


마지막으로, 투표 데이터를 INSERT/UPDATE쿼리를 임의로 수회 실행하면서 실제 데이터의 변경사항이 그래프로 잘 표시되는지 확인해본다.


이 때, 변화량을 명확히 확인하기 위하여 대시보드의 Time Range설정은 최근 5, 5초마다 리프레시로 설정해 두고 변화량을 살펴본다. 다음과 같이 그래프가 잘 그려지는 것을 확인할 수 있다.




110. 정리

1.     Prometheus MySQL Exporter가 모니터링 대상 MySQL서버에 exporter.cfg 에서 설정한 쿼리들을 주기적으로 실행하여 데이터를 주기적으로 추출(8090포트)한다.
2.     Prometheus pmmclient prometheus.yml 에서 설정한 모니터링 대상 MySQL 서버의 8090포트에 접근하여 추출 데이터를 주기적으로 수집(scrape)한다.
3.     Grafana Prometheus에 적재된 메트릭을 기반으로 그래프로 표현한다.


투표현황 대시보드를 구성한 시나리오는 상당히 간단한 샘플 예제이며, 이 예제를 바탕으로 좀더 복잡한 지표를 추출 할 수 있을 것이다. 다만 해당 쿼리의 수행시간이 1~2초 단위로 짧은 것이 아니라 1~5분 정도로 길게 소요된다면, 당연히 쿼리 수행 주기나 그래프의 Interval도 그 이상의 시간으로 적절히 조정해야 함을 기억하자


댓글 없음:

댓글 쓰기