본문 바로가기
실전 프로젝트/프로젝트 과정

실전 프로젝트 9 - 카프카 코어

by 구너드 2023. 8. 11.

카프카는 대용량 실시간 데이터 스트림을 처리하고 관리하기 위한 오픈 소스 메시징 시스템.
아파치 소프트웨어 재단에서 개발되었으며, 대량의 데이터를 안정적으로 처리하고 여러 시스템 간에 데이터를 신속하게 전달하는 데 주로 사용된다.


Broker
카프카 시스템은 여러 대의 브로커로 구성된다. 브로커는 데이터 메시지를 저장하고 처리하는 서버로, 각 브로커는 독립적으로 동작하며, 여러 개의 브로커가 하나의 클러스터를 형성한다.

Topic
토픽은 데이터 스트림의 주제를 나타낸다. 데이터는 토픽으로 분류되어 브로커에 저장되며, 다양한 Consumer가 해당 토픽의 데이터를 구독할 수 있다.

Producer
프로듀서는 데이터를 생성하고 토픽에 전송하는 역할을 한다. 예를 들어, 로그 메시지를 생성하거나 이벤트 데이터를 카프카 토픽으로 보낼 수 있다.

Consumer
컨슈머는 토픽에서 데이터를 소비하는 역할을 한다. 여러 개의 컨슈머가 하나의 토픽에서 데이터를 읽을 수 있으며, 데이터의 실시간 처리나 분석을 수행할 수 있다.

Partition
토픽은 하나 이상의 파티션으로 나뉜다. 파티션은 데이터를 여러 부분으로 분할하여 저장하고 처리하는 방법이다. 각 파티션은 별도의 브로커에서 관리된다.


라운드로빈과 스티키파티셔닝

 
라운드 로빈 파티셔닝
라운드 로빈 파티셔닝에서 메시지는 순환 방식으로 사용 가능한 파티션에 고르게 분산된다. 각각의 새 메시지는 첫 번째 파티션에서 시작하여 차례로 각 파티션을 통해 이동하면서 순차적으로 사용 가능한 다음 파티션에 할당된다. 이 접근 방식은 파티션 간에 균등한 메시지 배포를 보장하며 데이터 정렬 또는 메시지 그룹화에 대한 특정 요구 사항이 없을 때 유용할 수 있다.

스티키 파티셔닝

고정 또는 키 기반 파티셔닝에는 메시지에 있는 특정 키를 기반으로 메시지를 파티션에 할당하는 작업이 포함된다. 이 키는 일반적으로 발신자 또는 생산자가 결정한다. 동일한 키를 가진 메시지는 항상 동일한 파티션으로 전달된다. 이 방법은 동일한 키와 관련된 메시지가 순서대로 처리되도록 하고 특정 키에 대한 데이터 일관성을 보장한다. 이것은 특정 사용자와 관련된 모든 메시지가 동일한 파티션에 있는지 확인하는 것과 같이 관련 이벤트의 순서를 유지하는 것이 중요한 경우에 특히 유용할 수 있다.


차이점


메시지 배포
라운드 로빈: 메시지는 내용이나 관계를 고려하지 않고 파티션 전체에 고르게 분산.
스티키 파티셔닝: 동일한 키를 가진 메시지는 동일한 파티션으로 보내져 특정 키에 대한 데이터 일관성과 순서를 유지한다.

데이터 정렬
라운드 로빈: 순서가 중요한 경우 메시지가 원래 순서를 유지하지 못할 수 있다.
스티키 파티셔닝: 동일한 키를 가진 메시지를 순서대로 처리하여 데이터 일관성을 보장한다.

사용 사례
라운드 로빈: 데이터 관계나 순서에 관계없이 파티션 간에 로드를 고르게 분산시키려는 경우에 사용된다.
스티키 파티셔닝: 사용자 이벤트 또는 관련 트랜잭션과 같이 특정 키와 관련된 메시지의 순서 및 그룹화가 중요할 때 사용된다.

