[Kafka] Apache Kafka 뭔데? 대용량 실시간 데이터 처리를 위한 기술

Apache Kafka가 어디에 사용되는지 감을 잡고 싶으신 분은 [EDA] Event-Driven Architecture 뭔데? 를 먼저 읽어보시는 것을 추천합니다!


Apache Kafka

📌 Apache Kafka, 왜 지금 알아야 할까?

서비스 트래픽이 폭증하고, 실시간 데이터 분석이 당연시되는 시대에 "데이터는 곧 경쟁력"입니다. 하지만 데이터를 빠르고 안정적으로 주고받기란 생각보다 쉽지 않죠. 특히 시스템이 커질수록 문제는 아래 이미지와 같이 더 복잡해집니다.

출처:https://www.confluent.io/blog/event-streaming-platform-1/



이럴 때 등장한 게 바로 Apache Kafka예요.
Kafka는 LinkedIn이 내부 데이터 파이프라인 문제를 해결하기 위해 만든 분산형 이벤트 스트리밍 플랫폼입니다. 아래 이미지처럼 kafka를  도입함으로써 데이터와 데이터 흐름을 중앙에서 관리할 수 있게 되어 신속한 데이터 처리와 유연한 확장이 가능해졌습니다. 현재 Kafka는 전 세계에서 가장 널리 쓰이는 이벤트 브로커로 자리잡았습니다.

출처:https://www.confluent.io/blog/event-streaming-platform-1/

 

📌 Kafka는 어떤 기술인가요?

Apache Kafka는 대용량 데이터를 빠르고 안정적으로 주고받을 수 있도록 설계된 분산형 이벤트 브로커입니다.

  • Apache 소프트웨어 재단의 오픈소스
  • 가장 많이 사용되는 Event Broker
  • 분산 시스템에서 대용량 분산 이벤트 스트림을 처리
  • Publish-Subscribe 모델 기반 메시징 시스템
  • 로그 수집, 실시간 분석, MSA 이벤트 연동 등 다양하게 활용 가능

 

📌 Kafka의 핵심 특징

분산 아키텍처

  • 여러 Broker로 구성된 클러스터고가용성과 확장성을 보장합니다.
  • 데이터 복제를 통해 장애 시 자동 복구 및 리더를 선출하여 장애 발생 시 데이터를 안전하게 처리할 수 있습니다.

고성능, 대용량 처리

  • 대용량 데이터이벤트를 실시간으로 처리 가능합니다.
  • Event-Driven Architecture에 적합합니다.

높은 내구성

  • 메시지는 디스크에 저장되고 복제되어 장애 시에도 데이터 손실이 없습니다.

다양한 클라이언트 지원

  • 다양한 언어/플랫폼의 클라이언트를 지원하여 MSA에서 유연한 서비스 간 통신이 가능하고 결합도도 낮아 Event-Broker로 적합합니다.

 

Kafka의 동작원리

Kafka는 어떻게 데이터를 중앙 집중화하여 처리할 수 있었을까요? 바로 Pub/Sub (Publish/Subscribe) 모델을 기반으로 데이터 관리를 중앙 집중화할 수 있었습니다. Publisher(=Producer)가 메시지를 발행하고, Subscriber(=Consumer)특정 주제(Topic)를 구독하여 해당 주제와 관련된 메시지를 받는 방식입니다.

 

📌 Apache Kafka Architecture

출처: https://www.javatpoint.com/apache-kafka-architecture

📌 Kafka의 구성 요소

1. Producer - 메시지 생산자

Producer는 Kafka에 메시지를 발행(produce)하는 클라이언트입니다.

  • 메시지를 특정 Topic에 전송하며, Key와 Value를 포함할 수 있어요.
  • Key 값에 따라 어떤 Partition에 메시지를 넣을지 결정됩니다.
  • Key를 지정하지 않으면 Kafka는 자동으로 Round-Robin 방식으로 분산합니다.

 

