"아파치 카프카 애플리케이션 프로그래밍 with 자바"
교재의 학습 내용을 정리하였습니다
우선 토픽이란?
토픽은 카프카에서 데이터를 구분하기 위해 사용하는 단위임!
=> 토픽은 1개 이상의 파티션을 소유하고 있음
(파티션에는 프로듀서가 보낸 데이터들이 들어가 저장되는데 이 데이터를 '레코드' 라고 부름)
레코드에 대해 자세히 알아보고 가자
레코드는 타임스탬프, 메시지 키, 메시지 값, 오프셋, 헤더로 구성되어 있음
프로듀서가 생성한 레코드가 브로커로 전송되면 오프셋과 타임스탬프가 지정되어 저장됨
=> 브로커에 한번 적재된 레코드는 수정할 수 없고 로그 리텐션 기간 또는 용량에 따라서만 삭제됨
로그 리텐션이란 카프카 브로커에 저장된 메시지(레코드)를 얼마나 오래 보관할지를 결정하는 정책임
=> 카프카는 데이터를 로그(log)라는 형태로 디스크에 저장하고, 이 데이터가 얼마나 오래 유지될지를 리텐션 설정에 따라 관리
타임스탬프는 프로듀서에서 해당 레코드가 생성된 시점의 유닉스 타임이 설정됨
(컨슈머는 이를 토대로 레코드가 언제 생성되었는지 알 수 있음)
하지만 프로듀서가 레코드를 생성할 때 임의의 타임스탬프 값을 설정할 수 있고, 토픽 설정에 따라 브로커에 적재된 시간(LogAppendTime)으로 설정될 수도 있음
메시지 키는 메시지 값을 순서대로 처리하거나 메시지 값의 종류를 나타내기 위해 사용됨
(프로듀서가 토픽에 레코드를 전송할 때 메시지 키의 해시값을 토대로 파티션을 지정하게됨)
=> 동일한 메시지 키라면 동일 파티션에 들어감
(어느 파티션에 지정될지 알 수 없고 파티션 개수가 변경되면 메시지키와 파티션 매칭이 달라지므로 주의)
메시지 키를 선언하지 않으면 null로 설정되고 이런 레코드는 프로듀서 기본 설정 파티셔너에 따라서 파티션에 분배되어 적재
메시지 값에는 실질적으로 처리할 데이터가 들어있음
메시지 키와 값은 직렬화되어 브로커로 전송되기 때문에 컨슈머가 이용할 때 직렬화한 형태와 동일한 형태로 역직렬화를 수행해야 함
(프로듀서가 StringSerializer로 직렬화한 메시지 값을 컨슈머가 IntegerDeserializer로 역직렬화하면 정상적인 데이터를 얻을 수 X)
레코드의 오프셋은 0 이상의 숫자로 이루어져 있고 이는 직접 지정할 수 없으며 브로커에 저장될 때 이전에 전송된 레코드의 오프셋에 +1 값으로 생성됨
=> 이 오프셋은 카프카 컨슈머가 데이터를 가져갈 때 사용됨
(컨슈머 그룹으로 이루어진 카프카 컨슈머들이 파티션의 데이터를 어디까지 가져갔는지 명확히 지정할 수 있음)
헤더는 레코드의 추가적인 정보를 담는 메타데이터 저장소 용도로 사용함
(키/값 형태로 데이터를 추가하여 레코드의 속성을 저장하여 컨슈머에서 참조 가능)
=> 그래서 결론적으로는 그림을 보면 레코드가 토픽의 파티션에 저장되는 것을 볼 수 있음
파티션은 카프카의 병렬처리의 핵심으로써 그룹으로 묶인 컨슈머들이 레코드를 병렬로 처리할 수 있도록 매칭됨
=> 컨슈머의 처리량이 한정된 상황에서 많은 레코드를 병렬로 처리하는 가장 좋은 방법은 컨슈머 수를 늘려 스케일 아웃 하는 것임!
(컨슈머 개수를 늘림과 동시에 파티션 개수도 늘리면 처리량이 증가하는 효과를 볼 수 있음)
파티션은 queue와 비슷한 구조라고 생각하면 이해하기 쉬움
FIFO 구조와 같이 먼저 들어간 레코드는 컨슈머가 먼저 가져감
(카프카에서는 pop 같이 레코드를 삭제하진 X)
=> 이러한 특징 때문에 토픽의 레코드는 다양한 목적을 가진 여러 컨슈머 그룹들이 토픽의 데이터를 여러 번 가져갈 수 있음
토픽 이름 제약 조건
토픽 이름을 생성할 때 제약 조건이 있음
- 빈 문자열 토픽 이름은 지원하지 않음
- 토픽 이름은 마침표 하나(.) 또는 마침표 둘(..)로 생성될 수 없음
- 토픽 이름의 길이는 249자 미만으로 생성되어야 함
- 토픽 이름은 영어 대소문자와 숫자 0부터 9 그리고 마침표(.), 언더바(_), 하이픈(-) 조합으로 생성할 수 있음
(이외의 문자열이 포함된 토픽 이름은 생성 불가) - 카프카 내부 로직 관리 목적으로 사용되는 2개 토픽(__consumer_offsets, __transaction_state)과 동일한 이름으로 생성 불가능
- 카프카 내부적으로 사용하는 로직 때문에 토픽 이름에 마침표(.)와 언더바(_)가 동시에 들어가면 안됨
(생성은 가능하나 사용 시 이슈가 발생할 수 있기 때문에 WARNING 메세지가 발생함) - 이미 생성된 토픽 이름의 마침표(.)를 언더바(_)로 바꾸는 경우나 이 반대의 경우 신규 토픽 이름과 동일하다면 생성할 수 없음
(to.pic 이름의 토픽이 생성되어 있다면 to_pic 이름의 토픽을 생성할 수 없음)
의미있는 토픽 이름 작명 방법
토픽 이름을 모호하게 작성하면 유지보수 시 큰 어려움을 겪을 수 있음
(최소한 토픽 이름을 통해 어떤 개발환경에서 사용되는 것인지 판단 가능해야하고 어떤 어플리케이션에서 어떤 데이터 타입으로 사용되는지 유추할 수 있어야 함!)
전사에서 공용으로 사용하고 있는 카프카라면 토픽의 ownership을 가진 팀의 이름을 추가하는 것도 고려해볼만 하고
히스토리를 명확히 하고 싶다면 회사 내부에서 사용 중인 JIRA 타겟 번호를 토픽 이름에 넣는 것도 좋은 방법
(카프카 클러스터를 2대 이상 운영하는 경우에는 클러스터를 구분하기 위해 카프카 클러스터 이름을 넣을 수 도 있음)
이런식으로 작명하는게 좋은데 위에서 말했듯이 카프카 프로듀서나 컨슈머에서 토픽을 사용할 때 대소문자를 구분하기 때문에 human error 방지를 위해 대소문자를 섞어 쓰는 카멜케이스는 지양하는게 좋음
(구분자로 특수문자를 조합하여 사용하면 좋음)
토픽 이름에 대한 규칙을 사전에 정의하고 구성원들이 그 규칙을 잘 따르는 것이 가장 중요함
=> 아무리 규칙을 정해도 따르지 않으면 예측하지 못한 방향으로 토픽이름이 생성될 것임
(카프카는 토픽 이름 변경을 지원하지 않으므로 이름 변경을 위해선 삭제 후 다시 생성해야 함)
'Data Engineering > Kafka' 카테고리의 다른 글
[Apache Kafka] 카프카 브로커 · 클러스터 · 주키퍼 (5) | 2024.09.14 |
---|