ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kafka 개념] Kafka 토픽, 파티션 (1)
    Apache Kafka/개념 정리 2024. 2. 2. 09:28

     

    토픽과 파티션 그리고 레코드

    토픽은 카프카에서 데이터를 구분하기 위해 사용하는 단위이다.

    토픽은 1개 이상의 파티션을 소유하고 있으며

    파티션에는 프로듀서가 보낸 데이터들이 들어가 저장되는데, 이 데이터들을 '레코드(record)'라고 부른다.

     

     

    프로듀서가 전송한 레코드는 파티션에 저장된다.

     

     

    토픽

    카프카에는 다양한 데이터가 들어갈 수 있는데, 데이터가 들어가는 공간을 토픽이라고 부른다.

    카프카에서는 토픽을 여러 개 생성할 수 있다.

     

    또한 토픽은 이름을 가질 수 있는데, 무슨 데이터를 담는지 명확하게 명시하면

    추후 유지 보수 시 편리하게 관리할 수 있다.

     

    토픽은 데이터베이스의 테이블이나 파일 시스템의 폴더와 유사한 성질을 가지고 있는데,

    프로듀서가 토픽에 데이터를 넣게 되고 컨슈머는 데이터를 가져가게 된다.

    오른쪽 사진처럼, 토픽은 목적에 따라 click_log, send_sms, location_log(예시)와 같이 이름을 가질 수 있다.

     

     

     

    파티션

    토픽안에 1개 이상으로 존재하는 파티션은 자료구조에서 접하는 큐(queue)와 비슷한 구조라고 생각하면 쉽다.

    First-In-First-Out(FIFO) 구조와 같이 먼저 들어간 레코드는 컨슈머가 먼저 가져가게 된다.

    다만, 일반적인 자료구조로 사용되는 큐는 데이터를 가져가면(pop) 레코드를 삭제하지만,

    카프카에서는 삭제하지 않는다.

     

    파티션의 레코드는 컨슈머가 가져가는 것과 별개로 관리되며 이러한 특징 때문에 토픽의 레코드는

    다양한 목적을 가진 여러 컨슈머 그룹들이 토픽의 데이터를 여러 번 가져갈 수 있다.

     

     

     

     

    레코드

    레코드는 타임스탬프, 메시지 키, 메시지 값, 오프셋으로 구성되어 있다.

    프로듀서가 생성한 레코드가 브로커로 전송되면,

    브로커에 한번 적재된 레코드는 수정할 수 없고 로그 리텐션 기간 또는 용량에 따라서만 삭제된다.

     

    • 타임스탬프
      • 프로듀서에서 해당 레코드가 생성된 시점(CreateTime)의 유닉스 타임이 설정된다.
      • 다만, 프로듀서가 레코드를 생성할 때 임의의 타임스탬프 값을 설정할 수 있고, 토픽 설정에 따라 브로커에 적재된 시간(LogAppendTime)으로 설정될 수 있다는 점을 유의
    • 메시지 키
      • 메시지 값을 순서대로 처리하거나 메시지 값의 종류를 나타내기 위해 사용한다.
      • 메시지 키를 사용하면 프로듀서가 토픽에 레코드를 전송할 때, 메시지 키의 해시값을 토대로 파티션을 지정하게 된다. 즉, 동일한 메시지 키라면 동일 파티션에 들어가는 것이다.
      • 그러나 파티션 개수가 변경되면 메시지 키와 파티션 매칭이 달라지게 되므로 주의
      • 메시지 키를 선언하지 않으면 null로 설정된다. 메시지 키가 null로 설정된 레코드는 프로듀서 기본 설정 파티셔너에 따라서 파티션에 분배되어 적재된다.
    • 메시지 값
      • 실질적으로 처리할 데이터가 들어 있다.
      • 메시지 키와 메시지 값은 직렬화되어 브로커로 전송되기 때문에 컨슈머가 이용할 때는 직렬화한 형태와 동일한 형태로 역직렬화를 수행해야 한다. 예를 들어 프로듀서가 StringSerializer로 직렬화한 메시지 값을 컨슈머가 IntegerDeserializer로 역직렬화하면 정상적인 데이터를 얻을 수 없다.
    • 오프셋
      • 0 이상의 숫자로 이루어져 있다.
      • 레코드의 오프셋은 직접 지정할 수 없고, 브로커에 저장될 때 이전에 전송된 레코드의 오프셋 + 1 값으로 생성

     

     

     

     

    ⭐ 각각의 개념들을 살펴봤으니 ⭐

    ⭐ 해당 개념들이 카프카 내에서 전체적으로 어떻게 동작하는지 예시를 통해 알아보자! ⭐

     

     

     

     

    1개의 파티션을 가지는 토픽의 레코드 저장 및 읽기 과정

     

    첫 번째 파티션 번호는 0번부터 시작하며,

    하나의 파티션은 큐와 같이 내부에 레코드가 파티션 끝에서부터 차곡차곡 쌓이게 된다.

    (0 > 1 > 2 > 3 > ....)

     

     

    아래 사진의 click_log 토픽에 카프카 컨슈머가 붙게 되면,

    레코드를 가장 오래된 순서대로 가져간다. (0부터)

     

    컨슈머는 또 다른 레코드가 들어올 때까지 기다리며,

    여기서 컨슈머가 토픽 내부의 파티션에서 레코드를 가져가더라도 레코드는 삭제되지 않는다.

    파티션에 그대로 남게 되는 것이다.

     

     

    그렇다면 이 파티션에 남은 데이터는 누가 들고 가는 걸까??

    바로 새로운 컨슈머가 붙었을 때, 다시 0번부터 가져가서 사용할 수 있다.

     

    다만, 컨슈머그룹이 달라야하고 auto.offset.reset=earliest로 세팅 되어 있어야 한다.

    이처럼 사용할 경우, 동일 데이터에 대해서 두번 처리할 수 있는데

    이는 카프카를 사용하는 아주 중요한 이유이기도 하다.

     

     

     

     

     

    2개 이상의 파티션을 가지는 토픽의 레코드 저장 및 읽기 과정

    1개의 파티션을 가진 토픽 예시에 이어서

    확장하여 2개 이상의 파티션으로 설정했을 경우라고 가정해보자.

     

    이어서 레코드 7을 토픽에 담으려고 하는데, 어느 파티션에 들어가야 할까??

     

    이때 프로듀서가 레코드를 보낼 때,

    레코드에 메시지 키를 담아서 보낼 수 있다는 것을 우리는 알고있다!

     

    1. 키가 null이고, 기본 파티셔너를 사용할 경우 --> 라운드 로빈(Round Robin)으로 할당

    2. 키가 있고, 기본 파티셔너를 사용할 경우 --> 키의 해시(Hash) 값을 구하고, 특정 파티션에 할당

     

     

    이번 예시는 별도의 key를 설정하는 것을 가정하지 않았으므로 partition #1에 들어가게 된다.

    라운드 로빈 방식으로 할당되므로,

    레코드 7부터 11까지 파티션에 들어가는 순서를 살펴보면 아래와 같다.

     

    아래는 파티션의 개수가 3개일 때의 모습이다.

     

     

    근데 파티션을 늘리는 것은 아주 조심해야 한다.

    왜냐하면 파티션을 늘리는 건 가능하지만, 파티션은 다시 줄일 수 없기 때문이다.

     

    그렇다면 왜 파티션을 늘리는 걸까?

    --> 파티션을 늘리면 컨슈머의 개수를 늘려서 데이터 처리를 분산시킬 수 있다.

     

    이렇게 데이터가 늘어나면 파티션의 데이터는 언제 삭제될까?

    --> 삭제되는 타이밍은 옵션에 따라 다르다.

        레코드가 저장되는 최대 시간과 크기를 지정할 수 있다.

        이를 지정하게 되면, 일정한 기간 혹은 용량동안 데이터를 저장할 수 있게 되고

        적절하게 데이터가 삭제될 수 있도록 설정 할 수 있다.

     

     

     

     

     

     

    본 내용은 아래 교재와 강의를 바탕으로 정리한 글입니다.

     

     

    아파치 카프카 애플리케이션 프로그래밍 with 자바 | 최원영 - 교보문고

    아파치 카프카 애플리케이션 프로그래밍 with 자바 | 아파치 카프카 애플리케이션 개발을 위한 「실전 가이드」 아파치 카프카란 무엇일까? 카프카 애플리케이션은 어떻게 만들까? 데이터 파이

    product.kyobobook.co.kr

     

     

Designed by Tistory.