1. 시작하며
사이드 프로젝트를 진행하면서 Spring Boot 애플리케이션의 모니터링 시스템을 구축하던 중, 데이터베이스 상태를 실시간으로 모니터링할 수 있는 환경도 필요하다는 생각이 들었습니다. 데이터베이스는 서비스 성능과 안정성에 중요한 영향을 미치는 핵심 요소이기 때문에, 이를 효과적으로 관리하고 분석할 수 있는 시스템 구축이 필요했습니다.
Grafana에 대해 조사하던 중, MySQL 데이터베이스 모니터링 대시보드를 손쉽게 구성할 수 있다는 점을 알게 되었습니다. 이번 프로젝트에서는 Prometheus와 MySQL Exporter를 활용해 데이터를 수집하고, Grafana 대시보드를 통해 이를 시각화하여 MySQL 모니터링 시스템을 구축하는 과정을 공유하려고 합니다.
1.1 프로젝트 구조와 목표
이 프로젝트는 Docker Compose를 활용해 Prometheus, MySQL Exporter, Grafana 등 필요한 모든 서비스를 하나의 컨테이너 환경에서 실행하도록 구성되었습니다. 주요 구성 요소는 다음과 같습니다.
NowDoBoss/
├── CICD/
│ ├── Util/
│ │ ├── Prometheus/
│ │ │ ├── prometheus.yml # Prometheus 구성 파일
│ │ │ ├── prometheus.Dockerfile # Prometheus Docker 이미지 빌드 파일
│ │ ├── infra-env/ # 환경 변수 관리 (서브모듈)
│ │ ├── docker-compose.yml # 모든 컨테이너 실행을 위한 Compose 파일
... 이외 생략
목표는 다음과 같습니다.
- MySQL Exporter를 사용하여 MySQL 메트릭 데이터를 Prometheus에 수집
- Prometheus를 통해 데이터 저장 및 수집
- Grafana를 활용해 대시보드에서 실시간 데이터 시각화
- 데이터베이스 상태를 모니터링하여 운영 효율성을 높이고, 성능 이슈를 사전에 감지
2. Prometheus와 Grafana 개요
2.1 Prometheus
Prometheus는 오픈소스 모니터링 및 경고 도구로, 다양한 시스템에서 메트릭 데이터를 수집하고 저장합니다. Prometheus는 Pull 방식으로 데이터를 가져오며, 설정된 scrape_interval
에 따라 MySQL Exporter에서 데이터를 주기적으로 수집합니다.
Prometheus의 주요 특징은 다음과 같습니다.
- 시계열 데이터베이스를 활용한 효율적인 데이터 저장
- 다양한 Exporter를 통해 다양한 시스템 메트릭 수집
- 알림 규칙 구성 및 알림 전송 기능 제공
2.2 Grafana
Grafana는 Prometheus 등 다양한 데이터 소스에서 데이터를 가져와 대시보드를 생성하고, 이를 시각적으로 표현할 수 있는 도구입니다. Grafana는 다음과 같은 기능을 제공합니다.
- 대시보드 커스터마이징: 데이터 시각화를 위한 다양한 위젯 제공
- 데이터 소스 연결: Prometheus, InfluxDB, MySQL 등 다양한 데이터 소스 지원
- 알림 설정: 특정 조건을 기반으로 경고를 트리거
3. 구축 과정
3.1 MySQL Exporter 설정
MySQL Exporter는 Prometheus가 MySQL 데이터베이스의 메트릭 데이터를 수집할 수 있도록 지원합니다. 이를 설정하기 위해 다음 단계를 수행했습니다.
1) MySQL Exporter용 계정 생성
MySQL Exporter는 Prometheus가 데이터를 수집할 수 있도록 MySQL에 연결됩니다. 이를 위해 MySQL에 root 계정으로 접속해 MySQL Exporter 전용 계정을 생성합니다.
CREATE USER 'exporter'@'%' IDENTIFIED BY 'your_password';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';
FLUSH PRIVILEGES;
- PROCESS 권한: MySQL의 현재 프로세스 상태를 모니터링
- REPLICATION CLIENT 권한: 복제 관련 상태 확인
- SELECT 권한: 데이터베이스에서 데이터를 읽기 위한 권한
2) MySQL Exporter 실행
Docker Compose를 사용해 MySQL Exporter 컨테이너를 실행합니다.
services:
mysql_exporter_service:
image: prom/mysqld-exporter:latest
container_name: mysql-exporter
restart: always
ports:
- "${MYSQL_EXPORTER_PORT}:${MYSQL_EXPORTER_PORT}" # MySQL Exporter의 기본 포트는 9104이다.
command:
- "--mysqld.username=${MYSQL_EXPORTER_USER}:${MYSQL_EXPORTER_PASSWORD}"
- "--mysqld.address=${MYSQL_EXPORTER_MYSQL_CONNECT_HOST}:${MYSQL_PORT}"
depends_on:
- mysql_service
networks:
- nowdoboss-net
MYSQL_EXPORTER_USER
: MySQL Exporter 계정명MYSQL_EXPORTER_PASSWORD
: 해당 계정의 비밀번호MYSQL_EXPORTER_MYSQL_CONNECT_HOST
: MySQL 서비스가 실행 중인 호스트MYSQL_PORT
: MySQL 서비스 포트
3.2 Prometheus 설정
1) Prometheus 구성 파일 작성
Prometheus는 prometheus.yml
파일에서 수집 대상을 정의합니다.
global:
scrape_interval: 15s # 15초마다 메트릭을 수집
scrape_configs:
# MySQL Exporter 메트릭 수집
- job_name: 'mysql_exporter'
metrics_path: '/metrics'
static_configs:
- targets: ['mysql-exporter:9104'] # MySQL Exporter 컨테이너 이름과 포트
2) Prometheus 실행
Docker Compose를 사용하여 Prometheus 컨테이너를 실행합니다. Prometheus는 위에서 작성한 prometheus.yml
파일을 기반으로 동작합니다.
# Prometheus Dockerfile (prometheus.Dockerfile)
FROM prom/prometheus:latest
# Prometheus 설정 파일을 컨테이너 내부로 복사
COPY prometheus.yml /etc/prometheus/prometheus.yml
services:
# Prometheus 설정
prometheus_service:
build:
context: ./Prometheus # 해당 Dockerfile이 위치한 경로
dockerfile: prometheus.Dockerfile # 직접 빌드할 Dockerfile명
container_name: prometheus
restart: always
volumes:
- prometheus_data:/prometheus # Prometheus 데이터 저장소
ports:
- "${PROMETHEUS_PORT}:${PROMETHEUS_PORT}" # Prometheus 웹 UI 포트
command:
- '--web.enable-lifecycle' # Prometheus의 라이프사이클 관련 엔드포인트를 활성화
- '--config.file=/etc/prometheus/prometheus.yml' # Prometheus가 사용할 설정 파일을 지정
- '--storage.tsdb.path=/prometheus' # 데이터 저장 경로
networks:
- nowdoboss-net
3.3 Grafana 설정
1) Grafana 실행
Docker Compose를 사용하여 Grafana 컨테이너를 실행합니다.
services:
grafana_service:
image: grafana/grafana:latest
container_name: grafana
restart: always
ports:
- "${GRAFANA_PORT}:${GRAFANA_PORT}"
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD} # 기본 관리자 패스워드 설정
volumes:
- grafana_data:/var/lib/grafana # Grafana 데이터 저장소
networks:
- nowdoboss-net # Prometheus와 같은 네트워크 사용
volumes:
grafana_data:
완성된 Docker Compose 파일 코드
services:
mysql_exporter_service:
image: prom/mysqld-exporter:latest
container_name: mysql-exporter
restart: always
ports:
- "${MYSQL_EXPORTER_PORT}:${MYSQL_EXPORTER_PORT}"
command:
- "--mysqld.username=${MYSQL_EXPORTER_USER}:${MYSQL_EXPORTER_PASSWORD}"
- "--mysqld.address=${MYSQL_EXPORTER_MYSQL_CONNECT_HOST}:${MYSQL_PORT}"
depends_on:
- mysql_service
networks:
- nowdoboss-net
prometheus_service:
build:
context: ./Prometheus
dockerfile: prometheus.Dockerfile
container_name: prometheus
restart: always
volumes:
- prometheus_data:/prometheus
ports:
- "${PROMETHEUS_PORT}:${PROMETHEUS_PORT}"
command:
- '--web.enable-lifecycle'
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
networks:
- nowdoboss-net
grafana_service:
image: grafana/grafana:latest
container_name: grafana
restart: always
ports:
- "${GRAFANA_PORT}:${GRAFANA_PORT}"
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD}
volumes:
- grafana_data:/var/lib/grafana
networks:
- nowdoboss-net
volumes:
prometheus_data:
grafana_data:
networks:
nowdoboss-net:
name: nowdoboss-net
driver: bridge
2) Grafana 설정 과정
- Grafana 접속
- Grafana에 접속 후, 좌측 메뉴의 Connections 탭을 클릭합니다.
- Data sources 메뉴를 선택하여 데이터 소스 관리 화면으로 이동합니다.
- 데이터 소스 추가
- Add new data source 버튼을 클릭합니다.
- 제공되는 데이터베이스 옵션 중 Prometheus를 선택합니다.
- Prometheus 데이터 소스 설정
- Prometheus server URL 입력란에 Prometheus 서버의 URL(예:
http://prometheus:9090
)을 입력합니다.- Docker Compose 환경에서는 컨테이너 간 네트워크가 기본적으로 연결되어 있으므로, Prometheus 컨테이너의 이름과 포트를 사용하여 통신이 가능합니다. 예를 들어,
prometheus
컨테이너가 실행 중이라면 URL은http://prometheus:9090
과 같이 설정할 수 있습니다.
- Docker Compose 환경에서는 컨테이너 간 네트워크가 기본적으로 연결되어 있으므로, Prometheus 컨테이너의 이름과 포트를 사용하여 통신이 가능합니다. 예를 들어,
- 기본 설정값(Scrape interval, Query timeout 등)을 확인하거나 필요한 경우 수정합니다.
- 설정 완료 후 Save & Test 버튼을 클릭하여 설정을 저장하고 Prometheus 연결을 테스트합니다.
- 성공적으로 연결되면 "Successfully queried the Prometheus API" 메시지가 표시됩니다.
- Prometheus server URL 입력란에 Prometheus 서버의 URL(예:
- 대시보드 구성
- Grafana의 좌측 메뉴에서 Dashboards를 클릭하고, New Dashboard 버튼을 선택합니다.
- 대시보드 임포트
- Grafana의 대시보드 관리 화면에서 Import dashboard 옵션을 선택합니다.
- Grafana Labs에서 제공되는 JSON 파일이나 대시보드 ID(예:
7362
)를 입력하여 대시보드를 불러옵니다. - Import 옵션에서 데이터 소스를 Prometheus로 지정한 후 Import 버튼을 클릭합니다.
4. 완성된 시스템
최종적으로 Prometheus와 Grafana를 사용하여 MySQL 데이터를 실시간으로 모니터링할 수 있는 시스템이 완성되었습니다.
4.1 주요 모니터링 항목
완성된 Grafana 대시보드에서는 MySQL Exporter를 통해 수집된 다양한 메트릭 데이터를 실시간으로 확인할 수 있습니다. 주요 모니터링 항목은 다음과 같습니다.
- MySQL Uptime
- MySQL 서버가 현재까지 가동된 시간 (예:
2.7 weeks
) - 시스템의 안정성과 연속성을 확인하는 데 중요한 지표입니다.
- MySQL 서버가 현재까지 가동된 시간 (예:
- Current QPS (Query Per Second)
- 초당 처리된 쿼리 수 (예:
1.29
) - 데이터베이스의 부하 상태를 나타내며, 트래픽 변화에 따른 성능 상태를 파악할 수 있습니다.
- 초당 처리된 쿼리 수 (예:
- InnoDB Buffer Pool Size
- InnoDB의 버퍼 풀 크기 (예:
128 MiB
) - MySQL의 메모리 활용 상태를 분석하는 중요한 지표입니다.
- InnoDB의 버퍼 풀 크기 (예:
- Connections
- 현재 연결된 클라이언트 수와 최대 사용된 연결 수
- 시스템의 네트워크 사용량과 트래픽 증가에 따른 용량 제한 문제를 파악할 수 있습니다.
- MySQL Client Thread Activity
- MySQL 클라이언트의 활성 스레드 수 (Connected, Running)
- MySQL이 요청을 처리하는 동안 스레드 활동 상태를 분석합니다.
- Table Locks
- 데이터베이스 테이블의 잠금 발생 빈도
- 쿼리 실행 중 발생하는 잠금 문제를 모니터링하여 성능 병목현상을 방지합니다.
- MySQL Thread Cache
- MySQL에서 캐시된 스레드 수와 캐시 크기
- 스레드 캐시를 효율적으로 활용하고 있는지 분석하여 성능 최적화 상태를 확인할 수 있습니다.
- Other Metrics (No Data)
- 일부 지표는 Grafana 대시보드 설정 또는 Exporter 설정에 따라 데이터를 수집하지 못하는 경우가 있습니다. 예를 들어 "Buffer Pool Size of Total RAM" 항목에서 데이터를 수집하지 못한 경우 "No Data"로 표시됩니다.
5. 결론
이번 프로젝트를 통해 Prometheus와 Grafana를 활용한 MySQL 데이터베이스 모니터링 시스템을 성공적으로 구축할 수 있었습니다. 앞으로도 지속적으로 모니터링 시스템을 개선하며, 더욱 안정적이고 신뢰할 수 있는 서비스를 제공하기 위한 환경을 만들어가겠습니다.
6. 참고
'DevOps > Monitoring' 카테고리의 다른 글
[Monitoring] Portainer로 Sub Server Docker 환경 관리하기 (0) | 2025.01.05 |
---|