모니터링 설정 및 분산 환경 모니터링

박태현·2025년 8월 31일
0

MySQL 모니터링


MySQL의 metrics에 접근하기 위해서는 MySQL Exporter를 사용하여야 합니다.

이를 통해 mySQL의 Threads_running, Queries, Innodb_rows_read 등의 metrics를 가져올 수 있습니다.

기본적으로 변환된 메트릭 데이터를 9104 포트의 /metrics 엔드포인트를 통해 HTTP로 외부에 노출합니다

MySQL Exporter가 수집한 데이터를 Prometheus가 주기적으로 가져와 저장하며, 이 데이터를 그라파나가 시각화합니다

구현

  1. docker-compose.yml 파일 수정

    services:
      airdnb-prometheus:
        image: prom/prometheus
    
        # 로컬에서 만든 prometheus.yml을 컨테이너 안에 그대로 덮어씌워서 사용
        volumes:
          - ./prometheus.yml:/etc/prometheus/prometheus.yml
        ports:
          - "9090:9090"
        networks:
          - monitoring-net
    
      # grafana
      airdnb-local-grafana:
        image: grafana/grafana
        ports:
          - "3001:3000"
        networks:
          - monitoring-net
    
      mysql_exporter_service:
        image: prom/mysqld-exporter:latest
        container_name: mysql-exporter
        restart: always
        ports:
          - "9104:9104"
        command:
          - "--mysqld.username=taehyun:0136"
          - "--mysqld.address=host.docker.internal:3306"
        networks:
          - monitoring-net
    
    networks:
      monitoring-net:

    MySQL Exporter는 기본적으로 9104 포트를 사용하며, 로컬 MySQL에 접근하기 위해 Exporter 전용 계정을 생성해야 합니다.

    로컬 mysql에 접근하여 아래와 같은 명령어를 통해 Exporter 계정 생성

    CREATE USER '[아이디]'@'%' IDENTIFIED BY '[비밀번호]';
    GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO '[아이디]'@'%';
    FLUSH PRIVILEGES;
    
    저 같은 경우 taehyun에 0136으로 설정

    설정한 Exporter 계정을 바탕으로 Exporter에서 MySQL에 접근하기 위한 설정으로 아래와 같이 설정
    command:
    	- "--mysqld.username=taehyun:0136"
    	- "--mysqld.address=host.docker.internal:3306"

    ‼️‼️ 문제 발생

    MySQL Exporter의 공식 문서에서 권장하는 environment를 사용하여 DATA_SOURCE_NAME을 통해 mysql에 접근하는 방식이 작동하지 않아 위와 같이 설정

    ~~environment~~:       
    	~~- DATA_SOURCE_NAME=taehyun:0136@(host.docker.internal:3306)/~~

  1. prometheus.yml 파일에 아래 코드 추가

      - job_name: "mysql"
        metrics_path: '/metrics'
        static_configs:
          - targets: ['mysql_exporter_service:9104']

  • 이후 docker-compose up 명령어로 컨테이너들을 실행 시킨 후 http://localhost:9090/targets에 접근하여 확인해보면 Prometheus가 MySQL Exporter로부터 메트릭 데이터를 성공적으로 수집하고 있는 것을 알 수 있음

Grafana 연동

이전에 만든 datasource를 통해 7362번으로 임포트하여 대시보드를 생성



그라파나 mysql 주요 기능

  • MySQL Uptime
    MySQL 서버가 현재까지 가동된 시간

  • Current QPS ( Query Per Second )
    초당 처리된 쿼리 수

    데이터베이스의 부하 상태를 나타내며, 트래픽 변화에 따른 성능 상태를 파악할 수 있습니다.

  • InnoDB Buffer Pool Size
    InnoDB의 버퍼 풀 크기

    MySQL의 메모리 활용 상태를 분석하는 지표

  • Connections
    현재 연결된 클라이언트 수와 최대 사용된 연결 수

    시스템의 네트워크 사용량과 트래픽 증가에 따른 용량 제한 문제를 파악할 수 있음

  • MySQL Client Thread Activity
    MySQL 클라이언트의 활성 스레드 수

    MySQL이 요청을 처리하는 동안 스레드 활동 상태를 분석

  • Table Locks
    데이터베이스 테이블의 잠금 발생 빈도

    쿼리 실행 중 발생하는 잠금 문제를 모니터링하여 성능 병목현상을 방지

  • MySQL Thread Cache
    MySQL에서 캐시된 스레드 수와 캐시 크기

    스레드 캐시를 효율적으로 활용하고 있는지 분석하여 성능 최적화 상태를 확인


