Kafka 시스템 구조 알아보기

망7H·2021년 4월 15일
10

Kafka를 공부하다 보면 여러 용어들을 볼 수 있습니다. 어딘지 모르게 익숙한 용어인 Cluster 부터 생소한 ZookeeperTopic 같은 용어들이 있습니다.

실제 데이터 처리를 할 때는 Topic, Partition, Record와 같은 용어들을 많이 볼 수 있습니다. 데이터 처리와 관련된 용어와 주요 옵션들은 차후 포스팅에서 직접 실습을 진행하며 정리해보도록 하고, 이번에는 시스템 구조와 몇가지 중요한 특징들을 정리해볼까 합니다.

1. Topic & Partition

1) Topic

토픽은 카프카 클러스터의 브로커에서 데이터를 관리할 때 기준이 되는 개념입니다.
또는 어떤 주제의 데이터를 보관할지를 정하는 '주제'라고 생각해도 됩니다.
토픽은 2종류의 파티션인 반드시 존재하는 리더 파티션(Leader Partition)과 존재할 수도 있는 팔로워 파티션(Follower Partition)으로 구성될 수 있습니다.
여기서, '구성될 수 있다'는 말은 이 챕터의 '4) Replication Factor'에서 설명하겠습니다.

2) Leader Partition

파티션은 프로듀서(Producer)로부터 전달된 데이터를 보관하는 역할을 합니다.
그 중 리더 파티션은 프로듀서 또는 컨슈머와 직접 통신하는 파티션입니다.
리더 파티션은 프로듀서/컨슈머와 직접 통신함으로써 읽기, 쓰기 연산을 담당하게 됩니다.

3) Follower Partition

팔로워 파티션(Follower Partition)도 파티션이므로 데이터를 보관하는 역할을 합니다.
다만, 프로듀서로부터 리더 파티션으로 전달된 데이터를 복제(replication)하여 복제된 데이터를 저장합니다.
팔로워 파티션은 리더 파티션의 데이터를 복사하여 보관하는 역할을 하고 있지만,
리더 파티션이 속해있는 브로커에 장애가 발생한다면, 팔로워 파티션에서 리더 파티션의 지위를 가지게 될 수도 있습니다.

4) Replication Factor

  • 파티션의 복제 계수(replication factor)가 1인 경우 (= 복제 없음)
    복제 계수가 0이므로
    브로커 A의 파티션의 데이터를 복제해서 가지고 있을 브로커 B의 파티션이 없습니다.
    즉, 브로커 A에 리더 파티션만 존재하게 됩니다.
    브로커 A의 해당 토픽의 파티션이 총 3개였다면, 3개 모두 리더 파티션이 되는 것입니다.
  • 파티션의 복제 계수(replication factor)가 3인 경우 (= 복제 2개)
    복제 계수가 3이므로
    브로커 A의 파티션의 데이터를 복제해서 가지고 있을 브로커 B, C의 파티션이 존재합니다.
    이때, 브로커 A의 파티션이 3개였다면 A와 B, C는 각각 하나씩의 리더 파티션과 두개씩의 팔로워 파티션을 가지고 있게 됩니다.

2. Broker

브로커(Broker)는 카프카 서버라고도 불립니다.
브로커 내부에 여러 토픽들이 생성될 수 있고 이러한 토픽들에 의해 생성된 파티션들이 보관하는 데이터에 대해 분산 저장을 해주거나 장애 발생 시, 안전하게 데이터를 사용할 수 있도록 도와주는 역할을 합니다.

1) Controller

컨트롤러(Controller)는 클러스터의 여러 브로커 중 하나의 브로커가 컨트롤러의 역할을 하게 됩니다.
컨트롤러는 클러스터 내의 브로커가 장애 발생으로 사용할 수 없는 경우,
장애가 발생한 브로커의 토픽에 있는 리더 파티션을 같은 클러스터 내의 정상 동작하는 다른 브로커에게 토픽의 리더 파티션 지위를 재분배하는 역할을 합니다.