복잡성
라운드 로빈: 키 기반 라우팅이 필요하지 않으므로 구현이 더 간단하다.
스티키 파티셔닝: 키 기반 라우팅을 포함하므로 메시지 생성 중에 보다 신중한 고려가 필요하다.

요약하자면, 라운드 로빈 파티셔닝은 파티션 전체에 로드를 고르게 분산하는 데 중점을 두는 반면 스티키 파티셔닝은 동일한 키를 사용하여 데이터 일관성과 메시지 순서를 보장한다. 이러한 방법 중에서 선택하는 것은 데이터 순서 지정, 관련 이벤트 처리 및 균형 고려 사항과 같은 사용 사례의 특정 요구 사항에 따라 달라질 수 있다.


컨슈머 그룹과 컨슈머 - 리밸런싱

 
Consumer Group
카프카에서 컨슈머 그룹은 하나 이상의 컨슈머로 구성된 논리적 그룹을 의미한다. 하나의 토픽에 있는 메시지를 여러 컨슈머 그룹이 동시에 처리할 수 있도록 해준다. 이를 통해 데이터 처리의 확장성을 높이고, 여러 컨슈머가 동시에 작업하며 빠르게 데이터를 소비할 수 있게 된다. 각 컨슈머 그룹 내의 컨슈머들은 특정 토픽의 파티션을 공유하여 데이터를 소비한다. 각 파티션은 오직 한 컨슈머 그룹 내의 하나의 컨슈머에 의해 소비된다. 그리고 각 컨슈머는 파티션 내의 메시지를 순차적으로 처리한다.

Rebalancing
리밸런싱은 카프카 컨슈머 그룹의 구성원이 변경되거나 토픽의 파티션 수가 변할 때 발생하는 프로세스를 의미한다. 리밸런싱이 필요한 상황에서는 기존의 컨슈머 할당을 재조정하여 파티션을 새로운 컨슈머에게 분배하거나, 컨슈머 그룹의 멤버십이 변경될 때 기존 할당을 조정하는 등의 작업이 이루어진다.
 
1. 새로운 컨슈머가 그룹에 추가되거나, 기존의 컨슈머가 나가거나, 토픽의 파티션 수가 변경될 때 리밸런싱이 시작된다.
리밸런싱 시작 시, 그룹 내의 모든 컨슈머는 현재 할당된 파티션 정보와 관련된 조정을 위해 브로커와 조정 정보를 교환한다.
2. 각 컨슈머는 새로운 할당을 받거나 이전 할당을 포기하게 된다.
3. 파티션 할당이 완료되면 각 컨슈머는 새로운 파티션을 소비하기 시작한다.

리밸런싱은 데이터를 효율적으로 분배하고 각 컨슈머가 고르게 작업하도록 하는 중요한 메커니즘이다. 그러나 잘못된 구성이나 부정확한 파티션 할당이 리밸런싱 문제를 초래할 수 있으므로, 컨슈머 그룹의 구성 및 토픽 파티션의 변화에 대한 신중한 관리가 필요하다.


    public static void main(String[] args) {

        String topicName = "simple-topic";

        //KafkaProducer Object Config setting
        //key = null, value = "hello world"

        Properties props = new Properties();

        //bootstrap.servers, key.serializer.class, value.serializer.class
        //props.setProperty("bootstrap.servers", "192.168.56.101:9092");
        props.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.56.101:9092");
        props.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        props.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());

        //KafkaProducer create object
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(props);

        //ProducerRecord create object
        ProducerRecord<String, String> producerRecord = new ProducerRecord<>(topicName, null, "hello world2");

        //KafkaProducer send message
        kafkaProducer.send(producerRecord);

        kafkaProducer.flush();
        kafkaProducer.close();
    }

Zookeeper
 
분산 시스템에서 구성 및 동기화를 관리하기 위해 사용되는 분산 조정 서비스. 이를 통해 분산 시스템에서 고가용성, 신뢰성 및 일관성을 보장한다.
 
