잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).

여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.

감사합니다. -현록

후원해주실 분은 여기로→

현록의 기록저장소

Kafka 기본 개념 및 용어 본문

Study/Kafka

Kafka 기본 개념 및 용어

현록 2023. 1. 18. 10:38

Kafka의 정말 기본 개념

Kafka는 데이터 처리를 위한 플랫폼이다.

'느슨한 결합'을 목표로 한다.

기존의 데이터 처리 플랫폼은 애플리케이션과 강하게 결합되어 있어,

같은 데이터를 처리하려고 해도 애플리케이션마다 별도의 창구가 필요하거나,

그마저도 바로 되지 않아 더 길고 복잡한 경로나 새로운 저장소가 추가되거나 하여 시스템을 복잡하게 만들었다.

출처: https://www.confluent.io/blog/event-streaming-platform-1/
출처: https://www.confluent.io/blog/event-streaming-platform-2/

Kafka는 느슨하게 결합되어 있기에,

애플리케이션에서 통일된 형태로 바로 데이터를 생산/소비하고,

이 데이터를 연결된 다른 모든 애플리케이션에서 바로 사용할 수 있다.

출처: https://www.confluent.io/blog/event-streaming-platform-1/
출처: https://www.confluent.io/blog/event-streaming-platform-2/

 

 


Kafka는 이벤트 브로커 (※ 이 부분은 하나의 견해인지 잘 모르겠다. 나도 이 모두를 사용해본 것이 아니라...)

 

Redis, MQTT가 메시지 브로커라면,

Kafka, AWS Kinesis는 이벤트 브로커이다.

이벤트 브로커는 메시지 브로커의 역할도 수행할 수 있지만,

반대로 메시지 브로커가 이벤트 브로커의 역할을 수행할 순 없다.

메시지 브로커는 당장의 메시지 전달에 초점을 맞추며, 지난 시점의 메시지는 지난 메시지일 뿐이다.

이걸 보존하지도 않는다. 필요하면 연결된 애플리케이션에서 보존할 뿐, 브로커가 보존을 수행하진 않는다.

이벤트 브로커는 당장의 메시지 전달 뿐 아니라, 지난 메시지 역시 그로 인한 이벤트 발생이든 재처리든 할 수 있다.

지난 메시지 역시 브로커가 보존하고 있다.

 

 


ZooKeeper는 또 뭐야??

apache Kafka는 apache ZooKeeper와 연동하여 사용한다.

이 의존성을 향후에는 없애겠다고 했으나, 현재에는 그렇다.

(Kafka 3.3에서는 ZooKeeper 없이 Kafka 독자적으로 가능하도록 KRaft를 옵션으로 탑재하고 있으며,

향후 4에서는 제거할 계획이라고 한다.)

 

ZooKeeper는 분산 애플리케이션을 관리하는 코디네이터이다.

Kafka만을 위한 것이 아니라 그보다 먼저 존재해왔던 프로젝트로,

빅데이터 생태계에 동물형 심볼을 갖는 애플리케이션들이 많고, 이들의 사육사(ZooKeeper)격으로 만들어졌다.

분산 시스템에서 부분 실패 등을 안전하게 처리하기 위한 도구이다.

 

ZooKeeper는 Kafka 브로커들(서버들)의 메타 데이터를 관리한다.

Kafka는 멀티 브로커가 가능하며, 브로커 ID, 컨트롤러 ID 등의 데이터를 ZooKeeper가 관리해준다.

메시지의 저장은 Kafka 내부에 적재된다.

ZooKeeper는 Kafka 서버들의 정보를 관리하는 것이고, 둘을 혼동하면 곤란하다.

 

 


그래도 ZooKeeper에 대해 간단히..

출처: https://hadooptechblog.wordpress.com/2015/12/29/introduction-to-apache-zookeeper/

ZooKeeper 역시 단일로 실행되기보다는 스스로도 멀티 클러스터 환경으로 구성된다.

이 여러 클러스터들이 앙상블(Ensemble)을 이룬다.

설정에서 (묶인 클러스터들의 총 갯수) / 2 + 1 이 서로 통신이 되고 있어야 ZooKeeper를 이용할 수 있다.

분산 시스템에서 이러한 최소 필요 수를 쿼럼(Quorum)이라고 한다.

 

기본적으로 tcp/2181 로 다른 애플리케이션(ex. Kafka. 주키퍼 입장에선 클라이언트.)이 ZooKeeper를 이용하며,

tcp/2888 로 ZooKeeper의 클러스터들끼리 동기화를 한다.

tcp/3888 은 ZooKeeper의 클러스터들끼리의 leader/follower 선출에 사용한다.

 