이때, 컨트롤러의 역할을 하는 브로커에 장애가 발생하는 경우에는 다른 브로커가 컨트롤러의 역할을 한다고 합니다.

2) Coordinator

코디네이터(Coordinator)는 클러스터의 여러 브로커 중 하나의 브로커가 코디네이터의 역할을 하게 됩니다.
코디네이터는 컨슈머 그룹의 상태를 체크하여 컨슈머 그룹 내의 컨슈머가 장애가 발생하여 매칭된 파티션의 데이터를 컨슘(consume)할 수 없는 경우,
장애가 발생한 컨슈머에게 매칭된 파티션을 정상 동작하는 다른 컨슈머에게 매칭하여 줍니다.

이때, 파티션을 컨슈머에게 재할당하는 과정을 리밸런스(Rebalance)라고 합니다.

3. Cluster

클러스터(Cluster)는 브로커(카프카 서버)로 이루어진 집합체를 말합니다.

4. Zookeeper

주키퍼(Zookeeper)는 카프카의 분산 처리 시스템의 서버들에 관한 메타데이터(환경 설정 등)를 통합 관리하는 시스템입니다.
클러스터를 구성하는 브로커들끼리 공유되는 데이터를 유지하거나 특별한 조율을 하기 위해 사용됩니다.

1) Zookeeper

  • 설정관리 (Configuration Management)
    클러스터의 설정 정보를 최신으로 유지하기 위한 시스템으로 사용.
  • 클러스터 관리 (Cluster Management)
    클러스터의 서버(브로커)가 추가되거나 제외될 때 그 정보를 클러스터 안 서버(브로커)들이 공유하는데 사용됩니다.

(※ 이것 이외에도 주키퍼의 사용용도는 더 있으니 구글링 또는 책을 찾아 읽는 것을 추천합니다.)

2) Zookeeper Ensemble

주키퍼의 클러스터를 주키퍼 앙상블(Zookeeper Ensemble)이라 부릅니다.

5. Producer & Partitioner

프로듀서(Producer)는 메시지를 생산(produce)해서 브로커의 토픽으로 메시지를 보내는 역할을 하는 애플리케이션이나 서버 모두를 프로듀서라고 부릅니다.
프로듀서는 데이터를 전송할 때 리더 파티션을 가지고 있는 카프카 브로커와 직접 통신합니다.

1) Partitioner

파티셔너(Partitioner)는 프로듀서 애플리케이션 내에서 생성된 메시지를 카프카에 보낼 때, 이 메시지가 토픽의 어떤 파티션(Partition)에 전달될 지를 정하는 역할을 합니다.
여기서 중요한 것은 파티셔너는 파티션이 있는 곳에서 동작하는 것이 아닌 프로듀서 애플리케이션 내에서 동작한다는 것입니다.
프로듀서 API를 사용하는 경우, 2개의 파티셔너(RoundRobinPartitioner, UniformStickyPartitioner)를 제공합니다.
두 파티셔너는 둘 다 메시지 key가 있을 때는 메시지 key의 hash값과 파티션을 매칭하여 데이터를 전송한다는 점에서 공통점이 있습니다.
차이점으로는, 메시지의 key가 없을 때는 파티션에 메시지를 분배하는 로직에 차이가 있습니다.

  • RoundRobinPartitioner
    카프카 클라이언트 라이브러리 2.4.0 버전에서 파티셔너를 지정하지 않은 경우의 기본 파티셔너(Default Partitioner)입니다.
    메시지가 발생하는 대로 파티션을 순회하면서 전송하기 때문에 묶이는 빈도가 적습니다.
    이는 여러번 브로커와의 통신이 발생하므로 높은 리소스 사용률을 가지는 단점이 있었습니다.

  • UniformStickyPartitioner
    카프카 클라이언트 라이브러리 2.5.0 버전에서 파티셔너를 지정하지 않은 경우의 기본 파티셔너(Default Partitioner)입니다.
    RoundRobinPartitioner에서 발생한 단점인 브로커와의 잦은 통신을 해결하기 위해 UniformStickyPartitioner에서는 데이터가 배치로 모두 묶일 때 까지 기다린 뒤,
    묶여진 데이터 덩어리는 모두 동일한 파티션에 전송함으로써 높은 처리량과 낮은 리소스 사용률을 가지게 되었습니다.

