Kafka의 메트릭
Kafka의 모든 메트릭은 JMX(Java Management Extensions) 인터페이스를 통해 사용 가능하다.
JVM 기반의 애플리케이션에서 Prometheus에 메트릭을 공개하기 위한 Java 에이전트를 실행해 메트릭을 수집한다.
카프카 브로커 실행 시 JVM옵션에 jmx prometheus javaagent를 metric config와 함께 추가한다.
-javaagent:/path/to/jmx_prometheus_javaagent.jar=8080:/path/to/kafka_config.yml
kafka_config.yml
jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:6092/jmxrmi
ssl: false
lowercaseOutputName: true
rules:
- pattern: 'kafka.cluster<type=(.+), name=(.+), topic=(.+), partition=(.+)><>Value'
name: kafka_cluster_$1_$2
labels:
topic: '$3'
partition: '$4'
- pattern: 'kafka.log<type=Log, name=(.+), topic=(.+), partition=(.+)><>Value'
name: kafka_log_$1
labels:
topic: '$2'
partition: '$3'
...
- Kafka 브로커의 메트릭 패턴을 정의하고, 해당 메트릭을 Prometheus 형식에 맞게 변환하는 규칙을 설정한다.
Kafka 서버가 시작될 때 jmx_prometheus_javaagent가 함께 실행되며, 메트릭이 수집되고 Prometheus에 노출된다. jmx_prometheus_javaagent가 수집한 메트릭은 /metrics 엔드포인트를 통해 확인 가능하다.
브로커 메트릭
메트릭 | 의미 및 대응방안 |
UnderReplicatedPartitions 미복제 파티션 갯수 |
브로커 메트릭 중 가장 중요한 메트릭 정보 리더 리플리카 브로커의 파티션을 팔로어 리플리카 브로커들이 복제하지 못한 파티션들의 총계 제공 장애 상황 0이 아닌 숫자가 변동없이 꾸준히 나타나는 경우 - 클러스터의 부하 불균형 - 리소스 자원 고갈(CPU, 네트워크 처리량, 디스크) - 하드웨어 장애 - 다른 프로세스와의 충돌 - 로컬 구성의 차이 대응 - kafka-reassign-partition.sh를 이용한 재할당 (부하 불균형 시) - 다른 브로커와 로컬 구성 비교 |
ActiveControllerCount 클러스터 컨트롤러 갯수 |
브로커의 클러스터 컨트롤러 여부 확인 컨트롤러인 경우 1의 값을 갖는다 (아닌 경우 0) 장애상황 1의 값을 갖는 브로커가 2개 이상인 경우 1의 값을 갖는 브로커가 한개도 없는 경우 대응 - 컨트롤러가 2개인 경우, 두 브로커 모두 재시작 - 컨트롤러가 없는 경우, 컨트롤러 스레드가 제대로 동작하지 않는 이유 찾아야함(클러스터의 모든 브로커 재시작 권장) |
RequestHandlerAvgIdlePercent 요청 핸들러 유휴 비율 |
요청 핸들러가 사용중이 아닌 시간의 백분율(%)을 나타냄 실수이면서 0과 1사이의 값을 가짐 장애상황 이 수치가 작을수록 브로커의 작업 부담 커짐 20%미만 - 잠재적인 문제 있음으로 판단 10%미만 - 성능 문제가 진행중임 - 스레드 풀의 스레드 수가 충분하지 않은 경우 - 스레드들이 각 요청의 불필요한 작업을 수행하는 경우 |
BytesInPerSec 모든 토픽의 입력 바이트 |
모든 토픽의 바이트 입력을 초당 바이트로 나타냄 프로듀서로부터 브로커가 받는 메시지 트래픽이 얼마나 되는지 측정하는데 유용 클러스터를 확장해야하거나, 데이터 증가에 따른 다른작업을 해야할 시기를 결정하는데 도움 클러스터의 파티션들을 리밸런싱 해야하는지 평가할 때 유용 |
BytesOutPerSec 모든 토픽의 출력 바이트 |
모든 토픽의 출력 바이트 모든 토픽의 바이트 출력을 초당 바이트로 나타냄 컨슈머의 메세지 읽는 속도 측정 리플리카 트래픽도 포함됨 예) 복제팩터 2인 경우, 바이트 출력 속도는 바이트 입력속도의 두 배 |
MessagesInPerSec 모든 토픽의 메세지 입력 수 |
모든 토픽의 메세지 입력 수 초당 입력되는 개별적인 메세지 수 (메세지 크기와 무관) 평균 메시지 크기를 결정하기 위해 바이트 입력 속도와 함께 사용 |
PartitionCount 파티션 갯수 |
브로커가 갖는 모든 리플리카 파티션을 포함한 파티션 갯수 |
LeaderCount 리더 파티션 갯수 |
브로커가 현재 리더인 파티션의 수 클러스터의 모든 브로커에 걸쳐 균등해야 한다. 정기적으로 확인하고 경계할 것 권장 장애 상황 이 메트릭 값이 모든 브로커가 균등하지 않을 때 이 값이 0이 될 때 - 클러스터에 불균형 발생 시 브로커의 리더 갯수 서로 달라질 수 있음 대응 0인 경우에는 선호 리플리카 선출을 통해 균형을 맞추어야 함 |
OfflinePartitionsCount 리더가 없는 파티션 갯수 |
클러스터에서 현재 리더가 없는 파티션 개수 클러스터의 컨트롤러 브로커에 의해서만 제공 프로듀서에게 메시지 유실 등 영향을 줄 수 있으므로 즉시 해결 필요 장애상황 1 이상일 때 - 해당 파티션의 리더나 팔로어인 모든 브로커들이 다운되었을 때 - 해당 파티션의 리더와 팔로어간의 메세지 개수 불일치로 인해 리더가 될 수 있는 동기화 리플리카가 없고 언클린 리더 선출이 비활성화 되어있을 때 |
토픽 메트릭
브로커 메트릭과 매우 유사. 토픽 이름이 지정된다는 것과 지정된 토픽에만 각 메트릭이 국한된다는 점이 다르다.
이름 | JMX MBean |
바이트 입력 | kafka.server:type=BorkerTopicMetrics, name=BytesInPerSec, topic=TOPICNAME |
바이트 출력 | kafka.server:type=BorkerTopicMetrics, name=BytesOutPerSec, topic=TOPICNAME |
읽기 실패 요청 수 | kafka.server:type=BorkerTopicMetrics, name=FailedFetchRequestsPerSec, topic=TOPICNAME |
쓰기 실패 요청 수 | kafka.server:type=BorkerTopicMetrics, name=FailedProduceRequestsPerSec, topic=TOPICNAME |
입력 메세지 수 | kafka.server:type=BorkerTopicMetrics, name=MessageInPerSec, topic=TOPICNAME |
전체 읽기 요청 수 | kafka.server:type=BorkerTopicMetrics, name=TotalFetchRequestsPerSec, topic=TOPICNAME |
전체 쓰기 요청 수 | kafka.server:type=BorkerTopicMetrics, name=TotalProduceRequestsPerSec, topic=TOPICNAME |
파티션 메트릭
지속적으로 사용하는 관점에서 토픽 메트릭에 비해 덜 유용한 편이나, 일부 제한된 상황에서 유용할 수 있다.
(파티션 크기 측정 및 자원 추적 관리에 유용)
이름 | JMX MBean |
파티션 크기 | kafka.log:type=Log, name=Size, topic=TOPICNAME, partition=2 |
로그 세그먼트 갯수 | kafka.log:type=Log, name=NumLogSegments, topic=TOPICNAME, partition=2 |
로그 끝 오프셋 | kafka.log:type=Log, name=LogEndOffset, topic=TOPICNAME, partition=2 |
로그 시작 오프셋 | kafka.log:type=Log, name=LogStartOffset, topic=TOPICNAME, partition=2 |
프로듀서 메트릭
이름 | JMX MBean |
전체 프로듀서 | kafka.producer:type=producer-metrics, clinet-id=CLIENTID 메시지 배치의 크기부터 메모리 버퍼 사용에 대한 속성까지 모두 제공 ※ 주의 깊게 봐야할 속성 - record-error-rate : 항상 0 이어야 함. 메세지 전송 실패 시 삭제한 값을 지님 - request-latency-avg : 브로커가 produce 요청 받을 때까지 소요된 평균시간(임계값을 찾을것) 메시지 트래픽 측정 관련 속성 - outgoing-byte-rate : 초당 입력되는 메시지의 절대 크기(바이트) - record-send-rate : 초당 쓰는 메시지 개수 형태로 트래픽을 나타냄 - request-rate : 브로커에게 전송되는 초당 produce 요청 수 제공 메시지 크기 관련 속성 - request-size-avg : 브로커에게 전송되는 produce 요청의 평균 크기(바이트) - batch-size-avg : 한 메시지 배치의 평균 크기(바이트) - record-size-avg : 한 레코드의 평균 크기(바이트) - records-per-request-avg : 하나의 produce 요청에 있는 메시지의 평균 개수 |
프로듀서 - 브로커 | kafka.producer:type=producer-node-metrics, clinet-id=CLIENTID 전체 프로듀서 메트릭에 추가하여 특정 상황의 문제점을 디버깅하는데 유용 가장 유용한 메트릭 - request-latency-avg - outgoing-byte-rate |
프로듀서- 토픽 | kafka.producer:type=producer-topic-metrics, clinet-id=CLIENTID 두 개 이상의 토픽을 사용하는 프로듀서의 경우 프로듀서-브로커 메트릭보다 더 유용함 가장 유용한 메트릭 - record-send-rate - record-error-rate - byte-rate |
컨슈머 메트릭
이름 | JMX MBean |
전체 컨슈머 | kafka.consumer:type=consumer-metrics, client-id=CLIENTID |
Fetch 매니저 | kafka.consumer:type=consumer-fetch-manager-metrics, client-id=CLIENTID 컨슈머에서는 Fetch 매니저가 전체 컨슈머 메트릭보다 더 중요한 메트릭들을 들고 있다 가장 유용한 메트릭 - fetch-latency-avg : fetch 요청을 브로커가 받는 데 걸리는 시간 - bytes-consumed-rate : 컨슈머가 처리하는 메시지 트래픽 측정시 사용 - records-consumed-rate : 컨슈머가 처리하는 메시지 트래픽 측정시 사용 - fetch-rate : 컨슈머가 수행하는 초당 fetch 요청 수 - fetch-size-avg : 각 fetch 요청의 평균 크기를 제공 - records-per-request-avg : 각 fetch 요청의 평균 메시지 수 |
컨슈머 - 토픽 | kafka.consumer:type=consumer-fetch-manager-metrics, client-id=CLIENTID, topic=TOPICNAME |
컨슈머 - 브로커 | kafka.consumer:type=consumer-node-metrics, client-id=CLIENTID, node id=node-BROKERID 가장 유용한 메트릭 - request-latency-avg - incoming-byte-rate - request-rate |
컨슈머 - 조정자 | kafka.consumer:type=consumer-cordinator-metrics, client-id=CLIENTID |