2. Consumer - 메시지 소비자

Consumer는 Kafka로부터 메시지를 소비(consume)하는 클라이언트예요.

  • 특정 topic의 Partition에서 메시지를 읽어오며.
  • 읽어온 메시지들은 내부적으로 Offset 순서대로 처리됩니다.
    (Offset: 각 Partition 안에서 메시지의 위치 표시)
  • Consumer Group을 통해 여러 Consumer 인스턴스를 묶어 하나의 logical consumer로 구성할 수 있습니다.

 

3. Consumer Group – 같은 Topic을 읽는 Consumer 묶음

Kafka는 대용량 메시지를 병렬로 처리할 수 있도록 설계되어 있습니다. 그 핵심이 바로 Consumer Group이에요.

  • 여러 Consumer를 Consumer Group으로 묶으면, Kafka는 각 Partition을 Consumer에게 분배해줍니다.
  • 이때 한 Partition은 같은 Consumer Group 내에서 단 하나의 Consumer만 소비할 수 있어요.
  • 하지만 다른 Consumer Group에서는 동일한 Partition을 중복 소비할 수 있습니다.
  • 💡 이 구조는 같은 메시지를 서로 다른 목적으로 병렬 처리할 수 있게 만들어줍니다.

 

4. Topic - 메시지의 주제

Topic은 메시지를 구분하는 논리적인 단위입니다.

  • Producer는 특정 topic으로 메시지를 보내며
  • Consumer는 특정 topic에서 메시지를 읽어옵니다.

 

5. Partition - 각 Topic을 나눈 물리적 단위,병렬 처리의 단위

Topic은 여러 개의 Partition으로 나뉘어 저장됩니다.

  • Partition은 Kafka가 메시지를 물리적으로 저장하는 최소 단위입니다. 각 Partition은 별도의 파일로 저장되어 있습니다.
  • Partition 개수를 늘리면 → 더 많은 Consumer가 병렬로 처리 가능
  • 각 Partition은 메시지의 순서를 보장합니다.
💁🏻 메시지 병렬 처리 성능을 높이기 위해 적절한 Partition 설계는 매우 중요합니다.

topic을 생성할 때 patition의 수와 ReplicationFactor를 최소 3으로 설정해주어야합니다.

ReplicationFactor를 설정하지 않으면 default로 1이 설정되는데 이는 원본 메시지만 저장하고 복제를 하지 않겠다는 뜻이고 ReplicationFactor를 3으로 설정하면 두 개의 복제본을 생성하겠다는 의미입니다. 1개 Leader Partition2개의 Follower Partition이 만들어지는데 Leader Partition 에서는 모든 쓰기와 읽기가 가능하고, Follower Partition는 Leader Partition의 복제를 합니다.

 

만약 Leader Partition에 장애가 발생하는 경우 Follwer Partition 중 하나가 Leader Partition을 승계합니다. 이를 통해 장애를 대처 할 수 있습니다. 또한 하나의 topic에 대한 두 개 이상의 parition을 서로 다른 Broker에 구성함으로써, 메시지의 병렬 처리를 가능하게 하며, 확장성과 성능을 향상시킵니다.

💁🏻 어느 Partition에 저장할까?
Partition에 분산 저장해줄 때 어느 Partition에 저장할지 어떻게 결정할까요? 바로 메시지의 key 값을 설정하여 어느 Partition에 저장할지를 결정합니다. 만약 key 값을 설정하지 않았다면 RR(Round-Robin) 방식으로 결정합니다.

Partition 같은 경우 내부에 들어온 메시지의 순서가 보장됩니다. 때문에 메시지 key 값을 지정하여 특정 Partition에만 메시지가 저장되게 하여 들어온 메시지 순서를 보장할 수 있습니다. (물론 Partition을 하나만 두는 방법도 방법일 수 있습니다.) 메시지 key값을 지정하지 않는 경우  RR 방식을 사용하게 되고, 이 방식은 여러 Partition에 저장되기 때문에 메시지 순서를 보장할 수 없습니다.

