모종닷컴

Quorum based Controller 본문

Programming/Apache Kafka

Quorum based Controller

모종 2024. 1. 7. 17:04
반응형

브로커와 컨트롤러

카프카 버전 2.8 이후부터 메타데이터 관리를 주키퍼를 사용하지 않고 자체 관리하게 되었는데 이로 인해 카프카 애플리케이션의 역할은 크게 두 가지(브로커, 컨트롤러)로 구분할 수 있다. '컨트롤러'는 클러스터 수준의 메타데이터 관리 및, 리더 선출, 브로커 추가 제거 같은 클러스터 관리 작업을 하는 역할을 하며, '브로커'는 메시지의 저장 및 전송과 관련된 작업을 담당한다. 애플리케이션을 역할을 지정할 수 있는데, 브로커나 컨트롤러 중 하나의 역할만 지정할수도 있고, 브로커 겸 컨트롤러 역할도 지정할 수 있다.

Quorum based Controller

  • KRaft 합의 알고리즘을 통해 리더로 선출된 컨트롤러는 Active Controller라고 불리며, 그 외에 컨트롤러는 Follower Controller라고 불린다. 
  • 기존 카프카의 __consumer_offsets 토픽이나 트랜잭션 그룹 로그(__transaction_state)같이 메타데이터도 하나의 토픽(__cluster_metadata)을 가지게 되며, 이를 통해 메타데이터를 관리하게 된다. 기존에 주키퍼에 저장되던 모든 메타데이터들이 이 토픽에 저장되게 된다. 메타데이터 토픽의 리더는 당연히 Active Controller가 된다.
  • 쿼럼에서는 주키퍼와 마찬가지로 실행이 유지되기 위해서는 노드의 과반수 이상이 실행되어있어야 한다. 이를 다시 말하자면 3개의 쿼럼 구성에서는 한 번의 장애를 , 5개의 노드 구성에서는 2번의 장애를 극복할 수 있다.

메타데이터 복제 프로세스

KRaft 알고리즘을 통해 리더를 선출하고 리더 컨트롤러가 메타데이터 로그의 리더로 메타데이터를 관리한다는 것을 알았다면 실제 메타데이터가 어떤 과정을 통해 팔로워에게 복제되는지를 알아보면 좋을 것 같다.

메타데이터 저장

만약 메타데이터에 변경 사항이 생긴다면 Active Controller는 관련 변경 내용을 메타데이터 토픽에 저장한다. 좀 더 정확히는 메타데이터 로그에 추가하기 이전에 내구성 확보를 위해 로컬 디스크(Write-ahead Log, WAL)에 먼저 기록하고 fsync를 한 후 메타데이터 토픽에 저장한다.

메타데이터 패치

Follower Controller는 주기적으로 이 메타데이터 로그에 추가된 사항이 없는지 Active Controller에게 Fetch 요청을 보내게 되는데, Active Controller는 이 응답으로 추가된 사항들을 넘겨준다. Follower Controller는 응답받은 데이터를 로컬에 적용한다.

이벤트 /  델타 모델

쿼럼에서는 메타데이터 복제에 이벤트/델타 모델 방식을 사용한다. 특정 메타데이터가 A->B로 변경되었다는 데이터를 넘겨주는 것이 아니라, 어떤 이벤트가 일어났는지를 팔로워에게 전달한다는 것이다. 이벤트/델마 모델을 사용함으로써 과한 정보들이 네트워크들을 통해 송수신되는 것을 방지할 수 있다는 게 장점이 될 것 같다.

예를 들어 브로커 하나가 다운되면서 3만 개의 메타데이터의 변화가 생겼을 때 3만개의 메타데이터를 복제해야하는 것은 큰 작업이다. 하지만 특정 브로커 하나가 다운되었다는 하나의 이벤트만 팔로워에게 넘겨주면 나머지는 팔로워가 자체적으로 3만개의 메타데이터를 변경을 가해주면 된다.

메타데이터 캐시

카프카의 클러스터의 다양한 메타데이터 정보를 빠르게 접근할 수 있게 하기 위해 메모리에 현재 메타데이터 정보를 기록하는데 이를 "메타데이터 캐시"라고 한다. 이를 통해 카프카는 메타데이터 조회를 위해 항상 디스크에 접근하지 않고 빠르게 캐시 된 데이터에 접근할 수 있어 성능이 향상된다. 같은 맥락으로 클라이언트에서 메타데이터를 요구할 때 이 메타데이터 캐시를 이용하여 빠르게 응답을 줄 수 있다.

갱신 시점

팔로워는 Fetch 요청을 통해 리더의 메타데이터 로그를 따라잡는다고 위에서 얘기했는데, 이 Fetch 요청에는 팔로워가 현재 리더 로그의 어느 지점까지 복제 완료했는지를 표현하는 데이터를 포함하게 된다. 이를 통해 Active Controller는 팔로워들이 각각 어느 지점까지 자신의 로그를 따라왔는지를 알 수 있고, 모든 노드가 복제에 성공한 최신 지점까지를 메타데이터 캐시에 적용해도 된다는 명령을 내릴 수 있다.

여기서 주의할 점은 클러스터 내 모든 노드가 복제에 성공한 최신 데이터가 저장된다는 점이다. 예를 들어 A(리더), B, C(팔로워)라는 노드가 클러스터에 참여하고 있다고 가정해 보자. A에는 메타데이터 1,2,3이 저장되어 있고, B가 1,2,3까지 복제에 성공했다. 그런데 C가 아직 1,2까지밖에 복제를 못했다고 했을 때 A, B의 메타데이터 캐시에 1,2,3이 로그가 적용된 메타데이터가 올라가게 되면 클러스터 내의 메타데이터 간의 불일치가 발생하게 된다. 

새로운 클린업 정책 = 스냅샷 정책

만약 메타데이터가 무한정 쌓이게 된다면 여러 가지 문제들이 발생하게 된다. 일단 메타데이터도 토픽으로써 디스크에 저장된다 했으므로 당연히 메타데이터가 계속 쌓이게 되면 "디스크 용량 부족" 문제를 겪을 수 있다. 또한 새로운 노드가 클러스터에 참여하게 되면 현재까지 모든 메타데이터 로그를 복제해야 하므로 "동기화하는 시간이 증가"하는 문제가 있을 수도 있다. 또 현재까지의 모든 로그를 팔로워에게 전달해야 하므로 "리더 역시 리소스를 낭비"하게 된다. 

기존 카프카에서는 이를 위해 토픽에 삭제 정책, 압축 정책 등이 있었으나, 메타데이터가 이벤트/델타 모델을 사용하게 되면서 기존의 클린업 정책들을 사용할 수 없어 스냅샷이라는 새로운 정책이 등장하게 되었다.

특정 시점이 되었을 때 Active Controller는 현재 메모리에 올라가 있는 메타데이터 캐시를 스냅샷 형태로 변환해서 저장한다. 그리고 현시점 기준 이전의 메타데이터 로그를 삭제한다. 이렇게 하면 새로운 노드가 참여하더라도 이전의 모든 메타데이터 로그를 넘겨주는 것이 아니라 스냅샷을 전달해주기만 하면 된다.

반응형

'Programming > Apache Kafka' 카테고리의 다른 글

KRaft 합의 알고리즘  (0) 2024.01.07
카프카 모니터링 - 메트릭  (0) 2023.12.02
Kafka Transaction  (0) 2023.11.18
Exactly Once Semantics  (0) 2023.11.05