Kafka 모니터링


Kafka를 모니터링 하기 위해 kafka exporter를 사용하도록 하겠습니다.

기존의 로컬에서 사용하던 카프카를 docker 컨테이너에서 사용하도록 변경하였습니다.

  • docker-compose.yml 파일 수정 kafka docker 설정 및 kafka-exporter 설정 추가
    	test-kafka:
        image: confluentinc/cp-kafka:latest
        container_name: test-kafka
        ports:
          - "29092:29092"
        environment:
          KAFKA_NODE_ID: 1
          KAFKA_PROCESS_ROLES: 'broker,controller'
          KAFKA_CONTROLLER_QUORUM_VOTERS: '1@test-kafka:29093'
    
          # 프로젝트는 로컬에서 실행중
          KAFKA_LISTENERS: 'PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:29093,PLAINTEXT_HOST://0.0.0.0:29092'
          KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://test-kafka:9092,PLAINTEXT_HOST://localhost:29092'
          KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT'
          KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
          KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
          KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
          KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
          CLUSTER_ID: 'ciWo7IWazngRchmPES6q5A=='
          KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
        networks:
          monitoring-net:
    
      test-kafka-cli:
        image: confluentinc/cp-kafka:latest
        container_name: test-kafka-cli
        entrypoint: /bin/sh
        tty: true
        networks:
          monitoring-net:
      
      kafka-exporter:
        image: danielqsj/kafka-exporter:latest
        container_name: kafka-exporter
        ports:
          - "9308:9308"
        command: [ "--kafka.server=test-kafka:9092" ]
        networks:
          - monitoring-net
        depends_on:
          - test-kafka
        restart: always

‼️ kafka-exporter가 Kafka에 접속하지 못하는 문제 발생 ( connection refused ) ‼️

Connection refused 오류는 다음 두 가지 원인으로 인해 발생할 수 있습니다.

  1. Kafka 브로커 미기동 : Kafka 브로커가 아직 완전히 시작되지 않았거나, 내부 서비스가 준비되지 않은 상태에서 Kafka Exporter가 접속을 시도하는 경우
  2. Advertised Listener 설정 오류 : Kafka 브로커의 advertised.listeners 설정이 Kafka Exporter가 접근할 수 없는 주소로 잘못 지정된 경우

docker-compose.yml에서 depends_on 설정은 단순히 컨테이너가 실행되었음만 보장하므로, Kafka 브로커가 완전히 기동되고 연결을 받을 준비가 될 때까지 보장하지는 않습니다.

이러한 상황을 해결하기 위해, restart: always 설정을 사용하면 Kafka Exporter가 일시적인 연결 실패 후에도 자동으로 재시작을 시도하여, Kafka 브로커가 준비될 때까지 계속 접속을 시도하게 하여 문제를 해결하였습니다.

  • application-properties 파일 수정 카프카에 접속하기 위한 설정 수정
    spring.kafka.producer.bootstrap-servers=localhost:29092
    queue.event.topic.name=test_queueing_system
    
    spring.kafka.consumer.bootstrap-servers=localhost:29092
    spring.kafka.consumer.group-id=test_consumer_group01
    spring.kafka.consumer.auto-offset-reset=earliest

  • prometheus.yml 설정 파일 수정 prometheus가 kafka-exporter에서 메트릭을 수집하도록 하는 설정 추가
    - job_name: 'kafka'
    	static_configs:
    		- targets: [ 'kafka-exporter:9308' ]

이후 promethus에서 kafka-exporter metric을 잘 수집하는지 확인해보면 정상적으로 up 되는 것을 확인할 수 있음



