각진 세상에 둥근 춤을 추자

[Kafka] 카프카(Kafka) 기본 개념 본문

Java

[Kafka] 카프카(Kafka) 기본 개념

circle.j 2024. 11. 12. 11:26

아파치 카프카(Apache Kafka)란?

 

오픈 소스 분산 스트리밍 플랫폼으로 분산 메시징 시스템이다.

현재 대규모 데이터 처리와 메시징 시스템으로 주로 사용되고 있고, 여러 시스템 간에 실시간으로 메시지를 전송하는 데 특화되어 있다. 

 


카프카의 주요 특징

 

1. 분산형 시스템

카프카는 분산형 시스템으로, 여러 서버에 걸쳐 데이터를 분산 저장하고 처리한다.

2. 실시간 데이터 처리 

카프카는 스트리밍 데이터를 실시간으로 처리할 수 있으므로 로그 수집, 데이터 파이프라인 구축, 실시간 분석 등에 용이하다.

3. 내구성

카프카는 데이터를 디스크에 기록하며, 복제 기능을 통해 장애 발생 시에도 데이터를 안전하게 보관한다. 

4. 높은 처리량

카프카는 초당 수백만 건의 메시지를 처리할 수 있는 높은 처리량을 보유한다.

 

 


카프카의 동작 방식

 

카프카의 동작 방식을 이해하기 위해서는 카프카의 구성 요소와 데이터의 흐름을 먼저 이해할 필요가 있다. 

카프카는 기본적으로 프로듀서(Producer), 컨슈머(Consumer), 브로커(Broker), 토픽(Topic), 파티션(Partition)으로 구성되어 있다.

  • 프로듀서(Producer): 데이터를 토픽에게 전송
  • 컨슈머(Consumer): 토픽에서 데이터를 읽음
  • 토픽(Topic): 데이터를 구분하는 채널
  • 파티션(Partition): 토픽은 여러 개의 파티션으로 나누어 저장
  • 브로커(Broker): 카프카 클러스터의 서버로 데이터를 저장하고 관리

 

 

 

카프카의 동작 방식은 크게 프로듀서 → 브로커 → 컨슈머의 흐름이다. 

1. 메시지 전송 (프로듀서 → 토픽)

프로듀서는 특정 토픽에 메시지를 보낸다.

 

2. 파티션에 메시지 저장

카프카는 메시지를 어떤 파티션에 보낼지 결정하고 파티션에 순차적으로 저장한다.

(카프카는 파티션 키를 사용하거나, 파티션 키가 없다면 라운드 로빈 방식이나 해싱 방식으로 메시지를 분배한다.)

메시지는 로그 형태로 저장되며 파티션은 단순히 기록을 추가하는 방식으로 메시지를 저장한다.

즉, 파티션은 메시지를 변경하거나 삭제하지 않고 계속 보존한다. 

 

3. 브로커에 파티션 저장

각 파티션은 브로커에 저장되고 관리된다. (이때 각 파티션은 다른 브로커에 복제본을 가진다.)

 

4. 컨슈머 처리

컨슈머는 토픽을 구독하고, 해당 파티션의 데이터를 소비한다. 

컨슈머는 오프셋(파티션 내에서 각 메시지의 위치)을 기반으로 메시지를 읽는다. 

컨슈머는 메시지를 읽은 후, 해당 오프셋을 업데이트하여 중복 읽기를 방지한다.

 

 


카프카의 특징을 살펴본다.

카프카의 기본 라우팅

 

프로듀서가 메시지를 보낼 때, 카프카는 메시지를 어떤 파티션에 저장할지 결정한다.

파티션 키(메시지 키)가 있는 경우

- 메시지에 파티션 키가 지정되면, 카프카는 이 키의 해시 값을 계산하여 그 해시 값에 해당하는 파티션에 메시지를 보낸다.

(해시 값이 항상 일정하게 결정되므로, 같은 키를 가진 메시지는 항상 동일한 파티션으로 보내지게 된다.)

파티션 키(메시지 키)가 없는 경우

- 카프카는 라운드 로빈 방식을 사용하여 메시지를 파티션에 분배한다. (= 메시지가 순차적으로 각 파티션에 돌아가면서 배치)

 

카프카는 위와 같은 기본적인 라우팅 방식만을 제공하며, 사용자가 지정하는 라우팅 방식을 지원하지 않는다

