이번 토스 면접에서 kafka에 대해서 질문을 줬지만 난 대답하지 못했다.
왜? 잘 모르니까..
그냥 얼레벌레 써봤지.. 뭘 제대로 알았겠어..
그래서 후회돼서 복기해본다..
Kafka에 대한 큰 흐름
- 토픽(topic)은 물리적인 메시지 스트림이고, 물리적으로는 여러 개의 파티션(partition)으로 쪼개진다고 한다.
- 파티션은 추가만 되는 순서 있는 로그라고 보면되고 메시지마다 오프셋(offset)이라는 단조 증가 번호가 붙는다.
- 순서 보장은 "파티션 안에서만" 되고, 토픽 전체로는 순서를 보장하지 않는다.
- "같은 키는 같은 파티션으로 보낸다"가 중요한 포인트
- 프로듀서는 메시지 키가 있으면 hash(key) % 파티션 수로 파티션을 고르고, 키가 없으면 스티키 파티셔너로 분리한다.
- 즉, 순서가 중요한 단위 (예: 같은 주문 ID, 같은 판매자 ID)는 키로 묶어야 그 단위 안에서 순서가 지켜진다.
- 복제 (Replication) : 각 파티션은 리더 1개 + 팔로워 N개로 복제된다. 읽기/쓰기는 리더가 처리하고 팔로워가 따라 온다. 따라잡고 있는 복제본 집합을 ISR(In-Sync Replicas)라고 한다.
토픽이란?
- 메시지를 종류별로 담는 이름표
- 메시지를 보내는 쪽(프로듀서)는 "이 메시지를 어느 토픽에 적을까?"를 정하구, 받는 쪽(컨슈머)는 "나는 어느 토픽을 읽을까?"를 정한다.
- 주문 토픽을 구독한 컨슈머는 주문 메시지만 받지, 결제 메시지는 받지 않는다.
- 종류가 섞이지 않게 칸막이를 쳐주는 게 토픽의 역할
- 토픽은 이름일 뿐, 실제 데이터가 저장되는 물리적인 통이 아니다.
파티션이란?
- 토픽이 이름이었다면? 파티션은 실제로 메시지가 줄줄이 쌓이는 진짜 통!
- orders 토픽을 파티션 3개로 만들면 주문이 들어올 때마다 셋 중 하나의 파티션에 가서 맨 뒤에 한 줄씩 추가된다.
- 글을 적을 때 항상 맨 아래 빈 줄에 이어 쓰는 것과 같다. 중간에 끼워넣거나 지우지 않고, 무조건 뒤에만 붙인다.
- 추가만 되는 로그
브로커(broker)란?
- 그 통들이 실제로 올라가 있는 컴퓨터(서버)가 브로커.
- 당시 운영 카프카는 브로커 3대 클러스터
- replication factor(복제 계수) : 복사본을 총 몇 개로 유지할지 정하는 숫자
- 원본 포함 전체 개수
- replication factor = 1 → 원본 하나뿐, 복사본 없음 (그 브로커 죽으면 데이터 날아감)
- replication factor = 2 → 원본 1 + 복사본 1 = 총 2벌
- replication factor = 3 → 원본 1 + 복사본 2 = 총 3벌
- In-Sync Replicas (ISR) - "잘 따라오고 있는 복사본"
- 복사본(팔로워)이 3벌 있다고 해서, 그게 항상 원본이랑 똑같다는 보장은 없다.
- 네트워크가 느리거나 한 브로커가 버벅대면, 어떤 팔로워는 리더가 받은 최신 메시지를 아직 못 베낀 채 뒤처질 수 있다.
- In-Sync (싱크 맞음) : 리더를 거의 실시간으로 따라잡고 있는 복사본
- Out-of-Sync (뒤처짐) : 너무 늦어서 신뢰할 수 없는 복사본
- 리더가 죽었을 때, 새 리더는 반드시 ISR 안에 있는 복사본 중에서만 뽑기 때문에 ISR은 중요하다.
파티션이 카프카의 거의 전부인 이유?
- 병렬 처리
- 통이 3개니까, 컨슈머 3명이 각자 하나씩 동시에 읽을 수 있다.
- 처리 속도를 올리고 싶으면 파티션을 늘린다
- 컨슈머를 몇 개 띄울지는 개발자가 정해서 직접 실행한다.
- 보통 애플리케이션(서버) 인스턴스를 여러 개 띄우거나, 한 애플리케이션 안에서 컨슈머 스레드 수를 늘리는 식
- 순서 보장(통 안에서만)
컨슈머 그룹과 파티션의 관계
- 한 컨슈머 그룹 안에서, 하나의 파티션은 정확히 하나의 컨슈머만 소비한다.
- 반대로, 하나의 컨슈머는 여러 파티션을 동시에 소비할 수 있다.
- 결론
- 한 그룹의 최대 병렬 처리량은 파티션 개수로 제한된다.
- 컨슈머를 파티션보다 많이 띄워도, 초과분은 그냥 논다.

- 파티션이 4개면 아무리 컨슈머를 늘려도 동시에 4개까지만 일한다.
- 처리량을 더 늘리려면 컨슈머가 아니라 파티션을 늘려야 한다.
- 반대로 컨슈머가 파티션보다 적으면(컨슈머 2개) 한 컨슈머가 여러 파티션을 나눠 가진다.
- 죽지는 않지만 그만큼 부하가 몰린다.
- 다른 컨슈머 그룹은 같은 파티션을 독립적으로 또 읽는다.
- 그룹마다 오프셋을 따로 관리하기 때문이다.
- 토픽에 그룹/토픽/파티션 단위로 저장
- "같은 메시지를 여러 시스템이 각자 소비"가 가능한 이유.
poll 루프와 리밸런싱
- 컨슈머는 어떻게 "살아있다"고 인정받는가? (heartbeat.interval.ms vs session.timeout.ms vs max.poll.interval.ms)
- poll()이 한 번에 가져온 배치를 처리하는 데 너무 오래 걸리면 무슨 일이 벌어지는가?
- 그게 왜 리밸런싱 폭풍 → 컨슈머 증식 → 중복 처리로 번지는가?
- AckMode.BATCH였던 게 왜 불에 기름을 부었는가?









