Burrow

Burrow - Kafka Consumer Lag Checking

Burrow는 카프카의 모니터링 툴로 Consumer의 LAG을 모니터링할 때 주로 사용된다. 모든 Consumer의 커밋 오프셋을 모니터링한다. 또한 필요할 때 Consumer의 상태를 계산한다. HTTP 엔드포인트를 통해 상태를 요청할 수 있으며, 다른 카프카 클러스터의 정보를 제공받을 수 있다. 이메일이나 HTTP 호출을 통해 다른 서비스로 상태를 보낼 수 있는 구성 가능한 알람 기능도 있다.

특징

  • NO THRESHOLDS! : Groups are evaluated over a sliding window.
  • 여러 카프카 클러스터 지원
  • 커밋된 오프셋을 사용하여 모든 Consumer를 자동으로 모니터링
  • Zookeeper 커밋 오프셋 지원
  • Storm 커밋 오프셋 지원
  • Consumer 그룹 상태 및 브로커 정보 제공을 위한 HTTP 엔드포인트 제공
  • 경고 이메일 전송 기능 지원
  • 다른 시스템에 경고를 보내가 위한 HTTP 클라이언트 지원

Getting Started

설치 및 실행 방법은 Burrow에 자세히 설명되어 있으므로 이를 참고하여 진행하길 바란다. 소스코드를 다운받어서 설치하는 방법이 있고 Docker를 사용하는 방법도 있다.

Overview

Burrow는 카프카나 주키퍼에 오프셋을 커밋하는 컨슈머 그룹을 모니터링한다. 또한 컨슈머 그룹이 사용하는 모든 토픽과 파티션을 모니터링한다. 이를 통해 컨슈머의 상태를 종합적으로 보여준다. 또한 Burrow는 여러 HTTP 엔드포인트를 제공하며 이 엔드포인트를 통해서 카프카 클러스터나 컨슈머의 정보를 가져올 수 있다. HTTP 엔드포인트를 사용해서 카프카 클러스터를 관리하는데 도움이 되는 어플리케이션을 개발할 수 있다.

Why not MaxLag?

표준 카프카 컨슈머는 MaxLag을 추적할 수 있는 메트릭을 가지고 있다. 이 방법은 편리하지만 몇가지 단점이 있다.

  • 모든 컨슈머의 MaxLag을 모니터링 하기 위해서 모든 컨슈머로 부터 MaxLag 메트릭 정보를 수집해야 한다.
  • 컨슈머가 메트릭 정보를 전달하는 방식을 사용하면, 컨슈머가 실행중이 아닌 경우에는 메트릭 정보를 받을 수 없다.
  • MaxLag는 객관적이지 않다. MaxLag은 컨슈머 지체에 대한 객관적인 척도가 될 수 없다. 컨슈머는 메시지를 가져오고 난 뒤에 MaxLag을 측정한다. 따라서 메시지를 처리하는데 문제가 생긴다면 잘못된 값이 전달될 수 있다.
  • MaxLag은 자바 클라이언트에서만 제공된다.

How does it Work

Burrow는 여러 서브 시스템에 필요한 작업을 분리하는 모듈식 설계를 사용한다.

  • Clusters : 카프카 클라이언트를 실행시켜 토픽 목록과 모든 파티션의 HEAD 오프셋을 주기적으로 업데이트 한다.
  • Consumers : 레퍼지토리에서 컨슈머 그룹에 대한 정보를 가져온다. 레퍼지토리는 카프카 클러스터(__consumer_offsets 토픽) 혹은 주키퍼가 될 수 있다.
  • Storage : 이 모든 정보를 Burrow에 저장한다.
  • Evaluator : 특정 컨슈머 그룹에 대한 정보를 Storage 서브시스템에서 가져온다. 그리고 그룹의 상태를 계산한다. 상태를 계산하는 방법에 대해서는 뒤에서 설명하도록 하겠다.
  • Notifier : 설정된 간격으로 컨슈머 그룹의 상태를 요청한다. 그리고 설정된 기준을 충족시키는 그룹에 대한 알림을 보낸다. (Email, HTTP 혹은 다른 방법)
  • HTTP Server : API 인터페이스를 제공하여 클러스터 및 컨슈머에 대한 정보를 제공한다. HTTP requests에서 Burrow가 제공하는 HTTP 엔트포인트에 대한 설명을 볼 수 있다.

Configuration and Starting Burrow