6. Consumer

컨슈머(Consumer)는 토픽의 파티션에 저장되어 있는 메시지를 소비(consume)하는 역할을 하는 애플리케이션이나 서버 모두를 컨슈머라 부릅니다.
컨슈머는 데이터를 요청할 때 리더 파티션을 가지고 있는 카프카 브로커와 통신합니다.
토픽의 파티션으로부터 데이터를 가져가기 위해 컨슈머를 운영하는 방법은 2가지로
토픽의 특정 파티션만 구독하는 컨슈머를 운영하는 것과
1개 이상의 컨슈머로 이루어진 컨슈머 그룹을 운영하는 것이다.

1) Consumer Group

토픽의 파티션은 동일 컨슈머 그룹(Consumer Group) 내의 컨슈머와 1:1 ~ n:1로 매칭될 수 있다.

  • Partition 3개 (P1, P2, P3)와 Consumer Group A의 Consumer 3개 (C1, C2, C3)
    3개의 파티션은 각각 하나의 컨슈머에 할당되게 된다.
  • Partition 2개 (P1, P2)와 Consumer Group B의 Consumer 3개 (C1, C2, C3)
    2개의 파티션은 각각 하나의 컨슈머에 할당되면서 Consumer Group B에 있는 하나의 컨슈머는 어떤 파티션도 할당받지 못하는 상태가 된다.
  • Partition 4개 (P1, P2, P3, P4)와 Consumer Group C의 Consumer 3개 (C1, C2, C3)
    4개의 파티션은 각각 컨슈머에 할당되는데,
    이때 2개의 컨슈머는 각각 1개의 파티션을 할당받으며
    남은 하나의 컨슈머는 2개의 파티션을 처리하게 된다.



이상으로 카프카 시스템 구조에 대해 아주 간략히 알아보았습니다.
구글링 해보시면 알겠지만, 이번 포스팅에서는 실제 사용시의 디테일한 설정이나 주의사항에 대한 것은 과감히 빼두었습니다.
SpringBoot & Gradle을 사용하여 메시지를 생산하는 Producer로써 또는 메시지를 소비하는 Consumer로써 사용해보는 포스팅도 지속적으로 올릴 계획입니다.

해당 글 작성에 참고한 링크

[도서] 아파치 카프카 애플리케이션 프로그래밍 with 자바
https://kong-dahye.tistory.com/13
https://www.neya.kr/159
https://engkimbs.tistory.com/691
https://blog.voidmainvoid.net/360
https://programacion.tistory.com/156

profile
망한 개발자의 개발 기록입니다. 저를 타산지석으로 삼으시고 공부하세요.

1개의 댓글

comment-user-thumbnail
2022년 5월 19일

안녕하세요 글 잘보았습니다. 카프카에 대해서 한가지 여쭤볼게 있는데 어느 글에 달아야될지 몰라서 여기에 답니다 ㅠㅠ

mysql db를 master-slave(각각 다른 서버)로 구성하고 있고 부트 어플리케이션에서 master만 바라보고 있을때 만약에 master 서버를 이용하지 못한다고 가정하면 부트 어플리케이션의 application.yml에서 slave 서버로 변경

이런상황인 경우에 카프카를 쓰면 application.yml에서 slave 서버로 db정보를 변경하지 않고도 장애가 발생하지 않을까요?

답글 달기