- Kafka 32023년 08월 18일
- starryeye
- 작성자
- 2023.08.18.오후08:11
공부한 개념을 한 문장씩 쭉 세워본다.
토픽은 카프카에서 데이터를 구분하기 위해 사용하는 단위이다. (RDBMS 의 Table)
토픽은 1개 이상의 파티션을 가진다.
파티션에는 프로듀서가 보낸 데이터들이 저장된다. 해당 데이터를 레코드(record) 라 부른다.
파티션은 큐(Queue) 자료구조와 비슷하게 FIFO 로 동작된다.
큐에서는 데이터를 가져가면(pop) 삭제 하지만, 카프카에서는 삭제하지 않는다.
따라서, 동일한 레코드에 대해 여러 컨슈머 그룹이 가져갈 수 있는 환경이다.
위 그림은..
브로커 3개에 파티션이 5개인 1개의 토픽을 생성한 그림이다.
팔로워 파티션은 없으므로 replication factor 는 1 이다.
위 그림처럼 파티션이 5개인 1개의 토픽을 생성하면..
round-robin 방식으로 브로커에 순차적으로 리더 파티션이 생성된다.
브로커는 하나의 인스턴스 서버로 성능적 한계가 존재한다..
그래서, 위와 같이 하나의 토픽내에 여러 파티션(리더) 를 두면..
카프카 클라이언트는 리더 파티션이 있는 브로커와 통신하므로..
여러 브로커에 골고루 통신을 할 수 있다.
이를 통해 데이터가 특정 브로커와 통신이 집중되는 hot spot 현상을 막을 수 있다.
또한, 브로커는 scalable 하므로 가변적인 환경에서 안정적 운영이 가능하다.
replication factor 를 2 ~ 3 으로 하면 팔로워 파티션도 생성되는데..
팔로워 파티션도 리더 파티션 생성 방식과 동일하게 round-robin 방식으로 각 브로커에 생성된다.
브로커가 죽고 살아나다보면 특정 브로커에 리더 파티션이 쏠려있는 현상이 생길 수 있다.
이때, kafka-reassign-partitions.sh 명령으로 파티션을 재분배할 수 있다.
혹은, auto.leader.rebalance.enable 옵션을 true 로 하면 클러스터 단위에서
리더 파티션을 자동 리밸런싱하도록 도와준다. (브로커의 백그라운드 스레드가 작업)
기본값은 true 이다.
파티션(리더) : 컨슈머 매칭 비율은 1 : 1 또는 N : 1 이다.
1 : N 과 같이 하나의 파티션에 여러 컨슈머가 매칭되어있는 상태는 불가능하다.
카프카에서 브로커를 늘리는 행위는 카프카 자체(브로커)의 (초당) 처리량을 늘릴 수 있는 요소이다.
(리더 파티션이 여러 브로커에 분산 됨)
하지만, 카프카의 성능만 좋다고 해서 데이터 처리량을 늘릴 순 없다.
만약 브로커의 성능은 아주 충분한 상황인데..
프로듀서, 파티션, 컨슈머 모두 1개 씩 있는 상황을 가정해보자..
프로듀서가 초당 10개의 데이터를 보내는데..
컨슈머가 초당 1개의 데이터를 처리하여 처리가 지연되는 상황이 있을 수 있다.
이러한 상황을 컨슈머 랙(LAG)이라 한다.
컨슈머 랙이 4 라면 프로듀서가 4 의 오프셋 만큼 적재해놨지만
해당 컨슈머 그룹이 0 의 오프셋을 처리하는 중이라 보면된다.
위와 같은 상황에서 컨슈머 랙을 해결하려면..
우선 컨슈머를 10개로 늘리면 컨슈머 처리량과 프로듀서 처리량을 맞출 수 있을 것이고..
컨슈머를 늘렸기 때문에 파티션(리더)의 개수도 10개 이상으로 늘려줘야 할 것이다.
파티션은 카프카 병렬처리의 핵심이다.
하나의 컨슈머 그룹으로 묶인 컨슈머들이 레코드를 병렬로 처리 할 수 있도록 파티션(리더)에 매칭된다.
카프카에서 파티션의 개수를 줄이는 것은 지원되지 않는다.
토픽을 삭제하고 새로 생성하는 것 외에는 방법이 없다.
카프카 레코드는..
timestamp, offset, headers, key, value 의 요소들로 구성되어있다.
카프카 레코드는 한번 브로커에 저장되면 수정할 수 없으며 삭제는 브로커의 삭제 정책을 따른다.
레코드 타임스탬프는 토픽 단위의 message.timestamp.type 옵션에 따라..
프로듀서에서 레코드를 생성할 때의 시간 값이 사용되거나..
실제 브로커에 적재 될 때의 시간 값이 사용된다..
레코드 오프셋은 각 파티션(리더) 별로 고유하게 0 부터 시작하여 1 씩 증가된다.
따라서 프로듀서에서 레코드를 생성할 때는 오프셋이 지정될 수 없다.
레코드 헤더는 key - value 로 데이터를 추가 할 수 있는 공간이다.
HTTP header 와 용도나 성격이 비슷하다.
레코드 value 는 실질적으로 전달될 데이터가 담기는 공간이다.
데이터는 프로듀서, 컨슈머에서 직렬화 - 역직렬화 가 이루어지므로..
카프카 클라이언트에서 포맷을 미리 정해줘야한다.
보통 String(json) 으로 한다. (간단한 숫자이면 공간 낭비 일 수는 있다.)
레코드 key 는 레코드를 어느 파티션(리더)에 적재할지 정하는 용도로 사용된다.
이를 파티셔닝이라 부른다.
key 를 정하는 행위는 파티셔너에 의해 수행된다.
key 는 필수 값이 아니며, null 일 경우 round-robin 방식으로 파티션에 적재된다.
null 이 아닐 때는 기본 파티셔너에 의해 key 를 해싱하여 특정 파티션에 매핑시켜 적재하도록 한다.
리더 파티션은 특정 브로커에 고정적으로 위치하지 않는다.
카프카 클라이언트는 데이터를 전달하기 위해 리더 파티션의 위치를 알아야한다.
이를 위해 메타데이터를 브로커로 부터 요청하고 응답 받는다.
metadata.max.age.ms 옵션은 메타데이터를 강제로 refresh 하는 간격이다. (기본값은 5분이다.)
metadata.max.idle.ms 옵션은 프로듀서가 idle 상태일 때 메타데이터를 캐시에 유지하는 기간이다. (기본값은 5분)
카프카 클라이언트(프로듀서, 컨슈머)의 메타데이터가..
현재의 파티션 상태에 맞게 refresh 되지 않은 상태에서 잘못된 브로커로 데이터를 요청하면..
LEADER_NOT_AVAILABLE Exception 이 발생한다. (요청한 브로커에 리더 파티션이 존재하지 않음)
(Spring 에서는 자동으로 정확한 브로커로 다시 요청 응답이 이루어지는것 같다..)
다음글이전글이전 글이 없습니다.댓글