본문 바로가기
TIL/카프카

실전 카프카 개발부터 운영까지 - 4. 카프카의 내부 동작 원리와 구현

by yeon_zoo 2024. 3. 20.

4.1 카프카 리플리케이션

4.1.1 리플리케이션 동작 개요

replication-factor라는 기본 옵션에서 설정하는 값을 토대로 리플리케이션을 생성한다. N개의 리플리케이션이 생성되면, N-1개까지의 브로커 장애가 발생해도 메시지 손실 없이 안정적으로 메시지를 주고 받을 수 있다.

4.1.2 리더와 팔로워

리더 : 모든 읽기와 쓰기를 진행. 프로듀서는 리더에게만 메시지를 전송 / 컨슈머도 리더로부터 메시지를 가져옴.
팔로워 : 리플리케이션 진행. 파티션의 리더가 새로운 메시지를 받았는지 지속적으로 확인하고 새로운 메시지가 있다면 해당 메시지를 리더로부터 복제.

4.1.3 복제 유지와 커밋

  • ISR(InSyncReplica) 그룹 : 리더 & 팔로워는 ISR이라는 논리적 그룹으로 묶여있다. ISR 그룹 안에 속한 팔로워들만이 새로운 리더 자격을 얻을 수 있다. 만약 팔로워가 특정 주기의 시간만큼 복제 요청을 하지 않는다면, 리더는 해당 팔로워의 리플리케이션 동작에 문제가 발생했다고 판단해 ISR 그룹에서 추방한다. (리더 가능성 박탈)
  • 하이워터 마크 : ISR 내에서 모든 팔로워의 복제가 완료되면 리더는 내부적으로 커밋 표시한다. 마지막 커밋 오프셋 위치를 하이워터 마크라고 한다.
  • 커밋 : 리플리케이션 팩터 수의 모든 리플리케이션이 전부 메시지를 저장했음을 의미. 커밋된 메시지만 컨슈머가 읽어갈 수 있다. (for 메시지의 일관성)
  • replication-offset-checkpoint 파일 : 브로커가 재시작될 때, 커밋된 메시지를 유지하기 위해 사용하는 파일. 마지막 커밋 오프셋 위치를 저장한다.

4.1.4 리더와 팔로워의 단계별 리플리케이션 동작

카프카는 리더와 팔로워 간의 통신을 최소화할 수 있는 방안으로 설계되어 리더의 부하를 줄였다.

리더와 팔로워 간의 통신 방법

 

RabbitMQ Kafka
미러(= 카프카의 팔로워)가 메시지를 받았는지 리더에게 ACK를 리턴함.
  • 팔로워가 다음 fetch 요청을 보낼 때, 자신이 갖고 있는 마지막 오프셋 + 1 번호의 오프셋에 대한 리플리케이션 요청을 보낸다. (따라서 fetch 요청이자 ack 역할을 동시에 수행한다)
  • 리더는 요청받은 메시지에 대한 리플리케이션 응답에 n번 오프셋 메시지가 커밋되었다는 내용도 같이 전달한다.
  • 리더의 응답을 받은 팔로워는 n번 오프셋 메시지가 커밋되었다는 사실을 인지하고, 리더와 동일하게 n번 오프셋 메시지에 커밋을 표시한다.

이렇게 카프카는 ACK 통신을 제거하여 리더가 메시지를 주고 받는 기능에 더 집중할 수 있도록 구성했다. 또한, 팔로워들이 Pull 하는 방식으로 동작하게 하여 리더의 부하를 줄였다.

4.1.5 리더에포크와 복구

리더에포크 : 카프카의 파티션들이 복구 동작을 할 때 메시지의 일관성을 유지하기 위한 용도로 이용하며 컨트롤러에 의해 관리되는 32비트의 숫자. 복구 동작 시 하이워터마크를 대체하는 수단으로도 활용된다.

팔로워의 하이워터마크와 리더의 하이워터마크가 차이가 나는 상태에서 팔로워가 죽게 되면, 팔로워가 스스로 죽기 직전 커밋된 하이워터마크만을 확인하면 팔로워 내에 있는 커밋되지 않은 메시지를 버리게 될 수 있다. 이 때 리더에게 리더에포크 요청을 보내어 리더의 하이워터마크와 싱크(상향 조정)를 맞출 수 있다.

댓글