1. 개요
본 글은 Kafka에 대해서 간단하게 알아보는 글이다.
- 공식 문서 Kafka 소개 내용
- 아파치 카프카(Apache Kafka)는 고성능 데이터 파이프라인, 스트리밍 분석, 데이터 통합, 미션 크리티컬 애플리케이션을 위해 수천개의 기업에서 사용하는 오픈소스 분산 이벤트 스트리밍 플랫폼(open-source distributed event streaming platform)입니다.
이벤트 스트리밍?
DB, 센서, 클라우드 서비스 및 소프트웨어 애플리케이션과 같은 이벤트 소스(수많은 곳)에서 이벤트 스트림의 형태로 실시간으로 데이터를 캡처하는 방식
1-1. 용어 정리

- 카프카 클러스터
Broker들의 모임으로 확장성과 고가용성을 위해 Broker들이 클러스터로 구성되어 있다.
- 브로커(Broker)
각각의 Kafka 서버이다. Producer로부터 메세지를 받아 특정 Topic에 저장하고 해당 Topic을 구독한 Consumer에게 메세지를 전달한다.
(하나의 브로커는 여러개의 Topic을 가질 수 있다.)
- Topic
메세지를 구분하는 단위로 Producer로부터 전송된 데이터는 토픽이름으로 구별된다.
- Zookeeper
Kafka 클러스터 상태와 정보 등을 관리하는 역할로 기존에는 Kafka 구동 시 꼭 필요했다.
❗kafka3.0부터 주키퍼가 필요없는 KRaft모드가 프로덕션 환경에서 사용이 권장되기 시작했고, 최근 4.0부터는 주키퍼 지원이 완전히 제거 되었다.
- producer
데이터 제공자(메시지 발행자)
- consumer
데이터 사용자(메시지 소비자)
- Queue
Producer의 데이터를 임시 저장 후 Consumer에게 제공하는 장소
2. 카프카 탄생의 이유
Kafka는 비즈니스 소셜 네트워크 서비스인 링크드인에서 개발했다.
아래는 카프카 개발 이전의 링크드인 데이터 파이프라인이다.

애플리케이션 -> DB까지 end-to-end로 연결 되어 있다보니 점점 시스템이 복잡해지고 파이프라인 관리도 동시에 어려워지는 것을 볼 수 있다.
이를 해결하기 위해 모든 시스템이 하나의 플랫폼으로 데이터를 전송하고 실시간 처리가 가능하며, 확장성이 좋은 시스템을 만들어야 했고, 그것이 Kafka이다.
아래는 모든 이벤트/데이터 흐름을 중앙(Broker)에서 관리하는 카프카가 도입된 이후 링크드인의 파이프라인 구조이다.

- 이벤트/데이터 흐름을 중앙(Broker)에서 관리하게 되었다.
- 새로운 시스템이 생겨도 중앙에 연결하면 되므로 확장성이 증가했다.
3. 카프카의 동작 방식
카프카는 기본적으로 Pub-Sub 모델의 메세지 큐(MQ) 형태로 동작한다.
3-1. 메세지 큐(MQ)?

메세지 큐 방식은 위 사진과 같이 Endpoint 간에 직접적으로 통신하지 않고, 중간에 Queue를 통해 중개되는 방식이다.
- 메시지 큐의 장점
- 비동기 : 요청을 즉시 처리할 필요 없이 큐에 저장해두고, 나중에 필요할때 처리할 수 있다.
- 결합도 감소 : 서비스들이 서로를 직접 알 필요 없이, 오직 Queue와만 통신한다.
- 트래픽 제어, 안정성 향상 : 서비스 폭주 시 모든 요청을 한번에 처리 하는 것이 아닌 메시지 큐를 통해서 순차적으로 처리가 가능하다.
- 확장성 : 작업량이 많아져 메시지 큐에 메시지만 계속 쌓인다면 Consumer 서비스의 수만 늘려서 병렬적으로 처리하면 된다.
- 보장성 : 만약 Consumer가 데이터 처리 중 장애로 중단된다면, 큐는 다른 Consumer에게 해당 메세지를 다시 전달하여 처리를 보장한다.
3-2. Pub-Sub?
메시지 큐는 크게 Point-to-Point(P2P), Publish/Subscribe(Pub/Sub)으로 구분된다.
- P2P : 한명의 Producer와 한명의 Consumer로 메세지 전송 대상이 고정되어 있다.
- Pub/Sub : Producer가 특정 Topic(토픽)에 메시지를 보내면, 해당 Topic을 구독한 Consumer가 해당 메세지를 받는 구조이다.

