콘텐츠로 이동

1. 아파치 카프카(Apache Kafka) 개요

아파치 카프카는 서비스 간 실시간 메시지 교환을 위한 분산 스트리밍 플랫폼입니다. 단순한 메시지 전달을 넘어, 내부에 여러 브로커를 둔 분산 시스템으로 설계되어 확장성내결함성이 매우 뛰어납니다.


2. 데이터의 단위와 저장 구조

2.1 레코드(Record)와 토픽(Topic)

  • 레코드: 카프카 데이터의 최소 단위 (Key, Value, Timestamp로 구성).
  • 토픽: 이벤트(레코드)들의 집합체. (예: '구매', '리뷰', '오류 로그' 토픽)

2.2 파티션(Partition)과 오프셋(Offset)

  • 파티션: 하나의 토픽을 여러 개로 나눈 '병렬 큐'입니다. 파티션이 많을수록 더 많은 메시지를 동시에 처리할 수 있습니다.
  • 오프셋: 파티션 내에서 메시지가 저장된 순서(번호)입니다. 파티션 내부에서는 이 번호에 따라 순서가 보장됩니다.
  • 데이터 분산: 레코드의 키(Key)에 해시 함수를 적용해 특정 파티션으로 보냅니다. 같은 키를 가진 메시지는 항상 같은 파티션에 쌓여 순서가 유지됩니다. -> 파티션 처리는 하나의 컨슈머가 담당.

3. 메시지 소비의 핵심: 컨슈머 그룹(Consumer Group)

카프카는 컨슈머 그룹이라는 개념을 통해 두 가지 메시징 모델을 동시에 지원합니다.

3.1 분산 큐 모델 (병렬 처리)

  • 구성: 하나의 컨슈머 그룹 안에 여러 개의 컨슈머 인스턴스를 배치합니다.
  • 동작: 토픽의 파티션들이 그룹 내 컨슈머들에게 나뉘어 할당됩니다.
  • 효과: 대량의 데이터를 여러 명이 나누어 처리하므로 작업 속도가 매우 빠릅니다.

3.2 발행/구독 모델 (데이터 복제 및 공유)

  • 구성: 여러 개의 독립된 컨슈머 그룹이 동일한 토픽을 구독합니다.
  • 동작: 각 컨슈머 그룹은 토픽의 모든 메시지를 독립적으로 처음부터 끝까지 다 받습니다.
  • 효과: 동일한 '구매' 데이터라도 [배송 그룹]은 물건을 보내고, [통계 그룹]은 매출을 계산하는 등 서로 다른 용도로 동시에 사용할 수 있습니다.

4. 요약: 카프카를 배워야 하는 이유

  1. 범용성: 분산 큐와 발행/구독 방식을 설정만으로 모두 구현 가능합니다.
  2. 수평 확장성: 파티션을 늘려 성능을 쉽게 높일 수 있습니다.
  3. 유연한 설계: 키(Key)를 활용해 데이터 순서를 정교하게 관리할 수 있습니다.
  4. 내결함성: 분산 시스템 구조 덕분에 일부 브로커에 문제가 생겨도 서비스가 중단되지 않습니다.

1. 확장성 및 성능 (Scalability & Performance)

카프카는 단일 서버의 물리적 한계를 극복하기 위해 '파티션(Partition)'이라는 개념을 사용합니다.

  • 토픽의 분할 (Partitioning):
  • 하나의 토픽을 여러 개의 파티션으로 나누어 분산 저장합니다.
  • 이를 통해 단일 장치의 CPU 코어 수, 메모리 용량, 네트워크 대역폭에 제한되지 않고 수평적 확장(Scale-out)이 가능합니다.
  • 브로커(Broker) 분산:
  • 여러 대의 브로커에 파티션 소유권을 고르게 분배하여 부하를 분산합니다.
  • 메시지 유입량이나 처리 속도에 따라 파티션 수를 조절하여 병렬 처리 능력을 극대화할 수 있습니다.
  • 병렬 처리 (Parallelism):
  • 퍼블리셔(Producer): 파티션 개수에 비례하여 병렬로 메시지를 발행합니다.
  • 컨슈머(Consumer): 컨슈머 그룹 내의 인스턴스들이 파티션을 나누어 할당받아 병렬로 메시지를 소비합니다.
  • 트레이드오프 (Trade-off):
  • 높은 확장성을 위해 토픽 전체의 메시지 순서 보장은 포기하며, 개별 파티션 내에서만 순서가 유지됩니다.

2. 내결함성 (Fault Tolerance)

시스템 일부에 장애가 발생해도 데이터와 서비스를 유지하기 위해 '복제(Replication)' 메커니즘을 사용합니다.

  • 복제 횟수 (Replication Factor, RF):
  • 토픽별로 설정 가능하며, RF=N일 경우 각 파티션이 N개의 브로커에 복제됨을 의미합니다.
  • 리더(Leader)와 팔로워(Follower):
  • 리더: 모든 읽기(Read)와 쓰기(Write) 작업을 직접 처리합니다.
  • 팔로워: 리더의 데이터를 실시간으로 복제하며 대기합니다. 리더 장애 시 자동으로 새로운 리더로 승격됩니다.
  • 효율적 관리: 복제본이 많을수록 안정성은 높아지지만 시스템 자원(메모리, 디스크) 소모가 커지므로 토픽의 중요도에 따라 다르게 설정합니다.

3. 조정 및 관리 (Coordination)

