신뢰성 보장

  • 보장: 서로 다른 상황에서도 시스템이 지킬 것이라고 보장되는 행동
  • 아파치 카프카가 보장하는 것
    • 파티션 안의 메시지들 간에 순서를 보장한다.
      • 만약 메시지 A 다음에 B가 쓰여졌다면, 동일한 프로듀서가 동일한 파티션에 썼을 경우, 카프카는 B의 오프셋이 A보다 큰 것을 보장한다.
      • 컨슈머 역시 A를 읽어온 다음에 B를 읽게 된다.
    • 클라이언트가 쓴 메시지는 모든 인-싱크 레플리카의 파티션에 쓰여진 뒤에야 커밋된 것으로 간주한다.
      • 프로듀서는 메시지가 완전히 커밋된 다음 응답이 올지, 리더에게 쓰여진 다음 응답이 오지 아니면 네트워크로 전송된 다음 바로 응답이 올지 선택할 수 있다.
    • 커밋된 메시지들은 최소 1개의 작동 가능한 레플리카가 남아 있는 한 유실되지 않는다.
    • 컨슈머는 커밋된 메시지만 읽을 수 있다.
  • 이러한 보장들만으로는 시스템 전체를 완전히 신뢰성 있게 만들어 주지는 못한다.
    • 신뢰성 있는 시스템을 구축하는 데는 트레이 오프가 있고, 카프카는 이러한 트레이드오프들을 조절할 수 있도록 개발자나 운영자가 설정 매개변수를 조절함으로써 어느 정도의 신뢰성이 필요한지를 결정할 수 있도록 개발되었다.
    • 이러한 트레이드오프는 대개 메시지를 저장하는데 있어서의 신뢰성과 일관성이 우선이냐, 아니면 가용성, 높은 처리량, 낮은 지연, 하드웨어 비용과 같은 다른 고려사항이 우선이냐의 문제인 경우가 많다.

복제

  • 하나의 메시지를 여러 개의 레플리카에 씀으로써 카프카는 크래시가 나더라도 메시지의 지속성을 유지한다.
  • 동기화가 살짝 늦은 인-싱크 레플리카는 컨슈머를 느리게 만들 수 있다.
    • 이유: 프로듀서와 컨슈머는 메시지가 커밋되기 전, 모든 인-싱크 레플리카가 해당 메시지를 받을 때까지 기다려야 하기 때문이다.

브로커 설정

  • 브로커 단위에 적용되어 시스템 안의 모든 토픽들을 제어할 수도 있고 토픽 단위에서 적용되어 특정 토픽을 제어할 수도 있다.

복제 팩터

  • 2가지 프로퍼티
    • replication.factor: 토픽 단위 설정
    • default.replicatoin.factor: 자동으로 생성되는 토픽들에 적용되는 브로커 단위 설정
  • 예시: 복제 팩터가 3이라면, 각 파티션이 3대의 서로 다른 브로커에 3개 복제된다는 것을 의미한다.
  • 복제 팩터 역시 변경이 가능하다.
  • 복제 팩터가 N이면
    • 장점: N-1개의 브로커가 중단되더라도 토픽의 데이터를 읽거나 쓸 수 있다.
    • 단점: 최소한 N개의 브로커가 필요한 뿐더러 N개의 복사본을 저장하므로 N배의 디스크 공간이 필요하다.
  • 토픽에 몇 개의 레플리카가 적절할지 결정할 고려 사항
    • 가용성: 레플리카 수가 많을수록 가용성이 늘어난다.
    • 지속성: 복사본이 더 많을수록 모든 데이터가 유실될 가능성은 줄어든다.
    • 처리량: 레플리카가 추가될 때마다 브로커간 트래픽이 늘어난다. 클러스터의 크기와 용량을 산정할 때는 이를 고려할 필요가 있다.
    • 종단 지연: 레플리카 수가 더 많을수록 이들 중 하나가 느려짐으로써 컨슈머까지 함께 느려질 가능성은 높아진다.
    • 비용: 더 많은 레플리카를 가질수록 저장소와 네트워크에 들어가는 비용 역시 증가한다. 많은 저장 시스템들이 각 블록을 3개로 복제해서 저장하는 경우가 많기 때문에 카프카를 설정할 때 복제팩터를 2로 잡아줌으로써 저장 비용을 줄이는 것이 합리적인 경우가 있다.
  • 레플리카의 위치 역시 중요하다.
    • 이유: 같은 파티션의 모든 레플리카들이 같은 랙에 설치되어 있는 브로커들에 저장되었는데 랙 스위치가 오작동할 경우, 복제 팩터하고는 상관없이 해당 파티션을 사용할 수 없게 될 것이다.
    • 결론: 랙 단위 사고를 방지하기 위해서 브로커들을 서로 다른 랙에 배치한 뒤 broker.rack 브로커 설정 매개변수에 랙 이름을 잡아 줄 것을 권장한다.

