MySQL 데이터 모니터링 – Prometheus MySQL Expoter
지난 포스팅까지 차근차근 따라온 독자분들이라면 이 시점 즈음해서 한 가지 원하는 기능이 있을 수 있다.
“MySQL 서버에 SQL을 질의한 결과를 Prometheus에 쌓는다면, 이를 Grafana에서 대시보드로 구성할 수 있지 않을까?”
충분히 가능하다.
다시 말해, MySQL에 적재되어 있는 테이블 데이터에 SELECT SQL을 질의한 결과를 Prometheus에 적재할 수 있다면, Grafana의 다양한 그래프를 이용해서 실시간 데이터 변경 추이를 시각적으로 조회 할 수 있다.
자 시작해보자.
010. 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 -e "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 -e '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초간 후보별 득표수 조회
ㄴ. 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
: 쿼리 결과값에 대한 컬럼명
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 -s /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 & [1] 63570 [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가 정상적으로 등록되었는지 확인해본다.
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)를 클릭하여 그래프를 복사한다.
복제한 그래프의 설정화면으로 진입하여, 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도 그 이상의 시간으로 적절히 조정해야 함을 기억하자.
댓글 없음:
댓글 쓰기