Burrow는 viper을 사용하여 설정하도록 되어있다. 설정 파일이 이미 있으면, Burrow 어플리케이션을 시작할 때 설정 파일이 있는 디렉토리를 지정해주면 된다. 파일이 현재 실행중인 디렉토리에 있으면 이 옵션을 생략할 수 있다.

$ ./Burrow --config-dir=/path/to/configurations

설정에 대한 자세한 내용은 아래에서 설명하도록 하겠다.

Consumer Lag Evaluation Rules

컨슈머 그룹의 상태는 몇개의 규칙에 의해서 결정된다. 규칙은 주로 각 파티션에 대한 오프셋과 관련이 있다. 여러 규칙을 통해서 컨슈머의 현재 상태를 결정하기 때문에 따로 임계값을 설정할 필요가 없다.

Evaluation Window

Storage subsystem의 interval 설정은 슬라이딩 윈도우의 길이를 결정한다. interval은 각 파티션에 대해 오프셋을 몇 개 저장할 것인지를 지정한다. 기본값은 10이다. 만약에 기본값을 사용하고 컨슈머의 커밋 interval이 60초라고 하면 타임 윈도우의 크기는 약 10분이 된다. 윈도우는 컨슈머가 커밋한 오프셋과 함께 앞으로 이동한다. (새로운 오프셋이 추가되면 가장 오래된 오프셋은 삭제된다)

각 컨슈머 오프셋에 대해 오프셋 뿐만 아니라 컨슈머가 커밋한 시점의 타임스탬프값, LAG 값을 저장한다. LAG은 브로커의 HEAD 오프셋값과 컨슈머 오프셋 값의 차이로 계산된다. 브로커 오프셋은 고정된 간격으로 업데이트 되므로 음수가 될 수도 있다. 만약 음수가 되면 LAG값은 0으로 저장된다.

Evaluation Rules

다음 규칙은 파티션에 대한 그룹의 상태를 평가하기 위해 사용된다.

  1. 윈도우 내에 모든 LAG이 0이면 Consumer는 OK가 된다.
  2. 오프셋이 변하지 않는데 LAG이 고정되거나 증가하고 있으면 컨슈머는 ERROR 상태가 된다. 그리고 파티션은 STALLED라고 표시한다.
  3. 컨슈머의 오프셋이 증가하고 있지만 LAG이 고정되거나 증가하고 있으면 컨슈머는 WARNING 상태가 된다. WARNING 상태라는 것은 컨슈머가 느려서 점점 뒤쳐지고 있다는 것이다.
  4. 현재시간과 가장 최근 오프셋의 시간의 차이가 윈도우 내 가장 최근 오프셋의 시간과 가장 오래된 오프셋의 시간의 차이보다 큰 경우 컨슈머는 ERROR 상태가 된다. 그리고 파티션은 STOPPED라고 표시된다. 그러나 만약 컨슈머 오프셋과 현재 브로커 오프셋이 같다면 파티션은 에러로 간주되지 않는다. 이 룰은 오랜 시간동안 컨슈머가 커밋을 하지 않는 경우를 감지하는 것으로 보인다.
  5. LAG이 -1인 경우가 있다. 이는 Burrow가 아직 각 파티션별로 브로커 오프셋을 가지고 있지 않은 경우이다. 이런 상황은 Burrow가 시작할 때만 발생한다. 그리고 이 경우는 컨슈머를 OK 상태로 간주한다.

Burrow는 오프셋 윈도우가 가득차기 전에 파티션을 평가하려고 시도한다. Burrow가 시작되고 오프셋 커밋을 가져오는 동안 이는 잘못된 정보로 이어질 수 있다. 그룹 상태의 Complete 플래그는 Burrow가 파티션에 대해 얼마나 많은 정보를 가지고 있는지를 퍼센테이지로 나타낸다.

Offset Expiration

Storage 서브시스템의 expire-group 설정값동안 오프셋을 커밋하지 않은 컨슈머는 더이상 유효하지 않다고 생각하고 모니터링 목록에서 제거된다. 파티션에 대한 가장 최신 오프셋을 확인하여 expire-group 설정값보다 오래된 경우에는 모니터링 목록에서 파티션을 제거한다. 만약 토픽의 모든 파티션이 제거된 경우에는 토픽이 제거된다. 만약 컨슈머 그룹이 컨슘하고 있는 모든 토픽이 제거되면, 그룹도 Burrow에서 제거된다. 컨슈머가 오프셋 커밋을 다시 시작한다면 그 시점부터 모니터링이 다시 시작된다.