따라서 메시지 순서가 매우 중요한 프로그램이라면 Partition 수, 메시지 key 값 설정 등을 고려 필요가 있습니다. 하지만 메시지 순서를 위해 이러한 설정들을 강제하면, 메시지 병렬 처리라는 이점을 잃게되기 때문에 신중히 고려해봐야 합니다.
💁🏻 ISR (In-Sync-Replicas)
ISR은 Leader Partition과 Follower Partition들의 집합입니다. ISR에 속한 Partition들은 Leader Partition에 장애가 발생했을 때 새로운 Leader Partition이 될 수 있습니다. 즉, ISR에 속한 Follower Partition들은 Leader Partition이 될 수 있는 자격이 있다는 뜻(데이터 정합성 보장)입니다.

ISR에 속하는 지를 어떻게 확인할까요?
ISR그룹의 Leader Partition와 Follower Partition 사이에 주기적인 복제 요청이 발생하고, 이를 통해 동기화가 이루어집니다. 만약 Leader와 동기화되지 않으면 ISR에서 제외됩니다. Kafka는 각 복제본이 Leader Partition의 모든 메시지를 정상적으로 동기화했는지를 확인하기 위해 Offset을 사용합니다. Leader와 복제본의 Offset이 동일한 경우, 해당 복제본은 ISR에 속합니다.

 

 

6. Offset – 메시지의 위치값

Kafka는 메시지를 어디까지 읽었는지 기억하기 위해 Offset 값을 사용합니다.

  • Partition 내부에서 메시지의 순서를 나타내는 번호에요.
  • Consumer는 이 Offset 기준으로 메시지를 이어서 처리합니다.

 

7. Broker - Kafka의 저장소 서버

Kafka 클러스터 내부에서 메시지를 실제로 저장하고 전달하는 노드입니다.

  • Producer가 메시지를 보내면, Broker는 이를 해당 Topic의 Partition에 저장합니다.
  • Consumer는 Broker로부터 메시지를 받아가요.
  • 여러 Broker가 모이면 하나의 Kafka Cluster가 됩니다.

 

8. Kafka Cluster - 고가용성을 위한 구조

Kafka는 여러 Broker를 하나의 Cluster로 묶어 운영합니다.

  • 각 Broker는 서로 다른 Partition을 저장하고
  • 하나의 Partition은 여러 Broker에 복제되어 장애 상황에서도 안전하게 복구 가능

 

9. Zookeeper
Zookeeper는 Kafka의 분산 처리를 위한 도구입니다.

  • Zookeeper는 Kafka Cluster의 구성정보 즉, Broker들의 정보와 상태를 관리하고, 리더 선출 등의 작업을 조정합니다.
  • Kafka Cluster의 Broker들은 Zookeeper를 통해 서로의 존재 및 메타데이터 정보를 공유하고, 이를 통해 Kafka의 메타데이터, 브로커 상태, 토픽 등을 관리할 수 있습니다.
💁 KRaft의 등장: 더 간단하고 안정적인 운영 가능
ZooKeeper를 사용하게 되면 Kafka 클러스터 외부에 별도의 Zookeeper를 설정하고 운영해야합니다. 또한 Zookeeper는 분산환경에서 중앙 집중식으로 동작하기 때문에 단일 장애 지점이 될 수 있습니다. 이외에도 여러 이유가 있어 Kafka 자체에 메타데이터를 관리할 수 있는 KRaft가 나왔습니다. KRaft를 사용함으로써 ZooKeeper에 대한 종속성이 제거되고, KRaft는 Kafka 클러스터 내부에 내장되어 있기 때문에 간소화된 아키텍처를 제공합니다. 또한 KRaft는 Kafka 에 특화된 분산 리더 선출 알고리즘을 사용하여 단일 장애 지점을 제거하고, 높은 처리량과 낮은 지연 시간을 제공해줍니다.