이를 통해 Grafana에서 7589 대시보드를 만들어 확인 가능


임의로 특정 토픽에 100개의 메세지를 보냈을 때의 그래프

Kafka-cli 컨테이너에서 아래 명령어 실행

sh-5.1$ kafka-verifiable-producer --topic test_queueing_system --max-messages 100 --bootstrap-server test-kafka:9092



Kafka UI를 통한 Kafka 운영


  • docker-compose.yml 파일 수정
    kafka-ui:
        image: provectuslabs/kafka-ui
        container_name: kafka-ui
        ports:
          - "8989:8080"
        restart: always
        environment:
          - KAFKA_CLUSTERS_0_NAME=local-single-broker
          - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=test-kafka:9092
        networks:
          monitoring-net:

이후 http://localhost:8989/ 에 접근하면 kafka ui에 접근 가능


UI for Apache Kafka 옵션

[ 메인 대시보드 ]

  • Cluster name: local - 클러스터 이름
  • Brokers count: 현재 카프카 브로커 개수
  • Partitions: 현재 파티션 개수
  • Topics: Topic 개수
  • Production: 발행한 메시지 용량
  • Consumption: 수신한 메시지 용량

[ Broker 대시보드 ]

  • Uptime
    • Total Brokers: 총 브로커 개수
    • Active Controllers: 활동 컨트롤러
  • Partitions
    • Online: 현재 온라인 개수
    • URP: 복제가 덜 된 파티션수 ( Un Replication Partitions )
    • In Sync Replicas: 리더와 동기화된 상태를 유지하는 복제본들의 집합
    • Out of Sync Replicas: 싱크가 맞지 않는 리플리카 개수

[ Topic 대시보드 ]

  • 현재 생성된 모든 토픽을 나타냄
  • _confluent.support.metrics: confluent에서 지원되는 메트릭 정보를 위한 토픽
  • 상세정보
    • Topic Name: 현재 존재하는 토픽 이름
    • Total Partitions: 토픽의 총 파티션 개수
    • Out of sync replicas: 복제 싱크가 맞지 않는 복제 개수
    • Replication Factor: 복제 팩터 ( 복제 개수는 브로커 개수보다 작게 설정하는 것이 일반적 )
    • Number of messages: 메시지 수
    • Size: 메시지 총 크기
  • message 옵션에서 message의 정보도 볼 수 있음

[ consumer 대시보드 ]

  • 클러스터에 연동된 컨슈머 정보를 나타냄
  • 상세정보
    • Consumer Group ID: 컨슈머 그룹 아이디
    • Number Of Members: 컨슈머 그룹의 멤버수
    • Num Of Topics: 컨슈머 그룹의 토픽 수
    • State: 컨슈머 상태

Redis 모니터링 설정


Redis 모니터링을 위해 redis-exporter를 사용할 예정이며, 현재 Redis는 컨테이너가 아닌 로컬 환경에서 실행 중입니다.

docker-compose.yml 파일에 추가

redis-exporter:
	container_name: redis-exporter
	image: oliver006/redis_exporter:latest
    
	# 로컬에서 사용중인 redis 사용
	environment:
		- REDIS_ADDR=redis://host.docker.internal:6379
	ports:
		- "9121:9121"
	depends_on:
		- airdnb-prometheus
	networks:
		- monitoring-net
	restart: always

prometheus.yml 파일에 추가

- job_name: 'redis-exporter'
	static_configs:
		- targets: [ 'redis-exporter:9121' ]

application.properties 설정

redis.host = localhost
redis.port = 6379

이후 promethus에서 redis-exporter가 metric을 잘 수집하는지 확인해보면 정상적으로 up 되는 것을 확인할 수 있음


Grafana에서 14615 대시보드를 import 하여 실행

분산 환경 모니터링


각각 서버 1, 2, 3의 부하

분산 서버 환경으로 확장함으로써, 단일 서버 환경에서 나타나던 부하로 인한 간헐적 오류가 해소되었고, 요청 분산이 효과적으로 이루어짐을 검증할 수 있었습니다.

profile
꾸준하게

0개의 댓글