Configuration

Burrow는 viper를 사용하여 설정한다. viper는 TOML, JSON, YAML 등 다양한 포맷을 지원한다. 하지만 이 글에서는 TOML를 사용해서 설정하는법을 다룬다. 만약에 TOML에 익숙하지 않다면 TOML를 참고하길 바란다.

설정은 여러개의 하위 제목으로 구성된다.

General

[general] 설정에서는 PID 파일의 위치와 stdout/stderr 결과을 저장할 파일 위치를 설정할 수 있다.

[general]
pidfile="burrow.pid"
stdout-logfile="burrow.out"
access-control-allow-origin="mysite.example.com"
  • pidfile : 실행중인 프로세스의 PID를 저장할 경로와 파일 이름 (기본값 : burrow.pid)
  • stdout-logfile : stdout 및 stderr를 리다이렉트할 경로와 파일 이름, 이 값을 지정하지 않으면 stdout 및 stderr는 리다이렉트 되지 않는다.
  • access-control-allow-origin : HTTP 서버 응답의 Access-Control-Allow-Origin 헤더에 입력 할 값

Logging

[logging] 헤더는 로깅을 위한 설정을 포함한다. filename 설정이 제공되지 않으면 모든 로깅은 stdout으로 출력된다. 만약 filename 설정을 제공하면 로깅은 파일에 기록된다. 로깅을 위해서는 lumberjack 을 사용한다. 로깅 관련된 설정값들은 자세히 다루지 않는다. 만약 궁금하다면 Configuration를 참고하길 바란다.

Zookeeper

[zookeeper] 설정에서는 Zookeeper ensemble를 지정한다. 이를 통해 모듈의 메타데이터를 Zookeeper에 저장하며, 여러개의 Burrow 어플리케이션을 클러스터로 구성하여 실행할 수 있다. 여러개의 Burrow 어플리케이션 중 오직 하나만 Notifier를 실행한다.

[zookeeper]
servers=["zkhost01.example.com:2181", "zkhost02.example.com:2181", "zkhost03.example.com:2181" ]
timeout=6
root-path=/mypath/burrow
  • servers (필수값으로 기본값은 없음) : Zookeeper 서버 주소 (최소 한 개이상을 입력해야함)
  • timeout (6) : Zookeeper 세션의 만료 시간 초과 (초 단위)
  • root-path (기본값 : /burrow/notifier) : Burrow의 znode 전체 경로, 만약 경로에 해당하는 디렉토리가 없으면 디렉토리를 생성

Profiles

Profiles은 모듈의 일부 설정을 일반화하는데 사용된다. 이것들은 TLS와 SASL configs와 같은 항목으로, 여러 모듈에서 사용되어 설정의 중복과 오류를 방지 할 수 있다. 필수는 아니지만 제공 될 때 각각에는 고유한 소제목이 있어야한다.

Client Profile

[client-profile] 설정은 카프카 클러스터 연결에 사용되는 profile을 정의한다. [client-profile] 에서는 클라이언트 버전, 클라이언트 ID, TLS 설정 및 SASL 설정을 함께 그룹화 할 수 있다. [client-profile.myprofile]과 같이 고유한 소제목을 지정해야한다. 여기서 “myprofile”은 profile을 참조할 때 사용된다.

[client-profile.myclient]
kafka-version="0.10.2"
client-id="burrow-myclient"
tls="mytlsprofile"
sasl="mysaslprofile"
  • kafka-version (필수값) : 카프카 클라이언트 버전, 유효한 버전은 다음과 같다 : 0.8, 0.8.0, 0.8.1, 0.8.2, 0.9, 0.9.0, 0.9.0.0, 0.9.0.1, 0.10, 0.10.0, 0.10.0.0, 0.10.0.1, 0.10.1, 0.10.1.0, 0.10.2, 0.10.2.0
  • client-id : 클라리언트 ID
  • tls : 이 클라이언트 설정에 사용될 TLS Profile 이름
  • sasl : 이 클라이언트 설정에 사용될 SASL Profile 이름

TLS Profile과 SASL Profile은 다루지 않는다. 만약 궁금하다면 공식 WIKI를 참고하길 바란다.

HTTPServer