(라우팅: 데이터를 어디로 보낼지 결정하는 과정)

또한 카프카의 기본 라우팅 방식은 동적이지 않다고 할 수 있다. 

 

왜 카프카의 기본 라우팅 방식은 동적이지 않은가? 

- 고정된 규칙: 카프카는 파티션에 메시지를 보내는 규칙을 정해진 방식으로 처리한다. 

- 조건 기반 라우팅 불가: "특정 시간대에만 이 파티션으로 보내라." "어떤 특정 조건을 만족하는 메시지는 다른 파티션으로 보내라" 등의 조건에 따라 라우팅을 변경하는 동적 라우팅은 불가능하다.

 

따라서 사용자가 원하는 방식으로 라우팅을 하려면 카프카 스트림즈(Kafka Strems)를 활용해야 한다. 

 


카프카의 프로토콜 

 

TCP 기반의 custom 프로토콜

카프카는 TCP(Transimssion Control Protocol)기반의 자체 정의한 프로토콜인 custom 프로토콜을 사용하여 데이터를 전송한다. 

(TCP는 데이터 전송의 신뢰성을 보장하는 프로토콜로 데이터가 손실되지 않도록 보장하고 전송 순서를 유지하는 특성을 가지고 있다.)

즉, 카프카는 표준 프로토콜(HTTP, AMQP 등)이 아닌 자체적인 규칙에 따라 데이터를 송수신한다. 

 


카프카의 메시지 순서 보장 

 

 

카프카는 메시지를 위 그림과 같이 각 파티션에 저장한다. 

한 파티션 내의 메시지는 순서대로 저장되며, 한번 기록된 메시지는 변경되지 않는다.

 

예를 들어 파티션 0에 메시지 A, B, C가 순서대로 들어갔다면 다음과 같은 순서가 보장된다. 

카프카는 해당 순서를 변경하지 않는다.

 

하지만 여러 파티션이 병렬로 처리할 때는

즉, 카프카가 여러 파티션에 메시지를 분배하고 각각의 파티션에서 독립적으로 병렬 처리가 이루질 때는 각 파티션에서의 처리 순서는 별도로 유지되며, 파티션 간의 순서는 보장되지 않는다.

 

예를 들어 파티션 0에 메시지가 A, B, C가 순차적으로 들어갔고, 파티션 1에 메시지 D, E가 들어갔다면

파티션 0 내에서 메시지 순서는 A→B →C로 보장되지만, 파티션 0과 파티션 1 간의 시간 순서는 보장되지 않는다.

파티션 1의 메시지 D가 파티션 0의 메시지 B 보다 먼저 도착할 수 있다.

 


카프카의 데이터 저장 방식

 

카프카는 메시지를 메모리가 아니라 디스크에 영구적으로 저장하는 디스크 기반의 로그 시스템이다.

이 방식은 데이터의 영속성을 보장하며, 카프카 클러스터가 재시작되거나 장애가 발생해도 데이터를 유지하고 복구할 수 있게 한다.

 

카프카에서의 디스크 저장 구조는 다음과 같다

- 로그 파일: 카프카는 각 파티션에 대해 로그 파일을 사용하여 데이터를 저장한다. 각 메시지는 디스크에 순차적으로 기록되며, 순차적 쓰기 방식으로 인해 높은 성능을 발휘한다.

- 파티션 및 오프셋: 카프카는 데이터를 파티션 단위로 나누어 저장하며, 각 메시지에는 오프셋이라는 고유 번호를 붙여 순차적인 처리가 가능하도록 한다. 

 


다른 기술과의 비교

 

카프카와 비슷하게 메시지를 송수신하는 데 사용되는 기술로는 RabbitMQ와 Redis가 있다.

 

1. RabbitMQ

메시지 큐 시스템으로, AMQP 프로토콜을 사용하여 메시지 송수신을 처리한다.

영속성과 메시지 대기열을 지원하며, 순서 보장과 내결함성을 제공한다.

클러스터링 및 높은 안전성을 제공하지만 확장성은 카프카보다 제한적이다.

주로 비동기 작업과 큐 처리에 많이 사용된다.

 

2. Redis

인메모리 데이터베이스로, PUB/SUB 방식으로 메시지를 전송한다.

