kmg28801 / kafka-study

1 stars 0 forks source link

Chapter 5. 카프카 컨슈머 #5

Closed kmg28801 closed 1 year ago

taewoo-kim123 commented 1 year ago

카프카 컨슈머

import java.io.IOException;

import org.springframework.context.annotation.Configuration; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.kafka.support.KafkaHeaders; import org.springframework.messaging.handler.annotation.Header;

@Configuration public class KafkaConsumer {

//topics = ["a","b"] 식으로 가능
@KafkaListener(topics = "taewoo-topic", groupId = "taewoo-consumer-group")
public void consume(String message, @Header(KafkaHeaders.RECEIVED_PARTITION) Integer partition, @Header(KafkaHeaders.OFFSET) Integer offset) throws IOException {
        System.out.printf("Consume message : %s partition : %d, offset : %d\n", message, partition, offset);
}

}

  - @KafkaListener 어노테이션을 이용하였으며, [해당링크](https://victorydntmd.tistory.com/348)를 참조하였습니다.
책에서는 `KafkaConsumer`와 `ConsumerRecords` 를 이용하였는데, 이 방식이 더 깔끔하다고 생각하였습니다.
`partition`과 `offset` 등은 매개변수로 넣어주면 값을 얻을 수 있습니다.
  - `topics`에 배열로 넣으면 여러개의 토픽을 처리할 수 있음
![스크린샷 2023-05-06 오후 6 38 28](https://user-images.githubusercontent.com/122066644/236622922-f68e2955-be23-4b7a-b7e0-06b3da702022.png)

## 5.4 파티션과 메세지 순서
  - 기존에 사용하던 토픽과 다른 추가의 토픽을 하나 더 생성(파티션 수는 반드시 동일한 파티션 생성, 저는 Kafka UI 로 파티션 3개짜리 토픽 1개 생성)
  ``` sh
  /usr/local/kafka/bin/kafka-topics.sh --zookeeper peter-zk001:2181,peter-zk002:2181,peter-zk003:2181/peter-kafka --topic peter-01 --partitions 3 --replication-factor 1 --create

스크린샷 2023-05-06 오후 6 50 29

5.4.1 파티션 3개로 구성한 peter-01토픽과 메세지 순서

  1. 방금 생성한 토픽으로 메세지를 전송
     /usr/local/kafka/bin/kafka-console-producer.sh --broker-list peter-kafka001:9092,peter-kafka002:9092,peter-kafka003:9092 --topic peter-01
  2. 메시지 순서 확인
     /usr/local/kafka/bin/kafka-console-consumer.sh --broker-list peter-kafka001:9092,peter-kafka002:9092,peter-kafka003:9092 --topic peter-01 --from-beginning
  3. 다시 1,2,3,4,5 순서로 메세지 전송
  4. 다시 확인 오히려 알파벳보다 먼저 나오는 경우도 있는데, 토픽은 파티션이 3개, 각 파티션별로 메세지가 어떻게 저장되어있는지 확인하면

     /usr/local/kafka/bin/kafka-console-consumer.sh --broker-list peter-kafka001:9092,peter-kafka002:9092,peter-kafka003:9092 --topic peter-01 --partition 0 --from-beginning
    • 이건 메세지들이 하나의 파티션에만 순서대로 저장되는 것이 아니라, 각각의 파티션에 메세지가 저장되어서 나타나는 현상.

    • 컨슈머는 `peter-01토픽에서 메세지를 가져올때 프로듀서가 어떤 순서로 메세지를 보냈는지 알 수 없음. (오직 파티션의 오프셋 기준으로만)

      스크린샷 2023-05-06 오후 9 06 12
    • 책 기준으로 가져온 순서를 보면 a,d,b,e,c 순서로 가져왔음.

    • 출력 내용은 파티션의 오프셋 순서대로 메세지를 가져왔음. 오프셋은 절대 역전되지 않았음

    • 카프카에서 토픽의 파티션이 여러개인 경우 메세지의 순서를 보장할 수 없다.

      파티션 내에서의 메세지 순서는 프로듀서가 생성한 수서와 동일하지만, 파티션과 파티션 사이의 순서는 보장 X

5.4.2 파티션 1개로 구성된 peter-02토픽과 메세지 순서

  1. 파티션1개짜리 토픽 생성

    /usr/local/kafka/bin/kafka-topics.sh --zookeeper peter-zk001:2181,peter-zk002:2181,peter-zk003:2181/peter-kafka --topic peter-02 --partitions 1 --replication-factor 1 --create

    스크린샷 2023-05-06 오후 7 27 06

  2. a~e 까지 메세지 전송

     /usr/local/kafka/bin/kafka-console-producer.sh --broker-list peter-kafka001:9092,peter-kafka002:9092,peter-kafka003:9092 --topic peter-02
  3. 메세지 정상 순서 확인

    /usr/local/kafka/bin/kafka-console-consumer.sh --broker-list peter-kafka001:9092,peter-kafka002:9092,peter-kafka003:9092 --topic peter-02 --from-beginning
    1. 1~5까지 다시 전송
    2. 이 순서 역시 보낸순서와 동일한것을 확인
      • 파티션 1개일 경우 오프셋의 순서가 절대 역전되지 않기 때문에 컨슈머가 메세지를 가져갈때 프로듀서에서 생성한 메세지 순서와 동일
        만일 메세지의 순서를 보장해야하는 경우 파티션의 숫자를 1로 설정. 단 분산처리를 할 수 없고, 하나의 컨슈머에서만 처리해야해서 처리량이 높지 않다.

        5.5 컨슈머 그룹

      • 컨슈머 그룹은 카프카 토픽에서 메세지를 읽어오는 역할
      • 하나의 토픽에 여러 컨슈머 그룹이 동시에 접속 가능. (기존의 다른 메시징큐 솔루션에서 컨슈머가 메세지를 가져가면 큐에서 삭제되어 다른 컨슈머가 가져갈 수 없었는데, 하나의 데이터에 다양한 용도로 사용하는 요구가 많아졌기 때문에 이 방법을 사용)
    • 만약 프로듀서의 메세지 전송 속도가 컨슈머의 처리속도보다 빨라지게 된다면? ex) 프로듀싱 속도 : 1 , 컨슈밍 속도 : 3일 경우 -> 컨슈머를 확장해야함 단순하게 컨슈머만 확장하면 기존 컨슈머의 오프셋 정보와 새로 추가된 컨슈머의 오프셋 정보가 섞여서 메세지들이 뒤죽박죽.
    • 따라서 동일한 토픽에 대해 여러 컨슈머가 메세지를 가져갈 수 있도록 컨슈머 그룹이라는 기능을 제공. (컨슈머 확장에 용이, 빠른 장애 대처 가능)
    • 컨슈머 그룹 안에서 컨슈머들은 토픽의 파티션에 대한 소유권을 공유함.

5.5.1 컨슈머 그룹, 리밸런스

스크린샷 2023-05-06 오후 9 06 36

5.5.2 컨슈머뿐만 아닌 파티션도 같이 확장

5.5.3 컨슈머 다운

5.5.4 하나의 토픽 여러개의 컨슈머 그룹

5.6 커밋과 오프셋

5.6.1 자동 커밋

스크린샷 2023-05-06 오후 9 11 34

5.6.2 수동 커밋

5.6.3 특정 파티션 할당

5.6.4 특정 오프셋부터 메세지 가져오기