[httpserver] 설정은 HTTP Server와 관련된 설정을 포함한다. 만약에 [httpserver] 설정이 없다면 Burrow는 사용가능한 포트중 하나를 랜덤으로 선택하여 서버를 시작할 것이다. (로그를 통해 확인할 수 있다) 만약 [httpserver] 설정이 있다면 고유한 소제목이 있어야 한다. (예를 들면 [httpserver.mylistener] 처럼 mylistener라는 소제목이 있어야한다)

[httpserver.mylistener]
address=":8080"
timeout=300
tls="tls-profile-name"
  • address : ip:port 형식의 문자열이다. 만약 ip 부분이 생략되어 있으면 호스트의 IP를 사용한다. port 부분이 생략되어 있으면 임의의 포트가 선택된다.
  • timeout : keepalive timeout 값
  • tls : Lister가 사용할 TLS Profile의 이름

Storage

[storage] 설정은 storage 서브시스템과 관련된 설정을 포함한다. Burrow는 스토리지 모듈을 기본값으로 올바르게 구성하기 때문에 [starage]을 따로 설정하지 않아도 된다. 따로 설정하는 경우 고유한 소제목을 포함해야 한다. 오로지 하나의 [starage] 섹션만 허용이 된다.

[storage.mystorage]
class-name="inmemory"
intervals=10
expire-group=604800
workers=20
min-distance=1
group-whitelist=".*"
  • class-name (필수값) : 모듈 타입의 이름으로 “inmemory”만 허용된다.
  • intervals (기본값 : 10) : 각 파티션에 대해 저장할 오프셋 수입니다.
  • expire-group (기본값 : 7일): 이 시간동안 오프셋을 커밋하지 않으면 그 파티션은 모니터링 목록에서 제거된다.
  • worker (기본값 : 20) : goroutines의 worker의 수. 스토리지 모듈에서 더 많은 병렬 처리를 제공하기 위해 증가 될 수 있다.
  • min-distance (기본값 : 0) : 이 시간보다 자주 발생하는 오프셋 커밋은 병합된다. 예를 들어 이 값이 3이면 3초동안 발생한 커밋은 병합되어 하나로 저장된다. interval 설정과 함께 사용하면 오프셋 윈도우의 최소 시간을 설정할 수 있다.
  • group-whitelist : 지정된 경우, 정규 표현식과 일치하지 않는 그룹의 데이터는 무시한다.

Evaluator

[evaluator]는 evaluator 서스시스템과 관련된 설정을 포함하고 있다. Burrow는 evaluator 모듈을 기본값으로 올바르게 구성하므로이 [evaluator]을 따로 설정하지 않아도 된다. 만약 설정했다면 고유한 소제목을 포함하고 있어야한다. 그리고 오로지 하나의 [evaluator] 세션만 허용된다.

[evaluator.mystorage]
class-name="caching"
expire-cache=10
  • class-name (필수값) : 모듈 타입의 이름으로 “caching”만 허용된다.
  • expire-cache (기본값 : 604800) : 평가 결과를 캐싱할 시간 (초)

Clusters

[cluster]는 토픽과 오프셋 정보를 가져올 하나의 카프카 클러스터를 설정한다. 이 섹션을 설정할 필요는 없지만, 설정하지 않으면 Burrow가 어떤 작업도 하지 않는다. 설정했다면 고유한 소제목을 포함하고 있어야한다. 소제목은 다른 파트의 설정에서 해당 클러스터를 참조할 때 사용된다. 또한 HTTP 요청이나 알림에서도 소제목이 사용된다. 원하는 만큼 [cluster] 세션을 설정할 수 있다. 클러스터 설정은 토픽 목록과 클러스터 오프셋만 가져온다. 컨슈머 그룹에 대한 정보를 얻기 위해서는 [consumer] 섹션을 반드시 설정해주어야 한다.

“kafka” 클러스터 모듈은 하나의 카프카 클러스터에 연결된다. 그리고 토픽의 정보를 지속적으로 가져온다. 각 파티션에 대한 오프셋은 Storage 서브 시스템에 저장되어 그룹의 상태를 평가하는데 사용된다.