언클린 리더 선출

  • unclean.leader.election.enable
    • 아웃-오브-싱크 레플리카가 리더가 될 수 있는지 여부
    • 기본값은 false
  • ‘클린’의 의미: 새 리더를 선출할 때 커밋된 데이터의 유실이 없음을 의미
    • 인-싱크 레플리카 중에 리더를 선출하면 커밋된 데이터가 유실되지 않는다.
  • 아웃-오브-싱크 레플리카가 리더가 될 수 있도록 허용할 경우 데이터 유실과 일관성 깨짐의 위험성이 있다.
    • 하지만, 아웃-오브-싱크 레플리카가 리더가 될 수 없는 경우 모든 인-싱크 레플리카가 오프라인 상태일 때 복구되는 것을 기다려야해서 가용성이 줄어든다.
  • 운영자 입장에서는 이러한 상황이 닥쳤을 때 파티션을 사용 가능한 상태로 만들기 위해서 true로 바꾼뒤 클러스터를 시작하는 것도 가능하다.
    • 이 경우 클러스터가 복구된 뒤 설정값을 false로 되돌려주는 것을 잊지 말자.

최소 인-싱크 레플리카

  • min.insync.replicas
    • 토픽과 브로커 단위 모두 설정할 수 있다.
  • 카프카가 보장하는 신뢰성에 따르면, 데이터는 모든 인-싱크 레플리카에 쓰여진 시점에 커밋된 것을 간주된다.
    • ‘모든’이 단 한 개의 레플리카를 의미할 수도 있는데도 말이다.
    • 한 개의 레플리카만 인-싱크인 상태에서 이 레플리카가 작동 불능에 빠지면 데이터는 유실될 수 있다.
  • 커밋된 데이터를 2개 이상의 레플리카에 쓰고자 한다면 min.insync.replicas를 2로 잡아주면 된다.
    • 상황1: 3개의 레플리카가 모두 인-싱크 상태라면, 모든 것이 정상적으로 작동한다.
    • 상황2: 하나의 레플리카가 작동 불능에 빠져도, 모든 것이 정상적으로 작동한다.
    • 상황3: 2개의 레플리카가 작동 불능에 빠지면, 브로커는 더이상 쓰기 요청을 받을 수 없다. 대신, 데이터를 전송하고자 시도하는 프로듀서는 NotEnoughReplicasException을 받게 된다.
  • min.insync.replicas만큼 레플리카가 인-싱크 상태가 아니라면 해당 레플리카는 사실상 읽기 전용이 된다.

레플리카를 인-싱크 상태로 유지하기

  • 레플리카가 아웃-오브-싱크 상태가 될 수 있는 두 가지 이유
    • 레플리카가 주키퍼와의 연결이 끊어짐
    • 리더 업데이트 내역을 따라가는 데 실패해서 복제 랙이 발생
  • 카프카는 이 두 조건에 대한 카프카 클러스터의 민감도를 조절할 수 있는 브로커 설정을 가지고 있다.
  • zookeerper.session.timeout.ms
    • 설명: 카프카 브로커가 주키퍼로 하트비트 전송을 멈출 수 있는 최대 시간을 정의한다.
    • 기본값: 2.5.0부터 6초에서 18초로 증가했다.
    • 조정 기준: 가비지 수집이나 네트워크 상황과 같은 무작위적인 변동에 영향을 받지 않을 만큼 높게, 하지만 실제로 작동이 멈춘 브로커가 적시에 탐지될 수 있을 만큼 충분히 낮게 설정될 필요가 있다.
  • replica.lag.time.max.ms
    • 설명: 리더로부터 데이터를 읽어 오지 못하는 최대 시간을 정의한다.
    • 기본값: 2.5.0에서 10초에서 30초로 증가했다.
    • 주의점: 컨슈머의 최대 지연에도 영향을 준다. 기본값 기준으로 모든 레플리카에 도착햇허 컨슈머가 이 메시지를 읽을 수 있게 되는데 최대 30가 걸릴 수 있다.

