Under-Replicated Partitions — 단 하나만 봐야 한다면 이 지표
Kafka: The Definitive Guide (O'Reilly, 2017, 1st Edition) — Neha Narkhede, Gwen Shapira, Todd Palino Chapter 10: Monitoring Kafka — Kafka Broker Metrics / Under-Replicated Partitions (Cluster-level problems / Host-level problems) (pp.213-220)
브로커에서 지표를 딱 하나만 볼 수 있다면 그것은 under-replicated partitions여야 한다. 이 모듈은 이 지표의 정의와 MBean, 값이 0이 아닐 때 원인을 좁혀 가는 진단 순서(브로커 다운인지 성능 문제인지 → 한 대 문제인지 클러스터 문제인지 → 불균형인지 자원 고갈인지 → 하드웨어·프로세스 경합·설정 차이인지)를 다룬다. 실제로 브로커 장애를 진단할 때 가장 많이 쓰는 흐름이다.
지표의 정의와 첫 해석
under-replicated partitions는 클러스터의 각 브로커가 제공하는 지표로, 그 브로커가 리더 복제본을 맡고 있는 파티션 중에서 팔로워 복제본이 따라잡지 못한 파티션의 개수를 센다.
- 지표 이름: Under-replicated partitions - JMX MBean: kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions - 값 범위: 0 이상의 정수
이 하나의 값이 브로커 다운부터 자원 고갈까지 매우 다양한 문제를 드러내기 때문에, 0이 아닌 값에 어떻게 대응할지 자세히 볼 가치가 있다.
해석의 첫 갈림길은 값이 '일정한가, 출렁이는가'다.
클러스터의 여러 브로커가 변하지 않는 일정한 under-replicated partitions 수를 보고한다면, 보통 브로커 한 대가 오프라인이라는 뜻이다. 이때 클러스터 전체의 under-replicated partitions 합계는 그 다운된 브로커에 할당되어 있던 파티션 수와 같아지고, 정작 죽은 브로커는 지표 자체를 보고하지 않는다. 이 경우엔 그 브로커에 무슨 일이 있었는지 조사해야 한다. 흔히 하드웨어 장애지만 OS나 Java 문제일 수도 있다.
반대로 값이 출렁이거나, 값은 일정한데 오프라인 브로커가 없다면, 이는 보통 클러스터의 성능 문제를 뜻한다. 이쪽이 훨씬 진단이 어렵다.
핵심 포인트
- 리더인 파티션 중 팔로워가 따라잡지 못한 파티션 수를 브로커별로 센다
- MBean: kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions
- 여러 브로커에서 값이 일정 → 브로커 한 대 오프라인 (합계 = 그 브로커의 파티션 수, 죽은 브로커는 보고 안 함)
- 값이 출렁이거나 오프라인 브로커가 없는데 값이 일정 → 성능 문제
진단 전에 먼저 할 일 — preferred replica election
문제를 더 파고들기 전에 먼저 확인할 것은 최근에 preferred replica election을 실행했는지다.
Kafka 브로커는 한 번 리더십을 놓으면(장애나 종료 등) 자동으로 리더십을 되찾아 오지 않는다. auto leader rebalance를 켠 경우는 예외지만, 책은 이 설정을 권장하지 않는다. 그래서 클러스터 안에서 리더 복제본이 쉽게 불균형해진다.
preferred replica election은 안전하고 실행하기도 쉬우므로, 먼저 돌려 보고 문제가 사라지는지 확인하는 것이 좋다.
핵심 포인트
- 브로커는 리더십을 놓은 뒤 자동으로 되찾지 않는다 (auto leader rebalance는 비권장)
- 진단의 첫 단계는 preferred replica election을 먼저 실행해 보는 것
한 대의 문제인가, 클러스터 전체의 문제인가
다음 단계는 문제가 브로커 한 대에 국한된 것인지 클러스터 전체의 것인지 가르는 일이다.
under-replicated partitions가 브로커 한 대에만 있다면, 보통 그 브로커가 문제다. 다른 브로커들이 그 브로커로부터 메시지를 복제하는 데 어려움을 겪고 있다는 신호이기 때문이다.
여러 브로커에 흩어져 있다면 클러스터 문제일 수도 있지만, 여전히 특정 브로커 한 대가 원인일 수 있다. 그 한 대가 모든 곳으로부터의 복제에 문제를 겪는 경우다. 이때는 클러스터의 under-replicated 파티션 목록을 뽑아, 그 목록에 공통으로 등장하는 브로커가 있는지 확인한다.
# kafka-topics.sh --zookeeper zoo1.example.com:2181/kafka-cluster --describe \
--under-replicated
Topic: topicOne Partition: 5 Leader: 1 Replicas: 1,2 Isr: 1
Topic: topicOne Partition: 6 Leader: 3 Replicas: 2,3 Isr: 3
Topic: topicTwo Partition: 3 Leader: 4 Replicas: 2,4 Isr: 4
Topic: topicSix Partition: 5 Leader: 6 Replicas: 2,6 Isr: 6
Topic: topicNine Partition: 4 Leader: 3 Replicas: 3,2 Isr: 3
이 예에서 모든 줄의 Replicas에 공통으로 등장하면서 ISR에서는 빠져 있는 브로커는 2번이다. 즉 2번 브로커가 메시지 복제에 문제를 겪고 있다는 뜻이고, 조사 대상을 그 한 대로 좁힐 수 있다. 공통 브로커가 없다면 클러스터 전반의 문제일 가능성이 크다.
핵심 포인트
- kafka-topics.sh --describe --under-replicated 로 목록을 뽑아 공통 브로커를 찾는다
- 공통 브로커가 있으면 그 브로커의 문제, 없으면 클러스터 전반의 문제
클러스터 수준 문제 — 불균형과 자원 고갈
클러스터 문제는 보통 둘 중 하나다. 부하 불균형이거나 자원 고갈이다.
**불균형**은 찾기는 쉽지만 고치는 과정이 번거롭다. 진단에 필요한 브로커별 지표는 네 가지다: 파티션 수(partition count), 리더 파티션 수(leader partition count), 전체 토픽 바이트 인 레이트, 전체 토픽 메시지 인 레이트. 완벽히 균형 잡힌 클러스터라면 이 값들이 브로커 전반에 고르게 나온다. 책의 예시는 브로커 3대가 각각 파티션 100/101/100, 리더 50/49/50, 바이트 인 3.56/3.66/3.23 MB/s, 바이트 아웃 9.45/9.25/9.82 MB/s 수준으로 비슷한 모습이다.
preferred replica election을 이미 돌렸는데도 편차가 크다면 트래픽이 균형 잡혀 있지 않다는 뜻이므로, kafka-reassign-partitions.sh로 부하가 큰 브로커에서 한가한 브로커로 파티션을 옮겨야 한다. Kafka 브로커 자체는 파티션 자동 재배치 기능을 제공하지 않기 때문에 이 작업은 수동이며, 그래서 LinkedIn이 오픈소스로 공개한 kafka-tools 저장소의 kafka-assigner 같은 보조 도구가 나왔다.
**자원 고갈**은 브로커가 요청을 처리할 용량을 초과한 경우다. 흔한 병목은 CPU, 디스크 IO, 네트워크 처리량이다. 여기서 중요한 지적이 하나 있다. 디스크 사용량(용량)은 병목 지표가 아니다. 브로커는 디스크가 가득 찰 때까지 정상 동작하다가 그 순간 급작스럽게 실패하기 때문이다. 용량 문제를 진단하려면 OS 수준에서 CPU 사용률, 인바운드/아웃바운드 네트워크 처리량, 디스크 평균 대기 시간, 디스크 사용률(utilization) 같은 지표를 추적해야 한다.
이 자원 중 어느 하나라도 고갈되면 결국 같은 증상, 즉 under-replicated partitions로 나타난다. 여기서 반드시 기억할 것은 브로커의 복제 프로세스가 다른 Kafka 클라이언트와 정확히 같은 방식으로 동작한다는 사실이다. 클러스터가 복제에 문제를 겪는다면, 우리 고객(프로듀서와 컨슈머)도 똑같이 문제를 겪고 있다는 뜻이다. 그래서 클러스터가 정상일 때의 기준선(baseline)을 잡아 두고, 용량이 바닥나기 훨씬 전에 문제 조짐을 알려 줄 임계값을 설정해야 한다. 클러스터 사용량의 지표로는 All Topics Bytes In Rate가 좋은 가이드다.
핵심 포인트
- 클러스터 문제는 불균형 아니면 자원 고갈
- 불균형 진단 지표 4종: partition count, leader partition count, bytes in rate, messages in rate
- 재배치는 kafka-reassign-partitions.sh — 브로커는 자동 재배치를 제공하지 않는다
- 디스크 용량 사용률은 병목 지표가 아니다 (가득 차기 전까지 정상 동작하다 급작스럽게 실패)
- 브로커 복제도 일반 클라이언트와 같은 경로를 쓴다 — 복제가 느리면 고객도 느리다
호스트 수준 문제 — 하드웨어, 프로세스 경합, 설정 차이
문제가 브로커 한두 대로 좁혀졌다면, 그 서버가 나머지와 무엇이 다른지 봐야 한다. 원인은 대개 세 범주다: 하드웨어 장애, 다른 프로세스와의 경합, 로컬 설정 차이.
**하드웨어 장애**는 서버가 아예 멈추면 명백하지만, 성능만 갉아먹는 소프트 장애가 더 골치다. 메모리 일부가 불량이라 시스템이 그 구간을 우회해 가용 메모리가 줄었다거나, CPU에서 같은 일이 일어난 경우다. 이런 문제에는 IPMI 같은 하드웨어 관리 인터페이스로 하드웨어 건강 상태를 모니터링하고, 문제가 진행 중일 때는 dmesg로 커널 링 버퍼의 콘솔 메시지를 확인한다.
Kafka에서 성능 저하로 이어지는 더 흔한 하드웨어 장애는 디스크 장애다. Kafka는 메시지 영속화를 디스크에 의존하고, 프로듀서 성능은 디스크가 쓰기를 얼마나 빨리 커밋하느냐에 직결된다. 여기서의 편차는 프로듀서와 replica fetcher의 성능 문제로 드러나며, 후자가 곧 under-replicated partitions다.
여기서 특히 중요한 것이 '썩은 달걀 하나' 효과다. 브로커 한 대의 디스크 하나가 고장 나면 클러스터 전체의 성능이 무너질 수 있다. 프로듀서 클라이언트는 토픽의 파티션 리더를 맡은 모든 브로커에 연결하고, 모범 사례대로라면 그 파티션들은 클러스터 전체에 고르게 퍼져 있기 때문이다. 브로커 한 대가 느려져 produce 요청을 지연시키면 프로듀서에 백프레셔가 걸리고, 결국 모든 브로커로 가는 요청이 함께 느려진다.
대응은 IPMI나 하드웨어 인터페이스로 디스크 상태를 모니터링하고, OS 안에서는 SMART 도구로 디스크를 정기 점검하는 것이다. 디스크 컨트롤러도 눈여겨봐야 하는데, 특히 RAID 기능이 있는 경우 온보드 캐시는 컨트롤러가 정상이고 배터리 백업 유닛(BBU)이 살아 있을 때만 사용된다. BBU가 고장 나면 캐시가 비활성화되어 디스크 성능이 떨어진다.
**네트워크**도 부분 장애가 문제를 일으킨다. 불량 케이블이나 커넥터 같은 하드웨어 문제, 서버 쪽이나 상단 네트워크 장비 쪽의 속도·듀플렉스 설정 변경 같은 설정 문제, 네트워크 버퍼가 너무 작거나 연결이 너무 많아 메모리를 잠식하는 OS 문제 등이다. 핵심 지표는 네트워크 인터페이스에서 감지된 오류 수이며, 오류 카운트가 증가하고 있다면 미해결 문제가 있는 것이다.
**프로세스 경합**은 같은 시스템에서 도는 다른 애플리케이션이 자원을 소모해 브로커를 압박하는 경우다. 잘못 설치된 것일 수도, 모니터링 에이전트처럼 원래 돌아야 하는 프로세스가 문제를 일으키는 것일 수도 있다. top 같은 도구로 예상보다 CPU나 메모리를 많이 쓰는 프로세스를 찾는다.
다른 가능성을 모두 소진했다면 **설정 차이**가 스며들었을 가능성이 높다. 한 서버에서 도는 애플리케이션 수와 각각의 설정 옵션 수를 생각하면 차이를 찾는 일은 만만치 않다. 그래서 Chef나 Puppet 같은 설정 관리 시스템으로 OS와 애플리케이션(Kafka 포함) 설정을 일관되게 유지하는 것이 결정적으로 중요하다.
핵심 포인트
- 호스트 문제는 하드웨어 장애 / 다른 프로세스와의 경합 / 로컬 설정 차이 세 범주
- 디스크 장애가 Kafka 성능 저하로 이어지는 가장 흔한 하드웨어 원인
- 'One Bad Egg' — 브로커 한 대의 디스크 장애가 백프레셔로 클러스터 전체 성능을 무너뜨린다
- RAID 컨트롤러의 BBU 고장 → 캐시 비활성화 → 디스크 성능 저하
- 네트워크 인터페이스 오류 카운트 증가는 미해결 문제의 신호
- 설정 차이를 막으려면 Chef/Puppet 같은 설정 관리 시스템이 필요하다
이 모듈과 연관된 문항 2개가 문제 은행에 있습니다.
이 내용으로 문제 풀어보기