카프카는 클러스터의 상태를 관리하기 위해 주키퍼(Zookeeper)를 활용합니다.

  • 레지스트리 역할: 브로커의 주소와 관리하는 토픽/파티션 정보를 저장합니다.
  • 장애 감지 및 모니터링: 주키퍼의 임시 Z노드(Ephemeral Node)워처(Watcher) 기능을 사용하여 브로커의 연결 상태를 실시간으로 확인하고 장애 발생 시 이를 즉시 알립니다.
  • 리더 선출: 브로커 장애 시 파티션 리더를 교체하는 등의 조정 작업을 수행합니다.

4. 데이터 보존 및 복구 (Durability)

카프카는 일반적인 메시지 브로커와 달리 데이터를 메모리에만 두지 않고 디스크에 유지합니다.

  • 로그 보존: 컨슈머가 메시지를 읽어간 후에도 설정된 시간 동안 데이터가 삭제되지 않고 유지됩니다.
  • 이점:
  • 새로운 컨슈머가 과거의 메시지를 다시 읽을 수 있습니다(Replay).
  • 처리 중 오류가 발생했을 때 데이터를 잃지 않고 재시도가 가능합니다.
  • 장애가 발생했던 브로커가 복구되었을 때, 디스크의 데이터를 바탕으로 다른 브로커를 빠르게 따라잡을 수 있습니다.

요약

카프카는 단순한 메시징 플랫폼을 넘어, 파티셔닝(확장성), 복제(내결함성), 디스크 기반 저장(지속성), 그리고 주키퍼 기반 조정(관리)을 통해 고성능 분산 시스템으로서의 완성도를 갖추고 있습니다.


KRaft(Kafka Raft)

Apache Kafka의 KRaft(Kafka Raft)는 기존 Kafka 아키텍처의 고질적인 복잡성을 해결하기 위해 도입된 합의 프로토콜(Consensus Protocol)이자 새로운 메타데이터 관리 방식입니다.

간단히 말해, Kafka에서 Zookeeper에 대한 의존성을 완전히 제거하고 Kafka 내부에서 스스로 메타데이터를 관리하는 기술입니다.


1. KRaft가 도입된 배경 (Zookeeper의 한계)

기존 Kafka는 클러스터 상태(브로커 정보, 토픽 설정, ACL 등)를 관리하기 위해 외부 시스템인 Zookeeper를 반드시 사용해야 했습니다. 이는 다음과 같은 문제점을 야기했습니다.

  • 시스템 복잡도: Kafka 외에 별도의 Zookeeper 클러스터를 운영/관리해야 함.
  • 확장성 제약: 메타데이터가 Zookeeper에 저장되다 보니 파티션 개수가 수십만 개 이상으로 늘어날 경우 병목 현상 발생.
  • 느린 장애 복구: 컨트롤러 브로커가 다운되면 Zookeeper에서 새로운 컨트롤러를 선출하고 데이터를 동기화하는 과정에서 긴 가동 중단(Downtime)이 발생함.

2. KRaft의 핵심 아키텍처

KRaft는 Kafka 내부의 컨트롤러 노드들이 Raft 알고리즘을 사용하여 직접 메타데이터를 관리하는 방식입니다.

주요 구성 요소

  • Quorum Controller: KRaft 모드에서는 일부 브로커가 '컨트롤러' 역할을 수행합니다. 이들은 Metadata Log라는 특수 토픽을 공유하며 Raft 알고리즘을 통해 클러스터 상태를 동기화합니다.
  • Event-driven Metadata: 메타데이터 변경 사항이 로그 형태로 기록되며, 모든 컨트롤러와 일반 브로커는 이 로그를 소비(Consume)하여 최신 상태를 유지합니다.
  • Active Controller: Quorum 멤버 중 한 대가 리더 역할을 수행하며 쓰기 작업을 담당합니다.

3. KRaft의 작동 원리 (Raft 기반)

KRaft는 분산 시스템에서 널리 사용되는 Raft 합의 알고리즘을 변형하여 사용합니다.

  1. 리더 선출: 컨트롤러 노드들 사이에서 투표를 통해 하나의 리더(Active Controller)를 뽑습니다.
  2. 로그 복제: 클러스터 설정 변경(예: 토픽 생성)이 발생하면 리더가 이를 로그에 기록하고 다른 컨트롤러(Followers)에게 복제합니다.
  3. 상태 전파: 일반 브로커들은 컨트롤러로부터 메타데이터 로그를 읽어와 자신의 메모리에 업데이트합니다.

4. KRaft 도입 시 장점

특징 Zookeeper 모드 KRaft 모드
운영 단순성 Kafka + Zookeeper 두 시스템 관리 Kafka 단일 시스템만 관리
확장성 파티션 수 제한 (약 20만 개 내외) 수백만 개의 파티션 지원 가능
복구 속도 컨트롤러 교체 시 수 분 소요 수 초 내로 즉시 복구
데이터 일관성 외부 시스템과의 동기화 오차 발생 가능 내부 로그 기반으로 강력한 일관성 보장

5. 현재 상태 및 사용 가이드

  • 도입 시기: Kafka 2.8 버전에서 초기 공개되었고, 3.3 버전부터 Production Ready(운영 환경 사용 가능) 상태가 되었습니다.
  • Zookeeper 중단: Kafka 4.0 버전부터는 Zookeeper 지원이 완전히 제거될 예정이므로, 신규 클러스터 구축 시 KRaft 사용이 권장됩니다.

설정 시 주의사항

KRaft를 설정할 때는 server.properties 대신 config/kraft/server.properties를 참고해야 하며, 각 노드의 역할을 정의하는 process.roles 설정(broker, controller, 혹은 둘 다)이 핵심입니다.


KRaft 모드 구축을 위한 구체적인 설정 파일 예시나 실행 명령어가 궁금하신가요?