디스크에 저장하기

  • 카프카는 세그먼트를 교체할 때와 재시작 직전에만 메시지를 디스크로 플러시하며, 그 외의 경우에는 리눅스이 페이지 캐시 기능에 의존한다.
    • 배경: 각각 데이터의 복제본을 가지고 있는, 서로 다른 랙이나 가용 영역에 위치한 세 대의 장비가 리더의 디스크에 메시즈를 쓰는 것보다 더 안전하다는 판단이 있다.
  • 하지만, 브로커가 디스크에 더 자주 메시지를 저장하도록 설정하는 것은 가능하다.
    • flush.messages: 디스크에 저장되지 않는 최대 메시지 수
    • flush.ms: 얼마나 자주 디스크에 메시지를 저장하는지

신뢰성 있는 시스템에서 프로듀서 사용하기

  • 신뢰성 설정을 브로커에 적용하더라도, 프로듀서 역시 신뢰성이 있도록 설정을 잡아 주지 않는다면 시스템 전체로서는 여전히 데이터가 유실될 수 있다.
  • 2가지 예시
    • 브로커에 언클린 선출 기능을 끈 상태에서, 프로듀서가 메시지를 보낼 때 acks=1 설정을 한 경우
      • 리더가 프로듀서에게 “메시지가 성공적으로 쓰여졌다.“라고 응답을 보낸 직후 크래시가 나서 데이터가 레플리카로 복제되지 않으면, 프로듀서 입장에서 보면 메시지는 유실될 것이다.
    • 브로커에 언클린 선출 기능을 끈 상태에서, 브로커가 메시지를 보낼 때 acks=all 설정을 했지만, “Leader not Available” 응답에 대한 재시도를 하지 않은 경우
      • 프로듀서가 에러를 처리하지 않고 쓰기가 성공하지 성공할 때까지 재시도도 하지 않은 경우, 메시지는 유실될 수 있다.
  • 카프카에 메시지를 쓰는 애플리케이션을 개발하는 모든 이들은 신경써야 할 중요한 2개가 있다.
    • 신뢰성 요구 조건에 맞는 올바른 acks 설정을 사용한다.
    • 설정과 코드 모두에서 에러를 올바르게 처리한다.

응답 보내기

  • acks=0
    • 프로듀서가 네트워크로 메시지를 전송한 시점에 메시지가 카프카에 성공적으로 쓰여진 것으로 간주한다.
    • 보장: 우리가 전송하는 객체가 직렬화될 수 없거나 네트워크 카드가 오작동할 경우 여전히 에러를 받는다.
    • 문제점: 파티션이 오프라인이거나, 리더 선출이 진행중이거나, 심지어 전체 카프카 클러스터가 작동 불능인 경우 에러가 발생하지 않는다.
  • acks=1
    • 리더가 메시지를 받아서 파니션 데이터 파일에 쓴 직후 응답 또는 에러를 보낸다.
    • 문제점1: 일부 메시지가 리더에 성공적으로 쓰여서 클라이언트로 응답이 간 상태에서 팔로워로 복제가 완료되기 전에 리더가 정지하거나 크래쉬 날 경우에 데이터가 유실될 수 있다.
    • 문제점2: 메시지를 복제하는 속도보다 더 빨리 리더에 쓸 수 있기 때문에 불완전 복제 파티션이 발생할 수 있다.
  • acks=all
    • 리더가 모든 인-싱크 레플리카가 메시지를 받아갈 때까지 기다렸다가 응답하거나 에러를 보낸다.
      • 브로커의 min.insync.replicas 설정과 함께, 이 설정은 응답이 오기전까지 얼마나 많은 레플리카에 메시지를 복제될 것인지를 조절할 수 있게 해준다.
    • 장점: 프로듀서는 메시지가 완전히 커밋될 때까지 메시지를 재전송해서 가장 안전한 옵션이다.
    • 문제점: 프로듀서는 모든 인-싱크 레플리카가 메시지를 받을 때까지 가디린 뒤에야 해당 메시지 배치에 완료 표시를 하고 작업을 진행하기 때문에 지연이 가장 길어지는 옵션이다.