이러한 형태로 Pub-Sub 모델이 이루어져 있다.
3-3. Topic 내부
Kafka Broker 내부의 하나의 Topic은 여러 개의 파티션으로 나눠진다.
- 파티션의 두 가지 목적
- 병렬 처리: 데이터를 여러 파티션에 분산하여, 여러 컨슈머가 동시에 데이터를 처리하게 함으로써 처리량 극대화
- 데이터 분산: 데이터를 여러 서버(브로커)에 나누어 저장함으로써 한 서버의 용량을 초과하는 데이터를 다루고, 장애 발생 시 안정성 향상

- 파티션 키가 있는 경우
- 메세지에 키를 지정하면, 메시지에 키를 지정하면, 키의 해시값(hash)을 기준으로 파티션이 결정된다.
- 따라서 동일한 키를 가진 메시지들은 항상 같은 파티션에 순차적으로 저장된다.
- 파티션 키가 없는 경우
- 메세지는 라운드 로빈 방식으로 여러 파티션에 메세지를 순서대로 하나씩 분배한다.
파티션 키는 Producer가 어느 파티션에 저장할지 정할 때 쓰이는 것
파티션은 위 사진의 인덱스 값처럼 보이는 Offset(메세지의 위치 식별자)를 갖는다.
만약 파티션 0에 새로운 메세지가 추가된다면 Offset 값이 6인 레코드가 추가된다.
Consumer는 Offset을 통해 자신이 어디까지 데이터를 처리했는지 식별할 수 있다.
이때, Offset값은 수동 or 자동 커밋을 통해 업데이트 된다.
3-3-1. 컨슈머 그룹
여러 파티션의 데이터를 병렬로 처리하는 주체가 바로 컨슈머 그룹이다.
Kafka는 토픽의 파티션을 컨슈머 그룹 내의 컨슈머 인스턴스들에게 나누어 할당한다.
각 파티션이 그룹 내의 정확히 하나의 컨슈머에 의해서만 소비되도록 하고 컨슈머들은 각자의 offset으로 관리한다.

위 사진과 같이 4개의 파티션이 있고, 컨슈머 그룹의 컨슈머가 4개라면 각각 하나의 파티션씩 할당 받아 해당 토픽의 작업을 병렬 처리할 수 있게 된다.
❗컨슈머 그룹의 컨슈머 개수는 파티션 개수보다 많아질 수 없다. 만약 컨슈머가 파티션보다 많아지면, 남는 컨슈머는 파티션을 할당받지 못하고 유휴(idle) 상태가 된다. 따라서 처리량을 최대로 높이려면 컨슈머 개수를 파티션 개수와 동일하게 맞추는 것이 가장 이상적이다.
4. 정리
결국 카프카는 복잡하게 얽힌 시스템 간의 데이터 파이프라인을 정리하기 위해 탄생했다.
수많은 서비스에서 쏟아지는 데이터를 한 곳에서 효율적으로 처리하는 거대한 '데이터 물류 센터'라고 생각할 수 있다.
이 물류 센터(카프카)를 통해 데이터를 보내는 쪽과 받는 쪽이 서로를 직접 알 필요가 없어지면서, 시스템은 더 유연해지고 확장하기 쉬운 구조를 갖게 된다.
