토픽(Topic)과 파티션(Partition)
토픽(Topic)은 카프카에서 데이터를 구분하기 위해 사용하는 단위입니다.
토픽은 1개 이상의 파티션(Partition)을 소유하고 있고 파티션에는 프로듀서가 보낸 데이터들이 들어가 저장되는데 이 데이터를 레코드(Record)라고 부릅니다.
파티션은 카프카의 병렬처리의 핵심으로써 그룹으로 묶인 컨슈머들이 레코드를 병렬로 처리할 수 있도록 매칭됩니다.
컨슈머의 처리량이 한정된 상황에서 파티션 개수와 컨슈머 개수를 늘려 스케일 아웃하여 병렬로 처리가 가능하므로 처리량이 증가하는 효과를 볼 수 있습니다.
파티션은 FIFO(Firtst-in-first-out) 형태로 큐(Queue)와 비슷한 구조이지만 다른 점이 있습니다.
큐는 데이터를 가져가면 삭제하지만 카프카에서는 삭제하지 않고 컨슈머가 데이터를 가져가는 것과 별개로 관리하게 됩니다.
이러한 특징 때문에 토픽의 레코드는 다양한 목적을 가진 여러 컨슈머 그룹들이 토픽의 데이터를 여러 번 가져갈 수 있습니다.
토픽 이름 제약 조건
토픽은 생성할 때 토픽 이름에 대한 제한사항이 존재합니다.
- 빈(empty) 문자열로 생성할 수 없습니다.
- 마침표 하나(.) 또는 마침표 둘(..)로 생성할 수 없습니다.
- 249자 미만으로 생성해야 합니다.
- 영어 대소문자와 숫자 0부터 9 그리고 마침표(.), 언더바(_), 하이픈(-)의 조합으로만 생성할 수 있습니다.
- __consumer_offsets, __transaction_state(카프카 내부 관리 토픽)으로는 생성할 수 없습니다.
- 카프카 내부적으로 사용하는 로직 때문에 마침표(.)와 언더바(_)가 동시에 들어가면 생성은 가능하지만 사용 시 이슈가 발생할 수 있습니다.(WARNING 메시지 발생)
- 마침표(.)와 언더바(_)를 서로 치환한 경우 신규 토픽 이름과 동일하다면 생성할 수 없습니다.
(예) 이름이 topic.name인 토픽이 있다면 topic_name으로 생성 불가
의미 있는 토픽 이름 작명 방법
토픽의 이름을 모호하게 작성하면 유지보수 시 어려움이 생길 수 있습니다.
최소한 토픽 이름을 통해 어떤 개발환경에서 사용되는 것인지 판단이 가능해야 하고, 어떤 애플리케이션에서 어떤 데이터 타입으로 사용되는지 유추할 수 있어야 합니다.
전사에서 공통으로 사용하고 있다면 팀의 이름을, 히스토리를 파악하고 싶다면 업무 태스크의 고유번호를, 만약 클러스터(Cluster)를 2대 이상 운영할 때는 클러스터의 이름을 넣어 작명할 수 있습니다.
위 토픽 이름 제약 조건에서 설명한 여러 특수문자를 넣어 토픽 이름의 구분자로 사용하여 편리하게 읽을 수 있습니다.
토픽의 이름은 영어 대소문자 모두 지원하며 프로듀서나 컨슈머에서 사용 시 대소문자를 구분하여 처리하게 됩니다.
그렇기 때문에 휴먼오류를 방지하기 위해. 카멜케이스(CamelCase)를 사용하기 보다는 케밥케이스(kebab-case) 또는 스네이크 표기법(snake_case)을 사용하는 것을 권장합니다.
예시
- <환경>.<팀명>.<애플리케이션명>.<메세지타입> : prod.develop-team.order.json
- <프로젝트명>.<서비스명>.<환경>.<이벤트명> : commerce.order.prd.cancel
- <환경>.<서비스명>.<JIRA티켓>.<메시지타입> : prod.order.jira-123.json
- <클러스터명>.<환경>.<서비스명>.<메시지타입> : app-kafka.prod.order.json
토픽 이름에 대한 규칙을 사전에 정의하고 구성원들이 그 규칙을 잘 따르지 않는다면 의미가 없거니와 모호한 토픽 이름이 생성되어 이것들은 기술 부채(technical debt)로 이어질 수 있습니다.
게다가 토픽 이름 변경을 지원하지 않으므로 이름을 변경하기 위해서는 삭제 후 다시 생성해야 합니다.
레코드(Record)
레코드는 타임스탬프(Timestamp), 메시지 키(Key), 메시지 값(Value), 오프셋(Offset), 헤더(Header)로 구성되어 있습니다.
타임스탬프(Timestamp)
프로듀서가 생성한 레코드가 브로커에 전송되면 타임스탬프(레코드가 생성된 시점)가 지정되어 저장되고, 적재된 레코드는 수정이 불가능합니다.
하지만 프로듀서가 레코드를 생성할 때 임의의 타임스탬프 값을 설정할 수 있고, 토픽 설정에 따라 브로커에 적재된 시간으로 저장될 수 있다는 점을 주의해야 합니다.
메시지 키(Key)
메시지 키는 메시지 값을 순서대로 처리하거나 메시지 값의 종류를 나타내기 위해 사용합니다.
메시지 키를 사용하면 프로듀서가 토픽에 레코드를 전송할 때 메시지 키의 해시값을 토대로 파티션을 지정하게 되어, 동일한 메시지 키라면 동일한 파티션에 전송되게 됩니다.
하지만 어느 파티션에 지정될지 알 수 없고 파티션 개수가 변경되면 메시지 키와 파티션 매칭이 달라지게 되므로 주의해야 합니다.
만약 메시지 키를 사용하지 않는다면 프로듀서 기본 설정 파티셔너에 따라서 파티션에 분배되어 적재됩니다.
메시지 값(Value)
메시지 값에는 실질적으로 처리할 데이터가 들어있습니다.
키와 값은 직렬화되어 브로커로 전송되기 때문에 컨슈머가 이용할 때는 직렬화한 형태와 동일한 형태로 역직렬화를 수행해야 정상적인 데이터를 얻을 수 있습니다.
오프셋(offset)
오프셋은 0 이상의 숫자로 이루어져 있으며 직접 설정할 수 없고 이전에 전송된 레코드 오프셋+1 값으로 생성됩니다.
오프셋은 컨슈머가 데이터를 가져갈 때 사용하게 되는데 오프셋을 사용하면 컨슈머 그룹으로 이루어진 컨슈머들이 파티션의 데이터를 어디까지 가져갔는지 명확히 지정할 수 있습니다.
헤더(Header)
헤더는 레코드의 추가적인 정보를 담는 메타데이터 저장소 용도로 사용합니다.
헤더는 키/값 형태로 데이터를 추가하여 레코드의 속성을 저장하여 컨슈머에서 참조할 수 있습니다.
다음 글
카프카 커맨드 라인 툴(kafka command-line-tool) 명령어 설명 및 사용법
카프카 커맨드 라인 툴(kafka command-line-tool)카프카(kafka)에서 제공하는 커맨드 라인 툴을 통해 카프카 브로커 운영에 필요한 다양한 명령을 내릴 수 있습니다.카프카를 운영할 때는 카프카 클
devbksheen.tistory.com
'Apache Kafka' 카테고리의 다른 글
카프카 클라이언트(Kafka Client) - 컨슈머(Consumer) API (1/2) (0) | 2025.01.29 |
---|---|
카프카 클라이언트(Kafka Client) - 프로듀서(Producer) API (0) | 2025.01.20 |
카프카 커맨드 라인 툴(kafka command-line-tool) 명령어 설명 및 사용법 (0) | 2025.01.17 |
카프카(Kafka)의 기본 개념 - 브로커(Broker) (0) | 2025.01.16 |
Spring Boot에 Kafka 연동 (0) | 2021.09.24 |