Programming/프로그래밍 내용 정리

Apache Kafka 톺아보기

domean 2025. 5. 30. 08:33


🔵 Apache Kafka란?

  • 오픈소스 분산 데이터 스트리밍 플랫폼
  • 링크드인에서 개발, 현재는 Apache 재단에서 관리
  • 실시간 데이터 스트림의 게시(Publish), 구독(Subscribe), 저장(Storage), 처리(Process) 기능 제공
  • 대규모 데이터 이동에 적합 (A → B뿐 아니라 A → 여러 지점(Z) 동시에 가능)
  • 전통적 메시징 시스템의 대안
    • 높은 처리량(Throughput)내결함성(Fault Tolerance)
    • 지속성(Persistence) 기반 저장 구조 (디스크에 로그 형태로 저장)
    • 소비자가 개별 오프셋을 관리하며, 재처리나 리플레이가 용이

 


🔵 Apache Kafka 구성 요소 요약

Kafka는 메시지를 효율적으로 전달하고 저장하기 위한 분산형 스트리밍 플랫폼입니다.
아래는 Kafka의 핵심 구성 요소입니다.

 

 

 

 

구성 요소 설명 요약
브로커 메시지를 저장하고 컨슈머에게 전달하는 Kafka 서버 인스턴스
메시지 Kafka에서 주고받는 데이터의 기본 단위, 바이트 배열 형태로 저장됨
토픽 메시지를 논리적으로 분류하는 단위, 데이터의 주제 또는 카테고리 역할
파티션 토픽을 나눈 물리적 단위로, 순서를 보장하고 병렬 처리 및 분산 저장을 가능하게 함
클러스터 여러 브로커의 집합으로 고가용성과 확장성 제공
프로듀서 Kafka에 메시지를 발행하는 클라이언트
컨슈머 Kafka로부터 메시지를 읽는 클라이언트
컨슈머 그룹 하나의 메시지를 중복 없이 병렬로 처리하기 위한 단위
리밸런싱 컨슈머 그룹 내에서 파티션 소유권을 재조정하는 과정
리플리케이션 장애 복구와 가용성을 위한 파티션 복제 구조

 

 


🔵 Apache Kafka 구성 요소 상세

1. 브로커 (Broker)

📌 Kafka에서 메시지를 저장하고 전달하는 서버 인스턴스

✅ 핵심 기능

  • Kafka 클러스터의 기본 구성 단위
  • 메시지를 디스크에 저장 (토픽/파티션 기반)
  • 컨슈머 요청에 따라 메시지 전송
  • 리더/팔로워 파티션 관리 및 복제 수행

📘 상세 설명

  • 브로커는 Kafka 서버 인스턴스로, 클러스터를 구성하는 노드 단위입니다.
  • 프로듀서로부터 메시지를 받아 지정된 토픽/파티션에 저장합니다.
  • 컨슈머가 특정 오프셋을 요청하면 해당 메시지를 디스크에서 읽어 전송합니다.
  • 리더 파티션이 메시지 처리의 중심이 되고, 팔로워는 이를 복제하여 고가용성을 보장합니다.
  • 메타데이터 관리 역할은 ZooKeeper 또는 KRaft 컨트롤러가 수행합니다.

2. 메시지 (Message)

📌 Kafka에서 주고받는 가장 작은 데이터 단위

✅ 핵심 특징

  • 바이트 배열 형태로 저장됨
  • 키/값 구조를 가질 수 있음
  • 오프셋을 통해 순서를 추적 가능

📘 상세 설명

  • Kafka의 메시지는 실제로 전송되는 데이터 조각으로, JSON, Avro, 문자열 등 다양한 포맷이 사용될 수 있습니다.
  • 각 메시지는 토픽의 특정 파티션에 기록되고, 고유한 오프셋(offset)을 부여받습니다.
  • 메시지 키가 지정되면 동일 키 메시지는 항상 동일 파티션에 저장되어 순서 보장이 가능합니다.

3. 토픽 (Topic)

📌 메시지를 논리적으로 분류하는 단위 (주제별 구분)

✅ 핵심 특징

  • 메시지를 분류하는 이름 공간
  • 다수의 파티션으로 구성됨
  • 여러 컨슈머 그룹이 독립적으로 구독 가능

📘 상세 설명

  • 토픽은 데이터 스트림을 구분하는 단위입니다. 예: 주문, 로그인, 알림 등
  • 토픽은 내부적으로 여러 개의 파티션으로 분산되어 저장됩니다.
  • 컨슈머 그룹마다 고유한 오프셋을 유지하므로, 동일 토픽을 다수 애플리케이션이 독립적으로 처리 가능