ZooKeeper끼리는 설정으로 서로의 주소와 포트를 알고 있어야하지만,

ZooKeeper를 이용하는 애플리케이션들(ex. Kafka. 주키퍼 입장에선 클라이언트.)은 서로를 알 필요 없이

ZooKeeper가 분산된 애플리케이션들을 연결시켜주며,

애플리케이션은 설정에서 ZooKeeper 하나만 알아도 ZooKeeper들은 메타 데이터들을 스스로 동기화를 하는 점이 장점이다.

 

ZooKeeper와 애플리케이션이 같은 머신에서 돌 수 없는 것은 아니나,

ZooKeeper는 메모리에서 데이터들을 처리하고 있으므로,

머신의 메모리를 고려하거나 장애 분산 등을 고려하면 다른 머신에서 가동하는 것이 좋다.

 

 


Kafka 용어

 

※ Pub/Sub, Broker, Topic 등 메시지 브로커의 기본 공통 개념은 생략

 

※ 데이터의 저장: 데이터는 Kafka를 실행하는 머신의 설정한 디렉터리에 bytes 형태의 파일로 저장된다.

        그러므로 producer→Kafka 에는 직렬화, Kafka→consumer 에는 역직렬화가 수행된다.

 

ㆍSegment 파일: bytes들은 파일들(00000000000000000000.index, 00000000000000000000.log, 00000000000000000000.timeindex)로 저장된다.

        현재 사용되는 파일은 열려있는 상태이며, 설정한 시간 및 용량에 따라 파일을 닫고 새 파일을 열어 쓴다.

        닫힌 파일은 설정한 시간 및 용량에 따라 압축되거나 삭제된다.

 

ㆍController(컨트롤러): 멀티 브로커 환경에서, 브로커 1대는 컨트롤러 기능을 수행한다.

          컨트롤러는 각 브로커들에게 담당 파티션을 할당하며, 브로커들이 정상 동작하는지 모니터링 및 관리한다.

          누가 컨트롤러인지는 메타 데이터이므로, ZooKeeper에 저장된다.

 

ㆍOffset(오프셋): 토픽으로 들어온 메시지는 순서대로 오프셋이 매겨진다.

        컨슈머 그룹에서 메시지를 가져가더라도, 컨슈머마다 읽은 오프셋(컨슈머 오프셋)이 늘어날 뿐 데이터가 지워지진 않는다.

        다른 컨슈머가 사용할 수도 있고, 원하면 재사용도 가능하다.

        그러니 지우는 것이 아니라 데이터는 그대로이면서, 컨슈머마다 컨슈머 오프셋으로 어디까지 읽은지를 구분한다.

        데이터는 쌓인 용량이 설정한만큼의 용량이 되거나, 설정한만큼의 기간이 지나면 지운다.

 

ㆍPartition(파티션): 한 토픽은 여러 파티션으로 나뉠 수 있다.

         파티션의 수는 브로커의 수에 제한받지 않는다(하나의 브로커가 여러 파티션을 가질 수 있다. 섹션 맨 아래 무지개색 이미지 참고.).

         Producer의 Partitioner에 따라 레코드들이 분배되는데, 기본으로는 UniformStickyPartitioner를 사용한다.

         UniformStickyPartitioner는 레코드에 Key를 주어, Key-Value 쌍의 형태를 사용하면 Key로 Hash 계산을 하여 파티션에 분배하고,

         Key가 null이면 Round-Robbin으로 레코드들을 파티션들에 분배한다.

         파티션마다 오프셋이 매겨진다.

         토픽의 파티션은 언제든 늘릴 수 있지만, 줄일 수는 없다.

 

ㆍConsumer Group: 컨슈머 그룹은 한 토픽으로부터 데이터를 가져온다.

         다른 컨슈머 그룹이 동일한 토픽으로부터 데이터를 가져올 수 있다.

         컨슈머 오프셋은 컨슈머마다 계산되므로, 다른 그룹이 같은 토픽을 읽어도 서로 순서가 혼선될 일은 없다.

 

ㆍConsumer: 컨슈머는 자신이 속한 그룹이 가져올 토픽에 대하여, 그 토픽의 파티션으로부터 데이터를 가져온다.

      그룹 내의 컨슈머들의 수가 토픽의 파티션 수보다 적다면, 어느 컨슈머는 해당 토픽의 여러 파티션으로부터 데이터를 가져온다.

      그룹 내의 컨슈머들의 수가 토픽의 파티션 수와 일치한다면, 한 컨슈머가 해당 토픽의 한 파티션으로부터만 데이터를 가져온다.

      그룹 내의 컨슈머들의 수가 토픽의 파티션 수보다 많다면, 초과된 수의 컨슈머는 놀게 된다.

      그러므로 컨슈머 그룹 내의 컨슈머 숫자는 해당 토픽의 파티션 수 이하가 되도록 구성한다.

 