프로듀서 재시도 설정하기

  • 프로듀서의 에러 처리는 두 부분으로 나누어지는데, 바로 프로듀서가 자동으로 처리해주는 에러와 프로듀서 라이브러리를 개발자들이 처리해야 하는 에러다.
    • 예시:
      • LEADER_NOT_AVAILABLE 에러 코드를 리턴한 경우, 프로듀서는 전송을 재시도할 수 있다.
      • INVALID_CONFIG 에러 코드를 리턴할 경우, 같은 메시지를 재전송한다고 해서 설정이 변경되지 않는다.
  • 메시지가 유실되지 않는 것이 목표일 경우, 가장 좋은 방법은 재시도 가능한 에러가 발생했을 경우 프로듀서가 계속해서 메시지 전송을 재시도하도록 설정하는 것이다.
    • 재시도에 관한 가장 좋은 방법
      • 재시도 수를 기본 설정값(MAX_INT)으로 내버려 두고 메시지 전송을 포기할 때까지 대기할 수 있는 시간을 지정하는 deliver.timeout.ms 설정값을 최대로 잡아 주는 것이다.
  • 전송 실패한 메시지를 재시도하는 것은 메시지가 중복될 위험을 내포한다.
    • 원인: 실패했다고 생각했지만 실제로는 아닌 메시지와 재전송된 메시지가 모두 전송된 경우
    • 결론: 재시도는 각 메시지가 ‘최소 한 번’ 저장되도록 보장할 수 있지만, ‘정확히 한 번’은 보장할 수 없다.
    • 해결 방법: enable.idempotence=true 설정을 잡아줌으로써 프로듀서가 추가적인 정보를 레코드에 포함할 수 있도록, 그리고 이를 활용해서 브로커가 재시도로 인해 중복된 메시지를 건너뛸 수 있도록 할 수 있다.

추가적인 에러 처리

  • 다양한 종류를 에러를 에러 핸들러를 작성해 자유롭게 처리할 수 있다.

신뢰성 있는 시스템에서 컨슈머 사용하기

  • 컨슈머는 카프카에 커밋된 데이터만 읽을 수 있다. 즉, 컨슈머는 일관성이 보장되는 데이터만 읽는다.
  • 컨슈머가 해야 할 일은 어느 메시지까지 읽었고 어디까지는 읽지 않았는지를 추적하는 것이다.
  • 컨슈머가 읽는 과정
      1. 컨슈머는 메시지를 배치 단위로 읽어온 뒤 배치별로 마지막 오프셋을 확인한다.
      1. 브로커로부터 받은 마지막 오프셋 값에서 시작하는 다른 메시지 배치를 요청한다.
    • 이렇게 함으로써 컨슈머는 메시지 누락 없이, 언제나 새로운 데이터를 올바른 순서로 읽을 수 있다.
  • 컨슈머는 각 파티션에 대해서 어디까지 읽었는지를 커밋해둬야, 해당 컨슈머나 다른 컨슈머가 재시작한 뒤에도 어디서부터 작업을 계속할지 알 수 있다.
  • 컨슈머가 메시지를 누락할 수 있는 경우는 처리 완료하지 않은 이벤트들의 오프셋을 커밋하는 경우다.

신뢰성 있는 처리를 위해 중요한 컨슈머 설정

  • group.id: 같은 그룹 ID를 갖는 두 개의 컨슈머가 같은 토픽을 구도할 경우, 각각의 컨슈머에는 해당 토픽 전체 파티션의 서로 다른 부분집합이 할당되므로 각각은 서로 다른 부분의 메시지만 읽게 된다.
  • auto.offset.reset: 커밋된 오프셋이 없을 때나 컨슈머가 브로커에 없는 오프셋을 요청할 때 컨슈머가 어떻게 해야 할지를 결정한다.
    • earliest를 설정한 경우: 유효한 오프셋이 없는 한 컨슈머는 파티션의 맨 앞에서부터 읽기를 시작하게 된다.
      • 장점: 데이터 유실을 최소화할 수 있다.
      • 단점: 컨슈머는 많은 메시지들을 중복 처리하게 될 수 있다.
    • latest를 설정한 경우: 파티션의 끝에서부터 읽기를 시작한다.
      • 장점: 중복 처리는 최소화할 수 있다.
      • 단점: 컨슈머가 일부 메시지는 누락할 것이다.
  • enable.auto.commit: 자동 오프셋 커밋 기능은 우리가 처리하지 않은 오프셋을 실수로 커밋하는 사태가 발생하지 않도록 보장해준다.
    • 자동 오프셋 커밋 기능 단점: 메시지 중복 처리를 우리가 제어할 수 없다. 읽어온 메시지 중 일부만을 처리했고 아직 자동 커밋이 되지 않은 상태에서 컨슈머가 멈추면, 컨슈머를 다시 시작시켰을 때 메시지 중복 처리를 피할 수 없다.
  • auto.commit.interval.ms: 만약 오프셋 자동 커밋을 활성화한 경우, 이 설정을 통해 커밋되는 주기를 설정할 수 있다.
    • 기본값: 5초
    • 컨슈머가 poll()을 호출할 때 이전의 자동 커밋 시각으로부터 설정한 시간이 지났는지 확인하고 지났다면 커밋을 하게된다.
    • 자주 커밋할 수 록 오버헤드 역시 늘어나지만 컨슈머가 정지했을 때 발생할 수 있는 중복의 수는 줄어든다.

