Kafka는 대규모 트래픽 상황에서 이벤트를 안전하게 저장하고, 나중에 Consumer가 천천히 처리할 수 있게 도와주는 메시지 저장소이다.
쉽게 말하면 Kafka는 요청을 잠깐 쌓아두는 큰 대기줄이다.
일반적인 서비스 흐름은 다음과 같다.
사용자 요청 → 서버 → DB / Redis 저장 또는 조회
이 방식은 요청이 적을 때는 괜찮지만, 트래픽이 갑자기 몰리면 문제가 생긴다.
예를 들어 다음과 같은 상황이다.
이때 서버가 모든 요청을 즉시 DB나 Redis에 처리하려고 하면 서버와 DB에 큰 부담이 생긴다.
Kafka를 사용하면 구조가 다음처럼 바뀐다.
사용자 요청 → 서버 → Kafka 저장
↓
Consumer가 나중에 처리
서버는 무거운 작업을 바로 하지 않고, Kafka에 이벤트만 넣고 빠르게 응답한다.
실제 처리는 Consumer가 Kafka에서 메시지를 꺼내 천천히 처리한다.
즉, Kafka는 다음 역할을 한다.
Kafka는 갑자기 트래픽이 폭발해도 데이터를 잃지 않고, 이벤트를 안전하게 모아두었다가 여러 Consumer가 나누어 처리할 수 있게 해주는 시스템이다.
Kafka를 음식점 주문 시스템으로 생각하면 쉽다.
| Kafka 개념 | 음식점 비유 | 설명 |
|---|---|---|
| Producer | 손님 | 주문을 넣는 사람 |
| Kafka | 주문 대기판 | 주문을 순서대로 저장하는 곳 |
| Topic | 주문 종류별 게시판 | 치킨 주문, 피자 주문처럼 메시지를 분류하는 공간 |
| Partition | 게시판을 나눈 칸 | 주문을 여러 줄로 나누어 빠르게 처리하기 위한 단위 |
| Consumer | 요리사 | 주문을 가져가서 처리하는 사람 |
| Consumer Group | 요리사 팀 | 여러 요리사가 주문을 나누어 처리하는 팀 |
| Offset | 주문 번호 | 어디까지 처리했는지 기억하는 번호 |
| Broker | 주문 대기판 서버 | Kafka 메시지가 실제로 저장되는 서버 |
Producer는 Kafka로 메시지를 보내는 역할이다.
보통 API 서버가 Producer 역할을 한다.
예를 들어 사용자가 쇼핑몰에서 카테고리를 클릭하면 서버는 다음과 같은 이벤트를 Kafka에 보낸다.
{
"userId": 101,
"category": "fashion",
"timestamp": "2025-11-26T14:00:00"
}
즉, Producer는 이벤트를 만들어 Kafka에 넣는 역할이다.
Topic은 메시지를 종류별로 모아두는 공간이다.
쉽게 말하면 메시지를 담는 폴더이다.
예시는 다음과 같다.
category-click
order-created
order-canceled
payment-completed
카테고리 클릭 이벤트는 category-click Topic에 저장하고, 주문 생성 이벤트는 order-created Topic에 저장한다.
즉, Topic은 같은 종류의 메시지를 모아두는 단위이다.
Partition은 하나의 Topic을 여러 칸으로 나눈 것이다.
예를 들어 category-click Topic에 Partition이 3개 있다면 다음과 같은 구조가 된다.
category-click
├─ Partition 0
├─ Partition 1
└─ Partition 2
Partition이 필요한 이유는 병렬 처리를 하기 위해서이다.
Partition 1개 = 한 줄로 처리
Partition 3개 = 세 줄로 나누어 처리
즉, Partition 수가 많아질수록 동시에 처리할 수 있는 양이 증가한다.
단, 하나의 Partition은 같은 Consumer Group 안에서 한 번에 하나의 Consumer만 처리할 수 있다.
Consumer는 Kafka에 쌓인 메시지를 읽어서 처리하는 역할이다.
예를 들어 Consumer는 다음 작업을 할 수 있다.
즉, Consumer는 Kafka에 저장된 이벤트를 실제 비즈니스 로직으로 처리하는 역할이다.
Consumer Group은 여러 Consumer를 하나의 팀으로 묶은 것이다.
예를 들어 Partition이 3개이고 Consumer도 3개라면 다음처럼 나누어 처리할 수 있다.
Partition 0 → Consumer 1
Partition 1 → Consumer 2
Partition 2 → Consumer 3
이 경우 동시에 3개의 작업을 처리할 수 있다.
하지만 Partition이 3개인데 Consumer가 5개라면 2개의 Consumer는 놀게 된다.
Partition 수 = 병렬 처리의 최대치
즉, Consumer를 무조건 많이 늘린다고 빨라지는 것이 아니다.
병렬 처리량은 Partition 수에 의해 결정된다.
Offset은 Kafka 메시지의 번호이다.
Partition 안에 메시지가 저장될 때 다음처럼 번호가 붙는다.
Offset 0
Offset 1
Offset 2
Offset 3
Consumer는 Offset을 보고 어디까지 읽었는지 기억한다.
그래서 Consumer가 중간에 죽거나 서버가 재시작되어도 마지막으로 읽은 위치부터 다시 처리할 수 있다.
즉, Offset은 어디까지 읽었는지 기록하는 책갈피이다.
Broker는 Kafka 서버이다.
Producer가 보낸 메시지는 실제로 Broker 안에 저장된다.
Broker의 역할은 다음과 같다.
쉽게 말하면 Broker는 Kafka 메시지가 실제로 저장되는 창고이다.
Kafka는 Consumer가 메시지를 읽었다고 해서 메시지를 바로 삭제하지 않는다.
Consumer는 단지 Offset만 기록한다.
메시지는 Kafka에 남아 있다가 설정된 보관 기간이 지나면 삭제된다.
그래서 다른 Consumer Group은 같은 메시지를 처음부터 다시 읽을 수 있다.
예를 들어 category-click Topic을 여러 팀이 사용할 수 있다.
추천 서비스 팀 → 사용자 관심사 분석
랭킹 서비스 팀 → Redis 인기 카테고리 업데이트
로그 저장 팀 → 장기 보관용 DB 저장
각 Consumer Group은 Offset을 따로 관리하기 때문에 서로 영향을 주지 않는다.
사용자가 카테고리를 클릭하면 서버는 Kafka에 이벤트를 보낸다.
사용자 클릭
↓
API 서버
↓
Kafka Topic: category-click
↓
Consumer
↓
Redis ZSET 점수 증가
↓
인기 카테고리 TOP 10 조회
이 구조의 장점은 API 서버가 Redis 점수 증가 작업까지 직접 하지 않아도 된다는 점이다.
서버는 Kafka에 이벤트만 넣고 끝낸다.
Consumer가 나중에 Kafka 메시지를 읽어서 Redis를 업데이트한다.
아니다.
Kafka의 병렬 처리 최대치는 Partition 수가 결정한다.
Partition 3개 + Consumer 3개 = 효율적
Partition 3개 + Consumer 5개 = 2개 Consumer는 대기
Partition 3개 + Consumer 1개 = Consumer 1개가 전부 처리
따라서 Consumer 수만 늘린다고 무조건 빨라지지 않는다.
아니다.
Kafka는 메시지를 저장하지만 일반적인 조회용 DB는 아니다.
| 용도 | 적합한 기술 |
|---|---|
| 빠른 조회 | Redis |
| 영구 저장 / 검색 | DB |
| 이벤트 저장 / 전달 / 재처리 | Kafka |
Kafka는 데이터를 조회하기 위한 저장소라기보다 이벤트를 안전하게 전달하고 재처리하기 위한 시스템이다.
정확히 말하면 Kafka 자체가 실시간 처리를 하는 것은 아니다.
Kafka는 이벤트를 저장하고, Consumer가 그 이벤트를 빠르게 읽어서 처리할 수 있도록 도와준다.
즉, Kafka는 실시간 처리처럼 보이게 만드는 이벤트 저장소에 가깝다.
Kafka를 Broker 1대로만 운영하면 위험하다.
단일 Broker가 죽으면 다음 문제가 생긴다.
그래서 실무에서는 여러 Broker를 묶은 Kafka 클러스터를 사용한다.
Kafka Cluster
├─ Broker 1
├─ Broker 2
└─ Broker 3
Kafka는 Partition을 여러 Broker에 복제해서 저장할 수 있다.
예를 들어 Replication Factor가 3이면 하나의 Partition이 총 3개 복제본으로 유지된다.
Partition 0
├─ Broker 1: Leader
├─ Broker 2: Follower
└─ Broker 3: Follower
역할은 다음과 같다.
| 개념 | 설명 |
|---|---|
| Leader | Producer와 Consumer가 실제로 통신하는 Partition |
| Follower | Leader 데이터를 복제해두는 예비 Partition |
Leader가 있는 Broker에 장애가 발생하면 Follower 중 하나가 새로운 Leader로 승격된다.
이것을 Failover라고 한다.
즉, Kafka 클러스터는 장애가 발생해도 서비스가 멈추지 않도록 도와준다.
예전 Kafka는 클러스터 메타데이터 관리를 Zookeeper에 맡겼다.
하지만 Kafka 3.x부터는 Kafka 내부에서 직접 메타데이터를 관리하는 KRaft 방식을 사용할 수 있다.
KRaft는 다음 역할을 한다.
쉽게 말하면 KRaft는 Kafka 클러스터의 내부 관리자 역할을 한다.
Kafka UI를 사용하면 Kafka 상태를 화면에서 쉽게 확인할 수 있다.
할 수 있는 작업은 다음과 같다.
예를 들어 category-click Topic을 만들 때 다음처럼 설정할 수 있다.
Topic name: category-click
Partitions: 3
Replication factor: 1
클러스터 환경에서는 Replication factor를 3으로 설정해 Leader와 Follower 구조를 확인할 수 있다.
Kafka를 사용한 이벤트 처리 흐름은 다음과 같다.
1. 사용자가 상품 또는 카테고리를 클릭한다.
2. API 서버가 클릭 이벤트를 Kafka Topic에 저장한다.
이때 API 서버는 무거운 처리를 하지 않고 빠르게 응답한다.
3. Kafka는 메시지를 Topic과 Partition에 순서대로 저장한다.
4. Consumer Group에 속한 Consumer들이 메시지를 나누어 읽는다.
5. Consumer는 Redis 점수 증가, DB 저장, 추천 데이터 생성 같은 작업을 처리한다.
6. Consumer는 Offset을 기록해서 어디까지 읽었는지 기억한다.
Kafka는 대규모 트래픽 환경에서 서버와 DB를 보호하기 위한 이벤트 저장소이다.
API 서버는 요청을 Kafka에 빠르게 저장하고, Consumer가 나중에 메시지를 읽어 처리한다.
Topic은 메시지를 종류별로 나누는 폴더이고, Partition은 병렬 처리를 위한 단위이다.
Consumer Group은 여러 Consumer가 팀처럼 메시지를 나누어 처리하는 구조이다.
Offset은 Consumer가 어디까지 읽었는지 기억하는 번호이다.
Broker는 Kafka 메시지가 실제로 저장되는 서버이고, 여러 Broker를 묶으면 Kafka 클러스터가 된다.
Kafka 클러스터에서는 Replica, Leader, Follower 구조를 통해 장애가 발생해도 서비스를 계속 유지할 수 있다.
즉, Kafka는 대규모 트래픽을 안정적으로 처리하기 위한 핵심 기술이다.