4. 파티션 (Partition)

📌 병렬성과 순서를 보장하는 토픽의 물리적 저장 단위

✅ 핵심 특징

  • 각 파티션은 순차적인 오프셋을 가짐
  • 파티션 단위로 메시지가 저장되고 읽힘
  • 다른 브로커에 분산 저장되어 확장성 확보

📘 상세 설명

  • 하나의 토픽은 여러 개의 파티션으로 구성됩니다.
  • 파티션은 로그 파일로 구성되어, 메시지는 append-only 형식으로 저장됩니다.
  • 동일 키의 메시지는 같은 파티션에 저장되어 순서가 유지됩니다.

5. 클러스터 (Cluster)

📌 여러 브로커를 묶어 고가용성과 확장성을 제공하는 Kafka의 논리적 단위

✅ 핵심 특징

  • 하나의 Kafka 클러스터는 여러 브로커로 구성
  • 노드 추가/제거 가능
  • 장애 발생 시 브로커 간 데이터 복제 및 처리 지속 가능

📘 상세 설명

  • Kafka 클러스터는 여러 브로커가 네트워크로 연결되어 하나의 단일 서비스처럼 동작합니다.
  • 각 브로커는 특정 파티션을 담당하며, 리더/팔로워 역할을 나눠 가집니다.
  • 클러스터 구성 시 브로커 수, 파티션 수, 리플리카 수를 적절히 설정하여 성능과 안정성 균형을 맞춥니다.

6. 프로듀서 (Producer)

📌 Kafka에 메시지를 발행하는 클라이언트

✅ 핵심 특징

  • 특정 토픽으로 메시지를 전송
  • 키에 따라 파티션 자동 선택 가능
  • 배치 처리 및 재시도 설정 가능

📘 상세 설명

  • 프로듀서는 Kafka 클러스터로 메시지를 보내는 데이터 발신자 역할입니다.
  • 메시지를 전송할 때 토픽만 지정하면 Kafka가 자동으로 파티션을 선택하거나 키 기반 분배를 수행합니다.
  • acks, retries, batch.size, linger.ms 등의 설정으로 신뢰성과 성능 조절 가능

7. 컨슈머 (Consumer)

📌 Kafka로부터 메시지를 읽는 클라이언트

✅ 핵심 특징

  • 지정된 토픽을 구독
  • 각 파티션에 대해 오프셋 기반 메시지 읽기
  • poll() 호출 주기와 heartbeat 관리 중요

📘 상세 설명

  • 컨슈머는 메시지를 가져올 때 poll() 메서드를 주기적으로 호출해야 합니다.
  • 메시지 처리가 끝난 지점까지 오프셋을 커밋(commit)하여 다음 소비 위치를 관리합니다.
  • 자동 커밋 vs 수동 커밋 설정에 따라 정확성 보장이 달라집니다.

8. 컨슈머 그룹 (Consumer Group)

📌 하나의 메시지를 중복 없이 병렬로 처리하기 위한 단위

✅ 핵심 특징

  • 그룹 내에서 파티션을 나눠 처리
  • 각 파티션은 하나의 컨슈머만 소비 가능
  • 그룹 단위로 오프셋 관리

📘 상세 설명

  • 동일한 Group ID를 갖는 컨슈머들은 하나의 컨슈머 그룹으로 묶입니다.
  • 파티션 수보다 많은 컨슈머는 유휴 상태가 되며, 적절한 컨슈머 수 조정이 중요합니다.
  • 서로 다른 그룹은 동일 메시지를 독립적으로 소비 가능

9. 리밸런싱 (Rebalancing)

📌 컨슈머 그룹 내에서 파티션 소유권을 재조정하는 과정

✅ 발생 조건

  • 컨슈머 추가/제거, 장애 발생, 파티션 수 변경 시 자동 발생

📘 상세 설명

  • 리밸런싱은 모든 컨슈머가 잠시 메시지 소비를 멈춘 후 파티션을 재할당 받는 과정입니다.
  • 짧게는 수 초, 길게는 수십 초까지 메시지 지연이 발생할 수 있습니다.
  • 너무 잦은 리밸런싱은 처리 중단, 중복 소비 등 문제를 야기할 수 있으므로 적절한 설정이 필요합니다.

10. 리플리케이션 (Replication)

📌 장애 복구와 가용성을 위한 파티션 복제 구조

✅ 핵심 개념

  • 리더(Leader)와 팔로워(Follower) 리플리카로 구성
  • In-Sync Replica(ISR)만 새 리더 후보 가능

