아파치 카프카 애플리케이션 프로그래밍 with 자바 책 공부 내용 정리
카프카 브로커
카프카 브로커는 카프카 클라이언트와 데이터를 주고받기 위해 사용하는 주체이자, 데이터를 분산 저장하여 장애가 발생 하더라도 안전하게 사용할 수 있도록 도와주는 애플리케이션이다.
카프라 클러스터로 묶인 브로커들은 프로듀서가 보낸 데이터를 안전하게 분산 저장하고 복제하는 역할을 수행한다.
- 데이터 저장, 전송
프로듀서로부터 데이터를 전달받으면
카프카 브로커는 프로듀서가 요청한 토픽의 파티션에 데이터를 저장하고
컨슈머가 데이터를 요청하면 파티션에 저장된 데이터를 전달한다.
카프카는 페이지 캐시를 사용하여 디스크 입출력 속도를 높였다.
페이지 캐시란 OS에서 파일 입출력의 성능 향상을 위해 만들어 놓은 메모리 영역이다.
- 데이터 복제, 싱크
카프카의 데이터 복제는 파티션 단위로 이루어진다.
토픽을 생성할 때 파티션의 복제 개수(replication factor)도 같이 설정된다.
복제 개수의 최솟값은 1이고, 최댓값은 브로커 개수만큼 설정하여 사용할 수 있다.
복제된 파티션은 리더(leader)와 팔로워(follower)로 구성된다.
프로듀서 또는 컨슈머와 직접 통신하는 파티션을 리더, 나머지 복제 데이터를 가지고 있는 파티션을 팔로워라 한다.
팔로워들은 리더의 오프셋을 확인하여 현재 자신이 가지고 있는 오프셋과 차이가 나는 경우 리더로부터 데이터를 가져와 자신의 파티션에 저장하는데, 이를 복제(replication)이라한다.
만약 리더 파티션이 속한 브로커가 다운되면 팔로워 중 하나가 리더 지위를 넘겨받는다.
- 컨트롤러(controller)
클러스터의 다수 브로커 중 한 대가 컨트롤러의 역할을 한다.
컨트롤러는 다른 브로커들의 상태를 체크하고 브로커가 클러스터에서 빠지는 경우 해당 브로커에 존재하는 리더 권한을 재분배한다.
만약 컨트롤러 역할을 하는 브로커에 장애가 생기면 다른 브로커가 컨트롤러 역할을 한다.
- 데이터 삭제
카프카는 다른 메시징 플랫폼과 다르게 컨슈머가 데이터를 가져가더라고 토픽의 데이터는 삭제되지 않는다.
또한, 컨슈머가 프로듀서가 데이터 삭제를 요청할 수도 없다. 오직 브로커만이 데이터를 삭제할 수 있다.
데이터 삭제는 파일 단위로 이루어지는데 이 단위를 '로그 세그먼트(log segment)'라고 부른다.
이 세그먼트에는 다수의 데이터가 들어 있기 때문에 일반적인 데이터베이스처럼 특정 데이터를 선별해서 삭제할 수 없다.
세그먼트는 데이터가 쌓이는 동안 파일 시스템으로 열려있으며 카프카 브로커에 log.segement.bytes 또는 log.segment.ms 옵션에 값이 설정되면 세그먼트 파일이 닫힌다.
닫힌 세그먼트 파일은 log.retention.bytes 또는 log.retention.ms 옵션의 설정값이 넘으면 삭제된다.
닫힌 세그먼트 파일을 체크하는 간격은 카프카 브로커 옵션에 설정된 log.retention.check.interval.ms에 따른다.
- 컨슈머 오프셋 저장
컨슈머 그룹은 토픽이 특정 파티션으로부터 데이터를 가져가서 처리하고 이 파티션의 어느 레코드까지 가져갔는지 확인하기 위해 오프셋을 커밋한다.
커밋한 오프셋은 __consumer_offsets 토픽에 저장한다.
여기에 저장된 오프셋을 토대로 컨슈머 그룹은 다음 레코드를 가져가서 처리한다.
- 코디네이터(coordinator)
클러스터의 다수 브로커 중 한 대는 코디네이터의 역할을 수행한다.
코디네이터는 컨슈머 그룹의 상태를 체크하고 파티션을 컨슈머와 매칭되도록 분배하는 역할을 한다.
파티션을 컨슈머로 재할당하는 과정을 '리밸런스(rebalance)'라고 부른다.
주키퍼
카프카의 메타데이터를 관리하는 데에 사용된다.
카프카 클러스터로 묶인 브로커들은 동일한 경로의 주키퍼 경로로 선언해야 같은 카프카 브로커 묶음이 된다.
만약 클러스터를 여러 개로 운영한다면 한 개의 주키퍼에 다수의 카프카 클러스터를 연결해서 사용할 수도 있다.
토픽과 파티션
토픽은 카프카에서 데이터를 구분하기 위해 사용하는 단위이다.
토픽은 1개 이상의 파티션을 소유하고 있다.
파티션에는 프로듀서가 보낸 데이터들이 들어가 저장되는데 이 데이터를 '레코드(record)'라 부른다.
파티션은 자료구조에서 접하는 큐(queue)와 비슷한 구조라 생각하면 쉽다. first-infirst-out(FIFO) 구조와 같이 먼저 들어간 레코드는 컨슈머가 먼저 가져가게 된다. 다만, 일반적인 자료구조로 사용되는 큐는 데이터를 가져가면(pop) 레코드를 삭제하지만 카프카에서는 삭제되지 않는다.
- 토픽 이름 제약 조건
* 빈 문자열 토픽 이름은 지원하지 않는다.
* 토픽 이름은 마침표 하나(.) 또는 마침표 둘(..)로 생성될 수 없다.
* 토픽 이름의 길이는 249자 미만으로 생성되어야 한다.
* 토픽 이름은 영어 대소문자와 숫자 0부터 9 그리고 마침표(.), 언더바(_), 하이픈(-) 조합으로 생성할 수 있다. 이 외의 문자열이 포함된 토픽 이름은 생성 불가하다.
* 카프카 내부 로직 관리 목적으로 사용되는 2개 토픽(__consumer_offsets, __transaction_state)과 동일한 이름으로 생성 불가하다.
* 카프카 내부적으로 사용하는 로직 때문에 토픽 이름에 마침표(.)와 언더바(_)가 동시에 들어가면 안된다. 생성은 할 수 있지만 사용 시 이슈가 발생할 수 있기 때문에 WARNING 메세지가 발생한다.
* 이미 생성된 토픽 이름의 마침표(.)를 언더바(_)로 바꾸거나 언더바(_)를 마침표(.)로 바꾼 경우 신규 토픽 이름과 동일하다면 생성할 수 없다. 예를 들어, to.pic 이름의 토픽이 생성되어 있다면 to_pic 이름의 토픽을 생성할 수 없다.
레코드
레코드는 타임스탬프, 메세지 키, 메세지 값, 오프셋으로 구성되어 있다.
프로듀서가 생성한 레코드가 브로커로 전송되면 오프셋과 타임스탬프가 지정되어 저장된다.
브로커에 한번 적재된 레코드는 수정할 수 없고 로그 리텐션 기간 또는 용량에 따라서만 삭제된다.
메세지 키는 메세지 값을 순서대로 처리하거나 메세지 값의 종류를 나타내기 위해 사용한다.
메세지 키를 사용하면 프로듀서가 토픽에 레코드를 전송할 때 메세지 키의 해시값을 토대로 파티션을 지정하게 된다.
즉, 동일한 메세지 키라면 동일 파티션에 들어간다.
메세지 키를 선언하지 않으면 null로 설정된다. 메세지 키가 null로 설정된 레코드는 프로듀서 기본 설정 파티셔너에 따라서 파티션에 분배되어 적재된다.
메세지 값에는 실질적으로 처리할 데이터가 들어있다.
메세지 키와 메세지 값은 직렬화되어 브로커로 전송되기 때문에 컨슈머가 이용할 때는 직렬화한 형태와 동일한 형태로 역직렬화를 수행해야 한다.
직렬화, 역직렬화할 때는 반드시 동일한 형태로 처리해야 한다. 만약 프로듀서가 StringSerializer로 직렬화한 메세지 값을 컨슈머가 IntegerDeserializer로 역직렬화하면 정상적인 데이터를 얻을 수 없다.
레코드의 오프셋은 0 이상의 숫자로 이루어져 있다.
오프셋은 직접 지정할 수 없고 브로커에 저장될 때 이전에 전송된 레코드의 오프셋+1 값으로 생성된다.
오프셋은 카프카 컨슈머가 데이터를 가져갈 때 사용된다.
✨ 참고 도서 정보 :: 아파치 카프카 애플리케이션 프로그래밍 with 자바 (최원영)
'Framework > Kafka' 카테고리의 다른 글
[Kafka] 아파치 카프카 기본 개념 :: 클라이언트 라이브러리 - 컨슈머 API (4) | 2024.09.25 |
---|---|
[Kafka] 아파치 카프카 기본개념 :: 클라이언트 라이브러리 - 프로듀서 API (3) | 2024.09.23 |
[Kafka] 아파치 카프카 CLI 명령어 (1) | 2024.09.05 |
[Kafka] 아파치 카프카 실행 (2) | 2024.09.03 |
[Kafka] 아파치 카프카 (Apache Kafka) 란? (0) | 2024.08.23 |