왜 Zookeeper 모드에서 KRaft 모드로 변경하는가?
카프카에서는 2.8 버전부터는 zookeeper와 kraft로 쿼럼을 구성할 수 있었으며, 3.3 버전부터 kraft를 중점으로 지원을 하게 되고 3.5 버전부터는 Zookeeper가 사용하지 않는 것을 권고했으며, 2024년 4월 이후에 나올 4.0 버전 이후부터는 아예 Zookeeper는 지원을 안 하게 된다고 나와있다.
그렇다면 왜 주키퍼의 사용을 멈추고 래프트 모드로 교체를 하게 되었을까?
주키퍼의 문제점
1. 두 가지의 프로세스
주키퍼 프로세스와 카프카 프로세스 두 가지의 프로세스로 운영을 하게 되면 두 가지에 시스템에 대해서 학습을 해야 되고 별도의 설정을 해주어야 하기 때문에 번거로움이 있다. 또한, 보안 부분에서도 프로세스 별로 설정을 해주어야 하기 때문에 문제가 생길 수도 있다. 예를 들어 카프카 프로세스의 보안처리를 다해 문제가 없어야 하지만 주키퍼 프로세스에는 보안처리를 하지 않았기 때문에 문제가 발생할 수 있다.
2. 메타데이터의 불일치
컨트롤러가 주키퍼에 메타데이터를 쓰는 작업은 동기적으로 이루어지지만, 브로커 메시지를 보내는 작업과 주키퍼로 업데이트를 받는 과정은 비동기적으로 이루어진다. 그렇기 때문에 브로커, 컨트롤러, 주키퍼 간에 메타데이터 불일치가 발생할 수 있고 추적이 어렵다.
3. 컨트롤러 재시작 시 병목 현상
컨트롤러가 재시작될 때마다 주키퍼로 부터 모든 브로커와 파티션에 대한 메타데이터를 읽어오고 메타데이터를 모든 브로커로 전송한다. 이 문제는 계속 개선을 했지만, 여전히 문제가 되고 있다고 한다. 또한, 파티션과 브로커의 수가 증가할 수 록 컨트롤러의 재시작은 더욱 느려 저 사용자의 입장에서 운영 및 사용 시에 큰 부담으로 작용이 된다.
이러한 문제점들 말고도 여러 문제점들이 있지만, 크게 봤을 때 이문제들이 가장 큰 문제인 것 같다.
그렇다면 KRaft 모드는 어떻게 바뀌게되어 사용하는 걸까?
래프트 기반 컨트롤러 : KRaft
기존에 아키텍처를 변경하여 새로운 컨트롤러에서는 카프카 자체에 사용자가 상태를 이벤트 스트림으로 나타낼 수 있도록 하는 로그 기반 아키텍처를 도입했다. 컨트롤러 노드들이 메타데이터 이벤트 로그를 관리하는 래프트 쿼럼이 되어 클러스터 메타데이터의 변경 내역을 저장한다.
단일 프로세스
이제 카프카 프로세스 하나로 컨트롤러와 브로커의 서버를 관리할 수 있어 이중으로 작업을 해야 하는 부분들이 줄어들었다.
메타데이터 저장 방식의 변경
래프트 알곰리즘을 사용해 컨트롤러 노드들은 외부 시스템에 의존하지 않고 자체적으로 리더를 선출하고 로그 형식으로 메타데이터를 리더 컨트롤러뿐만 아니라 모든 컨트롤러가 데이터 정보를 최신 상태로 가지고 있어 리로드 기간이 필요가 없으며, 메타데이터의 추적도 로그를 통해 가능하게 되고 불일치도 막을 수 있게 되었다.
KRaft 모드 사용법
카프카 설치 경로로 이동하여 해당 명령어들을 실행한다.
클러스터 ID 생성 및 저장 공간 지정
해당 명령어를 이용해서 클러스터 ID를 생성할 수 있다.
bin/kafka-storage.sh random-uuid
bin/windows/kafka-storage.bat random-uuid # winddow
생성된 클러스터 ID를 이용해서 카프카 설정 파일에 지정되어 있는 log.dirs 경로에 메타데이터 파일을 생성한다.
멀티 클러스터를 구성할 경우 서버를 설정할 때마다 서버별로 저장 공간을 지정해야 한다.
bin/kafka-storage.sh format -t [클러스터 ID] -c [카프카 설정 파일]
bin/kafka-storage.sh format -t H649-msTQb2dHnInrVntog -c ./config/kraft/server.properties
bin/kafka-storage.sh format -t H649-msTQb2dHnInrVntog -c ./config/kraft/broker.properties
bin/kafka-storage.sh format -t H649-msTQb2dHnInrVntog -c ./config/kraft/controller.properties
bin/windows/kafka-storage.bat format -t H649-msTQb2dHnInrVntog -c ./config/kraft/server.properties
카프카 설정
브로커 역할을 설정하는 broker.properties, 컨트롤러 역할을 설정하는 controller.properties, 두 역할을 하는 server.properties 파일이 있다.
- process.roles : 해당 인스턴스가 수행하는 역할을 설정, controller, broker로 역할을 설정하고 둘 다 작성 시 두 역할을 모두 다 수행할 수 있다.
- node.id : 인스턴스의 id, 기존의 broker.id를 대체하고 있으며, 같은 클러스터에 속한 인스턴스들은 값이 같을 수 없다. 보통 1부터 시작해 자연수로 늘려서 사용한다.
- controller.quorum.voters : 사용할 컨트롤러 쿼럼을 지정, [컨트롤러의 node.id]@[컨트롤러의 호스트명]:[포트명]을 쉼표로 구분해서 지정한다. 브로커의 기본 포트는 9092이고 컨트롤러의 기본 포트는 9093이다.
- listeners : 기존의 listeners 설정과 같은 역할을 하지만, 컨트롤러 리스너도 설정할 수 있도록 확장되었다.
- listeners=PLAINTEXT://:9092 # 브로커 역할만 하는 경우
- listeners=CONTROLLER://:9093 # 컨트롤러 역할만 하는 경우
- listeners=PLAINTEXT://:9092, listeners= CONTROLLER://:9093 # 브로커, 컨트롤러 두 역할을 하는 경우
- log.dirs : 레코드 로그 파일과 메타데이터 로그 파일을 저장하는 경로, 브로커의 경우 레코드 로그 파일을 저장하고 컨트롤러의 경우 메타데이터 로그 파일을 저장하고 두 역할을 수행하는 경우 두 파일 모드 저장한다.
카프카 실행
bin/kafka-server-start.sh config/kraft/broker.properties
bin/kafka-server-start.sh config/kraft/server.properties
bin/kafka-server-start.sh config/kraft/controller.properties
bin/kafka-server-start.sh -daemon config/kraft/broker.properties # 백그라운드 실행
bin/windows/kafka-server-start.bat config/kraft/server.properties # window
주키퍼가 이제 지원을 하지 않게 되면서 자동적으로 카프카를 사용하려면 래프트 모드를 사용해야겠지만, 사용하고 있던 시스템이 무엇 때문에 교체가 되는지 어떤 점들이 개선되고 발전해 가는지를 알아보고 사용해 보는 게 기술을 이해하는데 좀 더 도움이 될 것 같아 내용을 조금 정리를 해보니 확실히 찾아보는 과정에서 카프카에 대해 이해가 된 것 같다.