| Kafka란?
- 카프카(Kafka)는 고성능 분산 이벤트 스트리밍 플랫폼이다. 흔히 메시지(이벤트) 큐라고 불리우며 Pub-Sub 모델 형태로 동작하며 분산환경에 특화되어 있다.
- producer 라고 불리우는 source application으로 부터 전송 받은 메시지를 broker에 저장해두며 이를 consumer라는 target application에서 사용할 수 있도록 해준다.
- kafka는 pub/sub 모델로써 consumer가 broker에 있는 메시지를 polling하는 형태로 broker의 부하를 줄여주어 효율적으로 대용량 처리를 병렬로 가능하게끔 한다.
- 메시지를 파일 시스템에 저장하기 때문에 데이터의 영속성을 보장한다.
- 기존의 메시징 시스템은 메시지 큐에 적재된 메시지 양이 많을수록 성능이 크게 감소하였지만, Kafka는 메시지를 파일 시스템에 저장하기 때문에 성능이 크게 감소하지 않는 이점이 있다.
| 주요 내용 정리
- Producer
- 데이터를 생성하여 kafka cluster에 데이터를 전송하는 역할을 한다.
- kafka는 topic이라는 주제에 따라 데이터를 전송하고 broker는 topic을 기준으로 구분하여 데이터를 저장한다.
- 설정에 따라 재처리 또는 실패에 대해 관리가 가능하다. ( DLQ = Dead Letter Queue 로 관리 할 수도 있다.)
- kafka는 key를 고유 로직으로 hashing 처리하여 저장하기에 동일한 key는 동일한 파티션에 항상 담기게 된다.
- But! 파티션이 늘어난다면(변동이 생긴다면) 이 rule이 깨지기 때문에 rule을 유지해야 하는 서비스라면 최초에 설정시 파티션의 갯수도 적정하게 설정할 필요가 있다.
- Broker
- 데이터 저장 : producer로 부터 전송받은 데이터를 영속적으로 저장한다. 저장시에는 topic별로 , 그리고 토픽내 파티션에 분산하여 저장한다.
- producer로 받은 데이터를 consumer가 가져갈 수 있게 역할을 수행. consumer는 토픽별로 데이터를 읽어가서 처리가 가능하다.
- kafka cluster 관리 : broker는 cluster의 상태와 구성을 관리한다. 파티션 중 리더 파티션을 선출하고 레플리카의 데이터 복제를 관리.
- Topic
- 메시지를 저장하는 논리적인 그룹의 단위
- RDB로 생각하면 각각의 테이블 처럼 데이터를 저장함.
- 데이터의 형태는 다양한 형태로 저장 가능 ( ex. string, set, json 등등)
- 하나의 토픽은 보통 1개 이상의 파티션으로 구성되어 분산 저장(처리)이 되는 형태.
- 토픽에 저장된 데이터는 consumer가 소비해도 삭제되지 않는다. ( 고가용성이 가능한 이유 중 하나다.)
- 메시지 삭제 정책은 존재하여 시간이나 데이터 총 사이즈로 설정할 수 있다.
- Partition
- 토픽은 하나의 브로커에 하나의 논리적인 곳에 저장되지 않고 데이터를 파티션으로 나누어서 저장한다.
- 라운드-로빈 방식으로 데이터를 각 파티션에 저장한다.
- 파티션이 나뉘어져 있어서 병렬로 데이터의 비동기 처리가 가능하다.
- 파티션이 2개 이상이면 데이터 처리의 순서 보장은 불가능하다.
- Consumer
- kafka broker에 topic에 저장된 데이터를 subscribe하여 그에 맞게 처리하는 역할을 한다.
- consumer는 보통 consumer group을 구성하여 그룹내에서 파티션을 각각 맵핑 및 접근하여 처리한다.
- Consumer group
- consumer group은 특정 토픽을 동일하게 처리할 때 병렬로 분산 처리하기 위해서 그룹핑된 컨슈머 집합.
consumer group에 속한 각각의 컨슈머는 하나의 토픽에 여러개의 파티션이 있을 때 같은 파티션에는 하나의 컨슈머만 접근이 가능하도록 제한이 되어 있다. 하지만 하나의 컨슈머는 하나의 토픽에 속한 여러개의 파티션에는 중복적으로 접근하여 처리가 가능하다. - 컨슈머 그룹내에는 group leader가 존재하여 consumer가 이슈가 있거나 할 때 리밸런싱을 하는 등의 관리를 맡는다. reader consumer는 토픽에 최초로 ack를 보내어 응답을 받은 consumer가 자동으로 할당된다.
- consumer group은 특정 토픽을 동일하게 처리할 때 병렬로 분산 처리하기 위해서 그룹핑된 컨슈머 집합.
- *** 컨슈머 그룹과 파티션 맵핑 예시 ****
- 1] join group 호출 (내가 너의 토픽을 consume 할거야!)
- 2] group leader 선출 (선착순!!)
- 3] 파티션과 컨슈머 그룹내 consumer와의 맵핑
- 4] 해당 맵핑 정보 전송 ( Group coordinator는 해당 정보를 zookeeper에게 전달)
- 5] 컨슈머에게 해당 내용 전파 ( 전파된 파티션으로 부터 데이터 consume 진행)
** 파티션과 컨슈머 갯수별 맵핑은??
- 1) 토픽 파티션 1 : 컨슈머 1 => 이렇게 구성할 경우 순서의 보장은 될 수 있으나 컨슈머가 문제가 생길경우 메시지를 처리할 수 없다.(장애발생)
2) 토픽 파티션 1: 컨슈머 그룹내 컨슈머 4개 => 이럴 경우 리더 컨슈머가 문제가 생길 경우 follower 컨슈머가 그 작업을 대신할 수 있다.
(하지만 컨슈머 스레드 3개는 아무일도 하지 않고 휴면 상태와 같이 있게 된다.)
3) 토픽 내 파티션 1개 : 컨슈머 그룹내 컨슈머 2개 => 같은 컨슈머 그룹내에서 동일 토픽에 파티션에는 1개의 컨슈머만접근 가능한 제한으로 인해 한개의 컨슈머는 휴면 상태와 다름 없이 일을 하지 않는다.

