실제 업무에서 카프카를 사용하는 작성하는 어플리케이션을 위해서 내부 구조를 알 필요는 없지만 어떻게 동작하는지 알아두면 문제가 발생했을 때 신속히 원인을 파악하고 대처하는(트러블슈팅) 기반이 될 수 있다.
이 글에서는 책 <O’Reilly Kafka The Definitive Guide>을 바탕으로 카프카 복제(Replication)가 동작하는 방식, 카프카가 프로듀서와 컨슈머의 요청을 처리하는 방법, 카프카가 스토리지(파일 형식, 인덱스 등)를 처리하는 방법을 알아본다.
클러스터 멤버십
주키퍼의 트리구조 데이터 저장
카프카에서 사용하는 주키퍼의 중요사항을 알아볼 필요가 있다. 주피커는 내부적으로 디렉터리처럼 계층적인 트리구조로 데이터를 저장한다. 데이터를 저장하는 노드를 znode라고 하며 각 znode의 이름 앞에는 /(슬래시)를 붙여 디렉터리처럼 경로(path)를 사용해 노드의 위치를 식별한다.
노드는 임시(ephemeral) 노드와 영구(persistent) 노드로 나뉜다. 임시 노드는 노드를 생성한 클라이언트가 연결되어 있을 때만 존재하고 끊어지면 자동으로 삭제된다. 영구 노드는 클라이언트가 삭제하지 않는한 계속 보존된다. 이러한 노드들을 모니터링하는 watch 기능이 있다. 클라이언트가 특정 노드를 watch하면 해당 노드에 변경사항이 생겼을 때 클라이언트에게 콜백 호출로 알려준다.
카프카에서의 활용
카프카는 이런 계층적인 트리구조로 데이터를 저장하는 주키퍼를 활용해 브로커들의 메타데이터를 유지 관리한다. 카프카 클러스터가 사용하는 주키퍼의 최상위 노드가 /kafka-main이라면 자식노드로 /kafka-main/controller, /kafka-main/brokers, /kafka-main/config가 생된된다. 각 자식노드의 역할을 다르다.
controller 자식노드에는 카프카 클러스터의 컨트롤러 정보가 저장된다. brokers 자식노드에는 브로커 관련 정보가 저장된다. brokers 역시 ids, topics라는 자식노드를 가지고 있으며 각각 브로커ID, 토픽 정보가 저장된다. config 자식노드에는 토픽의 설정 정보가 저장된다. 원래 최상위 노드의 자식노드로 consumers라는 게 있었고 이곳엔 컨슈머의 파티션 오프셋 정보를 저장했지만 카프카 0.9버전부터는 __consumer_offsets 라는 토픽에 저장하도록 변경되었다.
브로커의 생성
모든 카프카 브로커는 고유 식별자를 가지는데, 브로커 프로세스가 시잘될 때 주키퍼의 /brokers/ids 노드에 자신의 ID를 임시 노드로 등록한다. 만일 이 등록과정에 이미 같은 ID의 임시 노드가 있다면 에러가 발생한다. 또한 카프카 클러스터에 브로커가 삭제되거나 주키퍼와 연결이 끊어지면 해당 브로커가 생성했던 /brokers/ids 밑의 임시 노드는 삭제된다. 하지만 해당 브로커의 ID는 다른 데이터 구조 (/brokers/topics 등)에는 브로커들의 ID가 포함되어있다. 따라서 누락된 브로커 ID로 완전히 새로 교체한 브로커를 시작하면 새로 시작된 브로커가 누락된 브로커에 할당되었던 파티션과 토픽들을 가지고 클러스터에 합류한다. 새로운 브로커로 누락된 브로커를 복구시킬 수 있다.
'Data Engineering > Kafka' 카테고리의 다른 글
카프카 내부 메커니즘 - 4. 요청 처리 (0) | 2022.02.17 |
---|---|
카프카 내부 메커니즘 - 2.컨트롤러 (0) | 2022.02.15 |
Kafka의 Zero copy (0) | 2022.02.12 |
Kafka의 구조와 원리 (0) | 2021.07.04 |
Kafka tutorial - 1 [설치, topic생성, 발행, consumer group 실행] (0) | 2021.07.03 |