ㆍRebalance(리밸런스): 컨슈머 그룹 내부의 특정 컨슈머에 장애가 발생하면, 컨슈머들은 담당 파티션들을 다시 조정한다.

출처: https://ibm-cloud-architecture.github.io/refarch-eda/technology/kafka-consumers/

ㆍReplication(복제): 토픽의 파티션은 안전을 위해 다른 브로커들에게 복제되도록 할 수 있다.

         복제 수는 최대로는 브로커의 수만큼이 되도록 설정할 수 있다(그 넘어서는 브로커가 더 없으니 할 수 없는 것.. 바로 아래 이미지 참고.)

         브로커 하나가 한 토픽의 여러 파티션 원본을 가질 수는 있지만, 굳이 같은 파티션의 복제본을 여럿 들고있을 필요가 없다는 것을 생각하면 된다.

         leader 파티션은 Kafka 클라이언트(프로듀서, 컨슈머)와 데이터를 주고 받으며,

         follower 파티션은 leader 파티션으로부터 레코드를 지속 복제한다.

         만약 leader 파티션에 장애가 발생하면, 나머지 follower들끼리 새로 leader를 선출한다.

 

ㆍISR(In-Sync Replica): 특정 파티션의 leader, follower에서 레코드가 모두 복제되어 동기화(sync)가 맞는 상태.

           만약 ISR이 아닌 상태에서 장애가 발생했다면, unclean.leader.election.enable= 설정에 따라

           true면 sync 상관 없이 바로 follower들 중에 새로 leader를 선출하고,

           false면 leader가 살아날 때까지 대기한다. 즉, 그동안은 해당 파티션은 사용불가가 된다.

 

% kafka-topics.sh   --describe    --bootstrap-server kafka-01:9092,kafka-03:9092

Topic: mytest   TopicId: H0tGCsUcQDOFqD_-8C9bEQ PartitionCount: 7       ReplicationFactor: 1    Configs:

        Topic: mytest   Partition: 0    Leader: 1       Replicas: 1     Isr: 1

        Topic: mytest   Partition: 1    Leader: 0       Replicas: 0     Isr: 0

        Topic: mytest   Partition: 2    Leader: 2       Replicas: 2     Isr: 2

        Topic: mytest   Partition: 3    Leader: 1       Replicas: 1     Isr: 1

        Topic: mytest   Partition: 4    Leader: 0       Replicas: 0     Isr: 0

        Topic: mytest   Partition: 5    Leader: 2       Replicas: 2     Isr: 2

        Topic: mytest   Partition: 6    Leader: 1       Replicas: 1     Isr: 1

Topic: mytest3  TopicId: 7krfA2U1SjmmZKUWZFEW_w PartitionCount: 7       ReplicationFactor: 2    Configs:

        Topic: mytest3  Partition: 0    Leader: 2       Replicas: 2,1   Isr: 2,1

        Topic: mytest3  Partition: 1    Leader: 1       Replicas: 1,0   Isr: 1,0

        Topic: mytest3  Partition: 2    Leader: 0       Replicas: 0,2   Isr: 0,2

        Topic: mytest3  Partition: 3    Leader: 2       Replicas: 2,0   Isr: 2,0

        Topic: mytest3  Partition: 4    Leader: 1       Replicas: 1,2   Isr: 1,2

        Topic: mytest3  Partition: 5    Leader: 0       Replicas: 0,1   Isr: 0,1

        Topic: mytest3  Partition: 6    Leader: 2       Replicas: 2,1   Isr: 2,1

위 조회 중 mytest3 기준으로 작성한 이미지
각각 kafka 머신의 디렉터리 상태

 

 


간단한 설정 실습

 

https://github.com/BlackdeerY/docker-kafka-example

환경변수 등의 설정 없이

기본 openjdk 환경에 ZooKeeper, Kafka 쌩 파일에 설정 파일만으로 가동하고 테스트하는 예시를 두었다.

(Docker Compose 사용)

분산된 머신들과 사용하는 포트 및 데이터 저장 디렉터리, 사용 명령어 등에 대해 감을 잡고 나면,

좀 더 세밀한 설정으로 넘어가기 수월할 것.

 

 


Kafka 공식 문서

 

https://kafka.apache.org/documentation/

 

Apache Kafka

Apache Kafka: A Distributed Streaming Platform.

kafka.apache.org

 

 

'Study > Kafka' 카테고리의 다른 글

Kafka 설정  (0) 2023.01.25
Comments

잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).

여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.

감사합니다. -현록

후원해주실 분은 여기로→