[cluster.myclustername]
class-name="kafka"
servers=[ "kafka01.example.com:10251", "kafka02.example.com:10251", "kafka03.example.com:10251" ]
client-profile="profile-name"
topic-refresh=120
offset-refresh=30
  • class-name : 클러스터 모듈 타입의 이름으로 “kafka”만 허용된다.
  • servers : 카프카 클러스터 서버 주소
  • client-profile : client Profile 세션의 이름. 지정되지 않으면 기본 설정을 사용
  • topic-refresh (기본값 : 60) : 클러스터의 토픽 목록을 얼마나 자주 업데이트 할 것인지 (초단위)
  • offset-refresh (기본값 : 10) : 각 파티션의 오프셋을 얼마나 자주 업데이트 할 것인지 (초단위)

Consumers

[consumer]은 컨슈머 그룹 오프셋과 정보를 가져올 단일 레포지토리를 설정한다. 이 섹션을 설정하지 않아도 되지만, 설정하지 않으면 Burrow가 많은 작업을 하지 않게 된다. 설정했다면 고유한 소젝목을 포함하고 있어야 한다. 소제목을 로깅을 할 때 사용된다. 주어진 클러스터에 원하는만큼의 [consumer] 섹션을 구성 할 수 있다.

[consumer.myconsumers]
class-name="kafka"
cluster="myclustername"
servers=[ "kafka01.example.com:10251", "kafka02.example.com:10251", "kafka03.example.com:10251" ]
client-profile="profile-name"
offsets-topic="__consumer_offsets"
start-latest=true
group-whitelist=".*"
group-blacklist="^not-this-group$"
  • class-name (필수값) : 이것은 클러스터 모듈 타입의 ​​이름이다. “kafka” 혹은 “kafka_zk”을 지정해야한다. “kafka”는 브로커로부터 컨슈머 그룹의 오프셋 정보를 가져온다. 반면에 “kafka_zk”는 Zookeeper에서 컨슈머 그룹의 오프셋 정보를 가져온다.
  • cluster (필수값) : 이 모듈의 컨슈머가 속한 클러스터의 이름이다.
  • servers (필수값) : 카프카 클러스터 주소
  • client-profile : client Profile 세션의 이름. 지정되지 않으면 기본 설정을 사용
  • offsets-topic (기본값 : __consumer_offsets) : 컨슈머 오프셋을 저장하는 인터널 토픽 이름
  • start-latest (기본값 : false) : 만약 이 값이 true라면 오프셋 토픽을 읽을때 최신 오프셋부터 읽는다. 그렇지 않으면 처음부터 오프셋 토픽을 읽는다.
  • group-whitelist : 지정된 경우 정규 표현식과 일치하는 그룹에 대해서만 오프셋을 전송
  • group-blacklist : 지정된 경우 정규식과 일치하지 않는 그룹에 대해서만 오프셋을 보낸다. whitelist 이후에 처리된다.
“kafka” consumer module

“kafka” 컨슈머 모듈은 하나의 카프카 클러스터에 연결되고 __consumer_offsets 토픽을 컨슘한다. 이 토픽은 internal 토픽으로 모든 컨슈머의 오프셋과 그룹 메타데이터가 저장된다. 이 정보는 Storage Subsystem에 저장되고 그룹 상태 평가에 사용된다.

Notifiers

[notifier]은 그룹 상태에 대한 알림을 보내는 방법을 설정한다. 이 세션을 반드시 설정하지 않아도 된다. 만약 설정한 경우에는 고유한 소제목을 포함해야 한다. 소제목은 이 모듈이 로깅을 할 때 사용된다. [notifier] 세션은 원하는 만큼 설정할 수 있다.