4) 토픽내 파티션 4 : 컨슈머 그룹내 컨슈머 2개 => 이럴 경우 컨슈머 1대당 2개의 파티션에 붙어서 R-R방식으로 데이터를 가져와 처리한다.
5) 토픽내 파티션 4 : 컨슈머 그룹내 컨슈머 2개 => 이럴 경우 컨슈머 1대당 2개의 파티션에 붙어서 R-R방식으로 데이터를 가져와 처리한다.
6) 토픽내 파티션 4개 : 컨슈머 그룹 2개 => 각각의 컨슈머 그룹은 토픽에 파티션에 1:1로 맵핑하여 동일한 토픽 메시지를 같이 사용할 수 있다. ( 두 가지 로직을 태울 수 있다.)
위와 같이 컨슈머 그룹이 두 개라면 브로커에 하나의 토픽에 파티션은 consumer group별로 각각의 offset을 가지고 있어서 데이터가 어디까지 처리했는지 구분이 가능하게끔 제공하고 있다.
| 주요 config
- Producer
속성 | 설명 | 예시 |
bootstrap.servers(BOOTSTRAP_SERVERS_CONFIG) | 카프카 클러스터의 부트스트랩 서버 목록을 지정하고 연결하는데 사용. | localhost:9092 |
acks(ACKS_CONFIG) | 프로듀서가 메시지를 보낸 후 리더(broker)로부터 확인(acknowledgment)을 기다릴지 여부를 설정 | 0(기다리지 않음 - 손실 가능성 존재) 1(리더 브로커에게만 전송 여부 받기), all(레플리케이션에 저장 여부도 받기) |
retries(RETRIES_CONFIG) | 메시지 전송 중에 일시적인 오류가 발생한 경우 프로듀서가 재시도할 최대 횟수를 설정 | 0 : 재처리 하지 않음. 5 : 5회 재전송함. |
compression.type(COMPRESSION_TYPE_CONFIG) | 메시지 압축 방법을 설정합니다. 압축을 사용하면 전송 대역폭을 줄일 수 있음. | none, gzip, snappy, lz4, zstd |
key.serializer , value.serializer | 프로듀서에서 사용하는 메시지의 키(key)와 값(value)의 직렬화 방법을 설정 | StringSerializer |
- consumer
속성 | 설명 | 예시 |
bootstrap.servers(BOOTSTRAP_SERVERS_CONFIG) | 카프카 클러스터의 부트스트랩 서버 목록을 지정하고 연결하는데 사용. | localhost:9092 |
group.id | 컨슈머 그룹의 식별자를 설정합니다. 같은 그룹에 속한 컨슈머들은 메시지를 공유하여 소비한다. | example_group_id |
enable.auto.commit | 자동 커밋을 사용할지 여부를 설정합니다. 자동 커밋을 활성화하면 컨슈머가 일정 주기마다 오프셋을 자동으로 커밋 | true |
auto.commit.interval.ms | 자동 커밋 주기를 설정합니다. enable.auto.commit가 true로 설정되어 있을 때 커밋 주기마다 오프셋이 커밋 | 5000 |
auto.offset.reset | 컨슈머가 처음 실행되거나 오프셋이 존재하지 않는 경우 어떻게 오프셋을 재설정할지를 설정 | earliest(가장 적은 offset), latest(가장 최근 offset), none(오프셋을 재설정하지 않음) |
max.poll.records | 단일 poll() 호출에서 반환되는 최대 레코드 수를 설정 | 1 or 100 , 200, 300 … |
session.timeout.ms | session timeout 최대 설정 시간 | 10000 |
max.poll.interval.ms | polling interval 최대 시간 | 50000 |
key.deserializer ,value.deserializer | 컨슈머에서 사용하는 메시지의 키(key)와 값(value)의 역직렬화 방법을 설정 | StringDeserializer |
** 리밸런싱(브로커 대상 토픽과 컨슈머의 재맵핑) 과 관련된 주요 설정들
# 요청에 대해 응답을 기다리는 최대 시간
requestTimeoutMs: 30000
# 컨슈머와 브로커사이의 세션 타임 아웃시간.
sessionTimeoutMs: 30000
# session.timeout.ms와 밀접한 관계가 있으며 session.timeout.ms보다 낮아야한다. 일반적으로 1/3
heartbeatIntervalMs: 10000
# 컨슈머가 polling하고 commit 할때까지의 대기시간
maxPollIntervalMs: 600000
# poll ()에 대한 단일 호출에서 반환되는 최대 레코드 수
maxPollRecords: 1
위에서 보면 consumer는 한 번에 하나의 레코드를 가져오고 , polling을 하여 처리대기 시간은 상대적으로 길게 잡았으며, 세션 타임아웃보다 heartbeats 인터벌은 짧게 잡아 컨슈머의 이상여부(정상 실행 상태여부) 를 체크할 수 있게 설정해야 한다.
그리고 세션 타임아웃은 폴링한 데이터가 정상적으로 처리가 가능한 이상 수준의 타임아웃을 가져야 Rebalancing 이슈가 발생하지 않는다.
그러므로 max poll record를 너무 길게 잡으면 세션 타임 아웃 등 설정 정보도 늘어나서 컨슈머가 실제로 정상적인지 체크하는데 어려움이 발생할 수 도 있다.
session.timeout.ms
이 옵션은 heartbeat 없이 얼마나 오랫동안 컨슈머가 있을 수 있는지를 제어하며 heartbeat.interval.ms와 밀접한 관련이 있어서 일반적으로 두 속성이 함께 수정된다.
heartbeat.interval.ms 컨슈머가 얼마나 자주 heartbeat을 보낼지 조정한다. session.timeout.ms보다 작아야 하며 일반적으로 1/3로 설정 ex. 3000 (3초)
max.poll.interval.ms
이러한 경우에 컨슈머가 무한정 해당 파티션을 점유할 수 없도록 주기적으로 poll을 호출하지 않으면 장애라고 판단하고 컨슈머 그룹에서 제외시키도록 하는 옵션이다.300000 (5분)
max.poll.records
이 옵션으로 polling loop에서 데이터 양을 조정 할 수 있다.
enable.auto.commit
백그라운드로 주기적으로 offset을 commit = true
auto.commit.interval.ms
주기적으로 offset을 커밋하는 시간5000 (5초)
auto.offset.reset
이전 offset값을 찾지 못하면 error 발생 Ex.latest
**추가 정보 : kafka vs rabiitMQ vs redis pub/sub 의 비교
참고 정보 :
https://velog.io/@hyun6ik/Apache-Kafka-Consumer-Rebalance
Apache Kafka - Consumer Rebalance
Consumer는 메시지를 가져오기 위해서 Partition에 연속적으로 Poll한다.가져온 위치를 나타내는 offset 정보를 \_\_consumer_offsets Topic에 저장하여 관리한다.동일한 group.id로 구성된 모든 Consumer들은 하나
velog.io
https://magpienote.tistory.com/254
[Kafka 원리]Kafka Consumer 동작 원리 이해하기 (Consumer group, rebalancing, commit_offset, option, fetch 튜닝, messa
목차 consumer란? consumer offset Consumer는 어떤 메시지를 읽을 수 있을까? consumer group Consumer 메세지 읽기 옵션 Consumer Rebalance Consumer Group간 Rebalancing 옵션 그러면 언제 언제 Rebalancing 될까? Consumer Message O
magpienote.tistory.com
https://jyeonth.tistory.com/30
Apache Kafka 기본 개념 (Partition / Consumer / Consumer Group/ Offset Management)
Kafka는 가장 널리 쓰이는 메세지 큐 솔루션 중 하나이다. 다른 메세지 큐와 마찬가지로, Producer가 메세지를 publish하면 Consumer가 큐를 susbscribe하며 메세지를 가져가게 된다. 다만, 이 사이에 Topic / P
jyeonth.tistory.com
[Apache Kafka] 카프카란 무엇인가?
카프카, 데이터 플랫폼의 최강자 책을 공부하며 쓴 정리 글 입니다.카프카(Kafka)는 파이프라인, 스트리밍 분석, 데이터 통합 및 미션 크리티컬 애플리케이션을 위해 설계된 고성능 분산 이벤트
velog.io