📘 상세 설명

  • Kafka는 각 파티션 데이터를 여러 브로커에 복제하여 내결함성을 확보합니다.
  • 리더 리플리카는 모든 읽기/쓰기 요청을 처리하고, 팔로워 리플리카는 이를 따라 복제합니다.
  • 리더가 장애나면 ISR 중 하나가 자동 승격되어 데이터 유실 없이 처리를 이어갈 수 있습니다.

 

 

 


 

✅ Kafka 실전 Q&A 

1️⃣ 파티션 수 < 컨슈머 수가 많은 경우, 어떻게 동작하나요?

  • Kafka 규칙: 하나의 파티션은 하나의 컨슈머에게만 할당됨
  • 파티션보다 컨슈머가 많으면, 남는 컨슈머는 유휴(idle) 상태
  • 리소스 낭비 발생 → 컨슈머 수 ≤ 파티션 수가 권장됨

📌 예시: 3개 파티션 + 5개 컨슈머
→ 2개 컨슈머는 할당받지 못하고 대기 상태

 

2️⃣ 파티션 수 > 컨슈머 수가 적은 경우, 어떻게 동작하나요?

  • Kafka는 여러 파티션을 하나의 컨슈머에 할당 가능
  • 각 컨슈머는 할당된 파티션을 순차 처리
  • 병렬 처리 성능 확보 가능

📌 예시: 6개 파티션 + 3개 컨슈머
→ 각 컨슈머가 2개씩 파티션을 담당

 

3️⃣ 파티션 수를 늘리려면 어떻게 하나요?

 
  • 증가만 가능 (감소 불가)
  • 기존 메시지는 기존 파티션 유지 → 순서 보장 영향 없음
  • 컨슈머 그룹에는 리밸런싱 발생
  • 파티션이 지나치게 많으면 메타데이터/GC 오버헤드 주의

 

4️⃣ 오프셋은 어떻게 관리되나요?

  • 각 컨슈머 그룹이 오프셋을 개별적으로 관리
  • Kafka 내부 토픽 __consumer_offsets에 저장
  • 메시지 재처리를 위해 수동 커밋이 권장됨

📌 커밋 방식:

  • enable.auto.commit=true → 자동 커밋 (간편하지만 위험)
  • 수동 커밋 → 메시지 처리 완료 시점 명확히 조절 가능

 

5️⃣ 컨슈머 수를 늘리려면?

  • 동일한 Group ID를 가진 컨슈머 인스턴스를 추가
  • Kafka가 자동으로 리밸런싱 → 파티션 재할당
  • 병렬 처리량 증가 가능

⚠️ 단, 파티션 수보다 많으면 초과 컨슈머는 유휴 상태
토픽 확장 → 컨슈머 확장 순서 권장

 

6️⃣ 컨슈머 폴링 주기는 어떻게 설정하나요?

  • poll() 호출 간격이 max.poll.interval.ms 내에 있어야 함
  • 초과 시 → 장애로 간주 → 리밸런싱 발생

📌 주요 설정:

  • max.poll.interval.ms: 기본 5분, 메시지 처리시간 고려해 설정
  • heartbeat.interval.ms: 기본 3초, 생존 신호 주기
  • session.timeout.ms: 기본 30초, 이 시간 내 HeartBeat 없으면 제거

 

7️⃣ 리밸런싱이 일어나는 상황은?

  • 컨슈머 그룹에 새 컨슈머 참여
  • 컨슈머가 죽거나 종료됨
  • 토픽에 새로운 파티션 추가
  • 그룹 코디네이터 변경

💡 이때 파티션 재할당을 위해 전체 컨슈머가 잠깐 정지됨

 

8️⃣ 리밸런싱 시 발생 가능한 문제는?

  • 메시지 처리 중단: 실시간 시스템에 지연 발생
  • 중복 처리 가능성: 커밋 전에 리밸런싱 → 같은 메시지 다시 처리
  • 과도한 리밸런싱 → 성능 저하 + 리소스 소모

💡 해결 팁:

  • 메시지 처리 시간에 맞춰 max.poll.interval.ms 적절히 조정
  • 컨슈머는 멱등 처리 고려 (idempotent)

 

9️⃣ Kafka가 빠른 이유는?

  1. 순차 쓰기 기반 로그 구조 → 디스크 효율 극대화
  2. Zero-copy 전송 → 디스크 → 네트워크 직접 전송
  3. 페이지 캐시 활용 → 메모리 속도에 가까운 읽기
  4. 불변 메시지 구조 → 락/변경 없음 → 단순, 빠름
  5. 파티션 기반 병렬 처리 → 수평 확장 가능
  6. 배치 처리 + 압축 + 간결한 프로토콜

결과: 수백만 건/sec 처리 가능한 초고성능 스트리밍 플랫폼