컨슈머에서 명시적으로 오프셋 커밋하기

  • 데이터를 신뢰성 있게 다루는 컨슈머를 개발할 때 고려해야 할 중요한 사항들을 알아본다.
    1. 메시지 처리 먼저, 오프셋 커밋은 나중에
    1. 커밋 빈도는 성능과 크래시 발생시 중복 개수 사이의 트레이드오프다.
    • poll 루프 안에 여러 번 커밋하거나 루프가 몇 번 지나갈 때마다 커밋하는 것 사이에서 선택할 수 있다.
    • 커밋 작업은 상당한 성능 오버헤드를 수반한다.
    • 메시지를 읽어올 때마다 커밋하는 방식은 매우 낮은 빈도로 메시지가 들어오는 토픽에나 사용할 수 있다.
    1. 정확한 시점에 정확한 오프셋을 커밋하자
    • 폴링 루프 중간에서 커밋할 때 흔히 하는 실수로 마지막으로 처리된 메시지의 오프셋이 아닌, 마지막으로 읽어온 메시지의 오프셋을 커밋하는 것이다.
    • 언제나 처리가 완료된 메시지의 오프셋을 커밋하는 것이 중요하다.
    1. 리밸런스
    • 애플리케이션을 설계할 때는 컨슈머 리밸런스가 발생할 것이라는 것과 이것을 적절히 처리해 줄 필요가 있다는 점을 기억해야 한다.
    • 예시: 할당된 파티션이 해제되기 전에 오프셋을 커밋하고, 새로운 파티션이 할당되었을 때 애플리케이션이 보유하고 있던 상태가 있다면 이를 삭제해주는 작업을 작성해야한다.
    1. 컨슈머는 재시도를 해야 할 수도 있다.
    • 상황에 따라 poll()을 호출하고 레코드를 처리한 뒤, 일부 레코드는 처리가 완료되지 않아서 나중에 처리되어야할 수 있다.
      • 예시: 카프카에서 읽어 온 레코드를 데이터베이스에 쓰려고하는데, 정작 그 데이터베이스가 현재 사용 가능하지 않아서 나중에 재시도해야 할 수 있다.
    • 만약 #30 처리에 실패한 상태에서 #31 처리에 성공할 경우, #31의 오프셋을 커밋하면 안 된다.
    • 시도가능한 패턴
      • 방법1: 마지막으로 처리에 성공한 레코드의 오프셋을 커밋하고, 나중에 처리해야 할 레코드들을 버퍼에 저장한다. 컨슈머의 pause() 메서드를 호출해서 추가적인 poll() 호출이 데이터를 리턴하지 않도록 한 뒤, 레코드 처리를 계속한다.
      • 방법2: 별도의 토픽에 쓴 뒤 계속 진행한다.
        • 별도의 컨슈머 그룹을 사용해서 재시도 토픽에 저장한 레코드들을 처리하거나, 주 토픽과 재시도 토픽을 모두 구독하는 컨슈머를 하나 둬서 재시도 사이에는 재시도 토픽 구독을 잠시 멈추도록 할 수도 있다.
        • 이 패턴은 많은 메시지 교환 시스템에서 사용되어 온 데드 레터 큐 시스템과 비슷하다.
    1. 컨슈머가 상태를 유지해야 할 수도 있다.
    • 애플리케이션에 따라서는 poll() 메서드 호출 간에 상태를 유지해야 할 수도 있다.
    • 예시: 이동평균을 계산하고자 한다면, 새 메시지들은 폴링해 올 때마다 평균 값을 업데이트 해줘야 한다.

