Kafka 구성 요소

PEPPERMINT100·2024년 11월 6일
0

서론

이전 글을 통해서 메시지 큐가 무엇인지 어떤 종류가 있고 각각 특징이 뭔지 그리고 그중에서 카프카와 스프링 부트 앱을 연동하는 방법에 대해서 알아보았다.

여기에 더해서 카프카에 대해 조금 더 잘 이해하기 위해서 카프카를 이루는 요소에 대해서 알아본 내용을 정리해보려고 한다.

이전 글에 따른 도식을 먼저 살펴보자.

도식을 살펴보면 Producer, Consumer, Kafka cluster 그리고 그 안에 broker, Zookeeper가 보인다. 여기서 더 자세히 들어가면 브로커마다 토픽이 있고 토픽 내부에는 또 파티션이라는 개념이 존재한다.

조금 더 자세한 도식을 살펴보자.

자세히 보면 클러스터 내에 토픽과 파티션이 보일 것이다. 그리고 프로듀서와 다르게 컨슈머는 또 컨슈머 그룹이라는 것으로 엮여있는 것을 볼 수 있다. 간단히 카프카의 전체적인 구성도를 뜯어봤으니 이제 하나하나 살펴보도록 하자.

Zookeeper

카프카 아키텍쳐는 크게 Kafka Cluster(Broker들)와 Zookeeper로 나뉜다. 지금은 KRaft라는 것을 통해 카프카 단일로 기동이 가능하지만 오랫동안 같이 사용해왔던 Zookeeper도 간단히 알 필요가 있을 것 같다.

Zookeeper는 분산 어플리케이션의 데이터를 관리하는 시스템으로, 카프카 브로커를 관리하고 조정한다. Kafka의 브로커와 1:1로 구성되므로 브로커가 3개라면 Zookeeper도 3대를 기용한다.

Zookeeper는 주로 프로듀서와 컨슈머에 브로커의 신규 생성 여부, 브로커의 실패를 알리는데 사용되며 이 알림에 따라 프로듀서와 컨슈머는 어떻게 동작할지 결정하고 다른 브로커와의 작업을 조정한다.

Producer

메시지를 생성하여 카프카에 전달한다. 프로듀서는 전송시 ACK 설정을 통해 메시지가 성공적으로 전송되었는지 확인하고 필요시 재전송한다.

이 acks는 카프카에서 설정할 수 있는데, 0, 1, all(-1) 값을 설정할 수 있다.
0으로 설정하면 메시지를 파티션에 보내고 메시지를 받았는지 확인하지 않는다. 속도가 빠르지만 메시지가 손실될 가능성이 높다.
1로 설정하면 메시지를 파티션에 보내고 메시지를 리더 파티션으로부터 잘 받았는지 확인한다. 다른 팔로워 파티션에 잘 전돨 되었는지는 확인하지 않는다.
all(-1)로 설정하면 리더 파티션에 전달된 값이 팔로워 파티션에 정상적으로 전달되었는지 전부 확인하여 손실률이 적지만 속도가 느리다.

all(-1) 옵션에서는 min.insync.replicas 옵션을 지정해서 몇 개의 파티션까지 복제가 성공되어야 프로듀서에 ack를 성공이라고 알릴지 설정할 수 도 있다.

Consumer

카프카의 토픽으로부터 메시지를 소비하여 데이터를 처리한다. 특정 Consumer Group에 속할 수 있다. Consumer는 오프셋을 추적하여 마지막으로 소비된 메시지의 위치를 기억하고 실패 혹은 중단된 위치부터 다시 소비할 수 있다.

Topic

메시지를 분류하는 논리적인 단위로 프로듀서는 특정 토픽에 메시지를 전달하고 컨슈머는 특정 토픽에서 메시지를 받는다. 하나의 토픽은 여러개의 파티션으로 나누어져 있으며 이를 통해 병렬 처리를 한다. 토픽은 특정 기간 동안 메시지를 보관하고 있을 수 있다.

Offset

토픽 내의 각 파티션에 메시지의 고유 위치를 나타낸다.

Consumer Group

이전 글에서 스프링부트 앱에 Consumer를 등록할 때 Group Id를 지정해주었는데, 동일한 그룹 내에서는 하나의 파티션에 대해서 하나의 컨슈머만 메시지를 소비하게 된다. 이를 통해서 메시지가 중복으로 소비되는 것을 방지한다. 카프카의 컨슈머는 그룹단위로 오프셋을 조정한다. 

이 그룹이 필요한 이유는 Kafka의 특성 때문인데, RabbitMQ와 다르게 Kafka는 메시지가 소비되어도 그 메시지를 바로 삭제하지 않는다.

다른 그룹에서 소비될 수 있는 가능성을 열어두는 것이다. 특정 그룹이 어떤 메시지를 소비하고 그 곳에 오프셋을 지정해도 다른 그룹에서도 그 메시지를 사용할 수 있도록 하기 위해 그룹을 지정할 수 있다.

Partition

하나의 토픽은 1개 이상의 파티션이 존재하며 메시지를 저장하는 물리적인 파일을 의미한다. append-only로 새 메시지가 뒤에 추가되기만 하며 각 메시지의 저장 위치를 오프셋이라고 한다. (위에서 설명한 Offset)

만약 3대의 브로커가 있는 카프카에 6개의 파티션이 있는 토픽을 생성하면 각 브로커는 2개의 파티션을 맡게 도고 일부 파티션은 리더 파티션으로 데이터 읽기 쓰기 작업을 하게 되고 나머지 파티션은 팔로워 파티션으로 데이터를 복제 받아서 백업 역할을 하게 된다.

이 파티션안에는 Record라고 하는 메시지가 저장된다.

Record

레코드는 타임스탬프, 메시지키, 메시지 값, 오프셋으로 구성되어 있으며 프로듀서가 생성해서 브로커로 전송하고 이 레코드가 파티션에 저장된다. 이 메시지 값에 실제로 처리할 데이터가 들어 있다.

Controller

컨트롤러는 도식에서 보이진 않지만 여러개의 브로커중 한대가 컨트롤러의 역할을 하게 된다. 이 컨트롤러는 다른 브로커들의 상태를 체크하고 브로커가 삭제되는 경우 해당 브로커에 존재하는 리더 파티션을 적절히 재분배한다.

이미지 및 참조
https://blog.det.life/apache-kafka-overview-b04c4ab8ef49
https://lankydan.dev/intro-to-kafka-consumer-groups

profile
기억하기 위해 혹은 잊어버리기 위해 글을 씁니다.

0개의 댓글