[notifier.mynotify]
class-name="http"
interval=30
threshold=3
group-whitelist="^important-group-prefix.*$"
group-blacklist="^not-this-group$"
extras={ key1="value1", key2="value2" }2" }
send-close=true
template-open="path/to/file1.tmpl"
template-close="path/to/file2.tmpl"
(add additional class configs here)
  • class-name : 모듈 타입의 이름
    • http : HTTP 요청을 보낸다
    • email : Email을 보낸다.
  • interval (기본값 : 60) : 하나의 그룹에 대한 알림 전송 사이의 대기 시간 (초 단위)
  • threshold (기본값 : 2) : 알림을 보낼 그룹의 최소 상태, 상태에 대해서는 아래에서 더 자세히 설명한다. 기본값이 2 (Warning)이기 때문에 최소 Warning 상태가 되어야 알림을 보낸다.
  • group-whitelist : 지정된 경우 정규식과 일치하는 그룹에 대해서만 알림을 보낸다.
  • group-blacklist : 정규식과 일치하지 않는 그룹에 대해서만 알림을 보낸다. whitelist가 먼저 처리되고 그 다음에 처리된다.
  • extras : 보낼 메시지의 템플릿을 컴파일 할 때 사용할 수 있는 맵
  • send-close (기본값 : false) : true인 경우에 그룹의 상태가 WARN 이상에서 OK로 되었을 때 template-close 템플릿을 사용해서 알림을 보낸다.
  • template-open (필수값) : threshold 상태를 넘어간 그룹에 대한 알람 메시지를 컴파일하는데 사용되는 템플릿 파일의 경로와 파일 이름.
  • template-close : OK 상태로 바뀐 그룹에 대한 알람 메시지를 컴파일하는데 사용되는 템플릿 파일의 경로와 파일 이름. (send-close가 true인 경우에만 의미가 있다)
  • url-open : threadhold 상태를 넘어간 그룹에 대한 HTTP 요청을 보낼 URL
  • method-open : HTTP 메소드
  • url-close : 나쁜 상태(WARN 이상)에서 OK로 전환된 그룹에 대한 요청 보낼 URL (send-close가 true인 경우)
  • method-close : HTTP 메소드
  • timeout (5초) : HTTP 연결 timeout (초단위)
  • keepalive (300초) : keepalive을 사용하고 커넥션을 얼마나 유지할 것인지에 대한 값 (초 단위)

여기서는 Template에 대해서 자세히 다루진 않는다. Template을 커스터마이징 하려면 Template를 참고하길 바란다.

StatusConstant

StatusConstant는 파티션이나 그룹의 상태를 나타낸다. 0은 그룹을 찾을수 없음을 나타내며, 숫자가 클수록 더 나쁜 상태에 있는 것이다.

  • StatusNotFound : 0 => StatusNotFound indicates that the consumer group does not exist. It is not used for partition status.
  • StatusOK : 1 => StatusOK indicates that a partition is in a good state. For a group, it indicates that all partitions are in a good state.
  • StatusWarning : 2 => StatusWarning indicates that a partition is lagging - it is making progress, but falling further behind. For a group, it indicates that one or more partitions are lagging.
  • StatusError : 3 => StatusError indicates that a group has one or more partitions that are in the Stop, Stall, or Rewind states. It is not used for partition status.
  • StatusStop : 4 => StatusStop indicates that the consumer has not committed an offset for that partition in some time, and the lag is non-zero. It is not used for group status.
  • StatusStall : 5 => StatusStall indicates that the consumer is committing offsets for the partition, but they are not increasing and the lag is non-zero. It is not used for group status.
  • StatusRewind : 6 => StatusRewind indicates that the consumer has committed an offset for the partition that is less than the previous offset. It is not used for group status.

Http request consumer group status

Burrow는 컨슈머 그룹의 상태를 조회할 수 있는 HTTP 엔드포인트를 제공한다.

Usage

이 엔드포인트는 컨슈머 그룹의 현재 상태를 리턴한다. 현재 상태는 컨슘하고 있는 모든 파티션의 평가를 기반으로 한다. 평가는 요청시에 수행되며, 결과는 Consumer LAG 평가 규칙에 의해 결정된다. 2가지 버전의 요청이 있다. 엔드포인트가 “/status” 인 경우에는 현재 bad 상태인 파티션만 리턴한다. 반면에 “/lag” 엔드포인트는 파티션의 상태와 관계없이 컨슈머가 컨슘하고 있는 모든 파티션이 리턴된다.

URL path

  • GET /v3/kafka/(cluster)/consumer/(group)/status
  • GET /v3/kafka/(cluster)/consumer/(group)/lag

Parameters

  • cluster : 카프카 클러스터의 이름
  • group : 컨슈머 그룹의 이름

Response

Response는 status를 포함한다. status는 결과를 포함하고 있으며 파티션 상태에 대한 세부 정보가 포함되어 있다.

{
  "error": false,
  "message": "consumer group status returned",
  "status": {
    "cluster": "clustername",
    "group": "groupname",
    "status": "WARN",
    "complete": 1.0,
    "maxlag": {
      "complete": 1,
      "current_lag": 0,
      "end": {
        "lag": 25,
        "offset": 2542,
        "timestamp": 1511780580382
      },
      "owner": "",
      "partition": 0,
      "start": {
        "lag": 20,
        "offset": 2526,
        "timestamp": 1511200836090
      },
      "status": "WARN",
      "topic": "topicA"
    },
    "partitions": [
      {
        "complete": 1,
        "current_lag": 0,
        "end": {
          "lag": 25,
          "offset": 2542,
          "timestamp": 1511780580382
        },
        "owner": "",
        "partition": 0,
        "start": {
          "lag": 20,
          "offset": 2526,
          "timestamp": 1511200836090
        },
        "status": "WARN",
        "topic": "topicA"
      }
      ...
    ]
  },
  "request": {
    "url": "/v3/kafka/clustername/consumer/groupname/status",
    "host": "responding.host.example.com",
  }
}