시스템 신뢰성 검증하기

설정 검증하기

  • 우리가 선택한 구상이 요구 조건을 충족시킬 수 있는지 확인하는 데 도움이 된다.
  • 시스템의 예상 작동을 추론해 보기 위한 좋은 방법이다.
  • 카프카는 이러한 검증 작업을 위한 두 개의 중요한 툴을 포함한다.
  • VerifiableProducer, VerifiableConsumer 클래스가 포함되어 있는데, 이들 각각은 명렬줄 툴 형태로든 자동화된 테스팅 프레임워크에 포함된 형태로든 실행히 가능하다.
    • 검증용 프로듀서에는 akcs, retries, delivery.timeout.ms 등의 설정값을 잡아줄 수 있을 뿐더러 메시지를 쓰는 속도 역시 정해줄 수 있다.
    • 검증용 컨슈머는 이와 반대 방향으로 확인 작업을 수행한다.
  • 어떤 테스트를 할 것인지도 고려해야 한다.
    • 예시1: 리더를 정지시키면 어떻게 될까? 프로듀서와 컨슈머가 평상시처럼 작동을 재개하는데까지 얼마나 걸릴까?
    • 예시2: 컨트롤러가 재시작한 뒤 시스템이 재개되는 데 얼마나 걸릴까?
    • 예시3: 메시지 유실 없이 브로커들을 하나씩 재시작시킬 수 있을까?
    • 예시4: 한 파티션의 모든 레플리카들을 하나씩 중단시킨 다음 아웃-오브-싱크 상태가 된 브로커를 시작시키면 어떻게 될까? 작업을 재개하려면 어떻게 해야 할까?
  • 시나리오를 고른 뒤 검증용 프로듀서를 실행시키고, 검증용 컨슈머를 실행시키고, 해당 시나리오대로 실행해본다.
  • 아파치 카프카 소스코드 저장소는 방대한 테스트 스위트를 포함한다. 스위트 안에 포함된 많은 테스트들은 위에서 설명한 것 과같은 원리로 작동하며, 롤링 업데이트가 작동하는지의 여부를 확인하기 위해 검증용 프로듀서와 컨슈머를 사용한다.

애플리케이션 검증하기

  • 애플리케이션 로직이 카프카의 클라이언트 라이브러리와 상호작용하는 커스텀 에러 처리 코드, 오픗세 커밋, 리밸런스 리스너와 같은 곳들을 확인한다.
  • 우리는 개발 프로세스의 일부로서 애플리케이션의 통합 테스트를 수행할 것을 권장하며, 다양한 장애 상황에 대해 테스트를 수행할 것 역시 권장한다.
  • 테스트를 위해 가상의 네트워크나 디스크 장애를 발생시킬 수 잇는 좋은 툴들이 많다.

프로덕션 환경에서 신뢰성 모니터링하기

  • 프로듀서의 경우: 레코드별 에러율과 재시도율가 중요한 지표이다.
  • 컨슈머의 경우: 컨슈머 랙이 중요한 지표다.
    • 컨슈머 랙: 컨슈머가 브로커 내 파티션에 커밋된 가장 최신 메시지에서 얼마나 뒤떨어져 있는지를 나타낸다.
    • 컨슈머 랙을 확인하기 위해 링크드인이 개발한 Burrow를 사용하면 이 작업을 좀 더 쉽게할 수 있다.
  • 쓰여진 데이터가 적절한 시기에 읽혀진다는 것도 모니터링 해야한다.
    • 데이터가 적절한 시기에 읽히도록 하려면, 언제 데이터가 생성되었는지 알아야 한다.
    • 버전 0.10.0부터, 모든 메시지는 이벤트가 생성된 시점을 가리키는 타임스탬프를 포함한다.
      • 단, 이 값은 이벤트를 전송중인 애플리케이션이나 관련 설정이 잡혀 있는 브로커에 의애 재정의될 수 있음을 기억하자.
  • 클라이언트와 종단 간 데이터 흐름을 모니터링하는 것 외에도, 카프카 브로커는 브로커가 클라이언트로 보내는 에러 응답률을 보여주는 지표들을 포함한다.
    • kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSeckafka.server:type=BrokerTopicMetrics,name=FailedFetchReqeustsPerSec 지푯값을 수집할 것을 권장한다.