빠른 성능을 제공하지만 기본적으로 메모리 기반이라 영속성은 선택적이다.

순서 보장은 없으며 실시간 알림 시스템이나 캐싱에 적합하다.

빠른 성능과 실시간 처리에 강점이 있다. 

 

각 특징을 비교하면 다음과 같다. 

특징 RabbitMQ Redis Kafka
기본 개념 메시지 큐 (Message Broker) 인메모리 데이터 구조 서버,
Pub/Sub 시스템
분산 스트리밍 플랫폼,
분산 로그 시스템
프로토콜 AMQP
(Advanced Message Queuing Protocol)
PUB/SUB
(Publisher/Subscriber)
자체 프로토콜 (TCP 기반)
영속성 메시지 저장 가능, 
영속성 지원(디스크 저장 가능)
기본적으로 메모리 기반 메시지 디스크에 저장,
영속성 보장
성능 상대적으로 높은 메시지 처리 지연 기간, 
높은 안정성
빠른 읽기/쓰기 성능
(인메모리 처리)
초당 수백만 메시지 처리 가능
순서 보장 큐 내에서 순서 보장,
여러 큐 간의 순서 보장 X
순서 보장 안 함 파티션 내에서 순서 보장,
파티션 간 순서 보장 X 
확장성 클러스터링 지원,
확장성 좋지만 구성 복잡
높은 성능을 제공하지만
수평 확장성이 제한적
매우 높은 확장성,
분산 환경에서 효과적
메시지 전송 방식 큐 기반
(프로듀서→큐 →컨슈머)
PUB/SUB
(발행자 →구독자)
토픽/파티션 기반
(프로듀서 →파티션 →컨슈머)
사용 사례 실시간 메시지 처리, 비동기 작업 처리, 큐 처리 빠른 데이터 캐싱, 실시간 알림 시스템 실시간 데이터 스트리밍, 로그 처리, 이벤트 소싱

 

각 시스템에 대해 용도별로 사용 구분을 해 본다.

기술 적합한 경우
Kafka - 대용량 데이터 처리가 필요할 때
- 실시간 데이터 스트리밍 및 고성능 요구 시
- 고가용성이 필요한 경우
- 이벤트 기반 로그 추적 및 재처리가 필요한 경우 
=> 대규모 실시간 데이터 처리와 고가용성이 필요한 시스템에 적합
RabbitMQ - 복잡한 라우팅을 유연하게 처리해야 할 때
- 정확한 요청, 응답이 필요한 경우
- 트래픽이 적지만 장시간 실행되는 안정적인 백그라운드 작업 처리 시
=> 복잡한 라우팅과 정확한 요청, 응답이 필요한 상황에 적합
Redis - 이벤트 데이터가 DB에 저장되고 미들웨어에 저장할 필요가 없을 때
- 소비자에게 알림 보장이 필요 없고 단순히 푸시 알림만 중요할 때
- 유지 보수가 편리한 시스템이 필요할 때 
=> 빠른 실시간 알림과 유지보수 편리성이 중요한 시스템에 적합 

 

 


대시보드(관제)의 알람 기능에는 어떤 시스템이 적합할까?

 

(기능 요구사항)

- 긴급 알람이 실시간으로 정확하게 표시되어야 한다.

- 대량의 알람 데이터가 발생할 경우 DB의 과부하를 피해야 한다.

- 동일한 유형의 알람을 하나로 묶어 발생 횟수를 표시하는 기능이 필요하다.

- 알람이 발생하면 자동 또는 수동으로 해당 알람에 대한 조치를 취할 수 있는 기능이 필요하다.

- 알람이 발생한 후에 보관하거나 삭제할 수 있어야 한다. 

 

 

1. Kafka

- 실시간 스트리밍이나 이벤트 기반 시스템에서의 알람 처리에 적합 

- 일반 메시징 시스템보다는 약간의 처리 지연 가능성 있음 

 

2. RabbitMQ

- 정확한 요청-응답이 필요한 시스템에 유리 

- 카프카보다 처리 속도가 느림 

 

3. Redis

- 빠른 푸시 알림과 실시간 처리에 적합

- 장기 보관과 영속성에 대한 기능이 약함 (메모리 기반)

 

위 요구사항과 같은 긴급 알람과 대규모 알람 데이터 처리가 중요한 시스템에서는 Kafka가 가장 적합하다.