status 필드는 그룹이나 파티션의 상태를 표현한다. 상태는 아래와 같다.

  • NOTFOUND - 해당 그룹을 찾을 수 없다.
  • OK - 그룹이나 파티션이 정상적인 상태이다.
  • WARN - 그룹이나 파티션의 상태가 위험한 경우. 예를 들어 오프셋이 증가하고 있지만 LAG도 같이 증가하는 경우
  • ERR - 그룹이 에러 상태이다. 예를 들어 오프셋이 정지했는데 LAG이 0이 아닌 경우
  • STOP - 파티션이 멈춘경우. 예를 들어 오랜 시간동안 오프셋이 커밋되지 않은 경우
  • STALL - 파티션이 갇힌경우. 예를 들어 오프셋이 커밋되었지만 오프셋이 증가하지 않고, LAG은 0이 아닌 경우

maxlag 필드는 현재 가장 높은 종료 지연을 갖는 파티션의 상태 객체를 포함한다.

partitions 필드는 각 파티션의 세부 정보 및 오프셋 커밋 정보를 포함한다. 아래오 같은 필드를 포함하고 있다.

  • topic : 토픽 이름
  • partition : 파티션 ID
  • owner : the client host that owns this partition
  • complete : Burrow가 이 파티션에 대해 가지고 있는 정보에 대한 백분율 (0~1사이에 값)
  • current_lag : 이 파티션의 현재 lag
  • status : 이 파티션의 상태
  • start : 윈도우내에 첫번째 오프셋
  • end : 윈도우내의 마지막 오프셋

start와 end가 포함하고 있는 정보는 같다. start와 end는 오프셋이 커밋된 시점의 타임스탬프값과 오프셋값, 그리고 오프셋이 커밋된 시점에 lag 정보를 포함하고 있다.

Burrow Issue

Consumer start-latest

consumer 설정 중에 start-latest가 있다. 이 설정은 __consumer_offset 토픽을 처음부터 읽을지 혹은 최신부터 읽을지를 결정한다.

  • start-latest=true : __consumer_offset 토픽을 최신부터 읽는다.
    • 장점 :
    • 단점 : Burrow가 시작한 이후 컨슈머가 오프셋을 커밋 하지 않는다면, Burrow를 통해 해당 컨슈머 그룹의 상태를 알 수 없다.
  • start-latest=false : __consumer_offset를 처음부터 읽는다.
    • 장점 : Burrow가 시작한 이후 inactive한 컨슈머 그룹의 상태도 Burrow를 통해 알 수 있다.
    • 단점 : __consumer_offset 토픽을 처음부터 읽기 때문에 처음에 Burrow가 부정확한 Consumer group 정보를 갖게 된다.

start-latest를 false로 한다면 Burrow 시작 시점에 잘못된 알람이 갈 수도 있다.

[consumer.myconsumers]
class-name="kafka"
cluster="myclustername"
start-latest=true

minumum-complete

Burrow는 오프셋 윈도우가 가득차기도 전에 consumer의 상태를 계산한다. 이는 잘못된 정보로 이어질 수 있다. (특히 burrow의 시작 시점에는 오프셋 윈도우가 가득차지 않기 때문에 시작 시점에 컨슈머의 상태를 잘못 계산할 수 있다) complete 값은 오프셋 윈도우가 얼마나 가득찼는지를 나타낸다. (0~1)

오프셋 윈도우가 가득차기 전에 consumer의 상태를 잘못계산하는 것을 방지하기 위한 설정이 minumum-complete이다. minumum-complete은 complete의 최소값을 설정한다. 만약에 complete값이 minumum-complete 값보다 작다면 해당 파티션의 상태는 무조건 OK가 된다.

[evaluator.default]
class-name="caching"
minimum-complete=0.20

출처

Associated Projects

그 외에도 더 다양한 프로젝트가 있지만 많이 사용되지는 않는거 같음

출처 및 참고자료