Z노드 - 데이터를 저장할 수 있는 메모리 내 노드로 구성,상태, 메타데이터와 같은 정보를 저장할 수 있다. 주키퍼노드는 기본 데이터 저장 단위라고 할 수 있으며 파일 시스템과 유사하게 계층 구조로 구성된다. 각 노드는 이름을 가질 수 있고 데이터가 포함될 수 있다. 트리와 유사하게 조직되며 각 노드는 자식 노드를 가짐으로써 이러한 계층 구조를 형성한다.
 
리더선출 - 클라이언트의 요청을 하나의 노드가 리더 역할로 처리하도록 보장하기 위해 브로커들의 리더를 선출한다.
 
카프카는 주로 브로커의 메타데이터와 리더선출을 관리하기 위해 주키퍼를 사용하며 카프카 설정 시 주키퍼에 토픽, 파티션, 레플리케이션, 컨슈머 오프셋과 같은 데이터들이 저장된다. 이러한 정보는 카프카 브로커와 클라이언트가 데이터가 어떻게 분산되며 어떤 브로커가 어떤 파티션을 메인으로 담당하는지 알 수 있다.


Broker
 
아파치 카프카 클러스터의 핵심 구성 요소 중 하나로 데이터를 저장하고 관리하며 프로듀서 및 컨슈머 간의 효율적인 통신을 중재하는 역할을 한다. 
 
브로커는 토픽에 속하는 데이터를 파티션 단위로 저장하며 각 파티션은 브로커에게 저장 공간을 제공, 메세지 순서를 보장한다. 토픽 내에서 데이터를 파티션으로 분할하고 이로인해 데이터를 분산시킴으로써 데이터를 병렬처리하기 때문에 확장성에 용이하다. 
 
프로듀서는 브로커에게 데이터를 전송하고 컨슈머는 브로커에게서 데이터를 가져온다. 브로커는 프로듀서의 데이터를 받아 리더 파티션에 저장하며 컨슈머에게 데이터를 제공한다고 할 수 있다


Producer 
 
데이터를 생성하고 카프카 클러스터의 특정 토픽으로 전송하는 역할. 이러한 전송되는 데이터를 레코드라고 부른다. 
 
파티셔닝 - 카프카는 토픽을 파티션으로 분할하는데 파티션은 메세지를 저장하기 위한 논리적인 공간이며 메세지의 순서를 보장하고 데이터를 병렬로 처리하기 위해 사용된다. 프로듀서가 레코드를 전송할 때, 선택한 토픽 및 파티션에 따라 레코드가 해당 파티션으로 전송되며. 이때 생성한 데이터는 직렬화된 형태이다.
 
메타데이터 - 카프카 클러스터와의 통신을 위해 브로커 메타데이터를 유지한다. 이 메타데이터는 각 토픽의 파티션 및 리더 브로커의 정보를 포함하며 올바른 위치로 레코드를 전송하는 데 사용된다.
 
배치 전송 - 프로듀서는 레코드를 배치로 그룹화하여 전송할 수 있다. 이를 통해 네트워크의 오버헤드를 줄이고 성능을 향상시킬 수 있다. 이러한 배치 전송은 파티션 할당 전략에 따라 특정 파티션으로 할당된다.


Consumer
 
데이터를 가져와서 처리하는 역할. 특정 토픽의 파티션에서 데이터를 읽고 이를 활용한다.
 
컨슈머는 읽은 데이터의 위치를 나타내는 오프셋을 관리하여 어디까지 데이터를 읽었는지에 대한 단서를 제공한다. 또한 같은 그룹 내의 컨슈머 중 하나가 에러가 발생하여 작동하지 않게 되면, 리밸런싱을 통해서 파티션을 재할당된다. 그룹은 여러 컨슈머를 묶은 것으로 이를 통해 동일한 토픽의 데이터를 각 파티션으로 나누어 병렬로 데이터를 읽을 수 있다.