카프카 설치하기

uchan·2025년 8월 19일

기존 방식 (Kafka + ZooKeeper)

  • 역할: ZooKeeper는 Kafka 클러스터의 메타데이터(브로커 정보, 토픽/파티션 정보, 컨트롤러 선출 등)를 관리하는 외부 의존성.
  • 구성:
    • ZooKeeper 클러스터(보통 3개 이상) + Kafka 브로커들.
    • Kafka 브로커는 ZooKeeper를 통해 메타데이터를 공유.
  • 장점:
    • 오랫동안 사용되어 안정성과 레퍼런스가 풍부.
  • 단점:
    • Kafka 외에 ZooKeeper 클러스터를 따로 관리해야 해서 복잡성 증가.
    • 브로커, 컨트롤러, 주키퍼 간에 메타데이터 불일치가 발생할 수 있음. (컨트롤러 -> 주키퍼로 메타데이터 쓰는 작업은 동기적으로 이루어지지만 브로커에 메시지가 보내지거나 주키퍼로부터 업데이트 받는 과정은 비동기적으로 이루어짐)
    • 주키퍼는 수평 확장이 불가능하며 오직 리더를 통해서만 쓰기 작업이 이루어지기 때문에 병목현상이 존재한다.

새로운 방식 (Kafka + KRaft)

  • 역할: Kafka 자체에 Raft consensus 프로토콜을 내장해서, 더 이상 ZooKeeper가 필요 없음.
  • 구성:
    • Kafka 브로커 중 일부가 컨트롤러 노드로 동작 → 클러스터 메타데이터 관리.
    • 나머지는 브로커 역할.
  • 장점:
    • 외부 ZooKeeper 제거 → 아키텍처 단순화.
    • 설치와 운영이 쉬움. (주키퍼 학습할 필요 X)
    • 장애 복구, 스케일링 관리 개선.
  • 단점:
    • 오래된 가이드/툴들은 아직 ZooKeeper 기준인 경우 많음.

과거 주키퍼를 이용하여 카프카 서버를 운영하였지만 최근에는 주키퍼를 제거하고 카프카 자체만으로 운영 가능하게끔 KRaft 방식을 권장한다. 따라서 앞으로 실습 및 서비스에 적용할 때는 KRaft 를 사용하자!

핵심 브로커 매개변수

주키퍼에서 KRaft 로 넘어오면서 일부 매개변수가 삭제되고 수정되었다.

  • 제거된 설정
    • zookeeper.connect
    • zookeeper.*
  • 수정된 설정
    • broker.id => node.id로 대체됨
  • 추가된 설정
    • process.roles (브로커 또는 컨트롤러 등 해당 서버의 역할을 설정한다)
    • controller.quorum.voters (기존 zookeeper quorum을 대체하는 controller quorum 으로서 1대 이상 필요하며 주로 3대 혹은 5대 권장한다)

이외 로그, 토픽, 토픽 별 파티션 등 관련 매개변수를 조정할 수 있다.
추가로 파티션 수를 계산할 때는 처리량과 소비자 병렬성(하나의 파티션은 동시에 오직 하나의 컨슈머에서만 처리할 수 있다)을 고려해야한다.

하드웨어 선택하기

디스크

로그 세그먼트를 저장하는 디스크의 처리량은 프로듀서 클라이언트 성능에 큰 영향을 미친다. 따라서 대체로 많은 수의 클라이언트 연결을 받아야한다면 SSD(빠르게 처리)를 사용하고, 쓰기 작업이 거의 없다면 HDD(싸고 더 많은 용량 제공)을 사용하는 것이 좋다.

저장 용량

만약 하루에 1TB 의 트래픽을 받을 것으로 예상되고, 받은 메시지를 1주일간 보존해야한다면 최소 7TB 가 필요하다. 여기에 트래픽 변동이나 증가를 대비한 예비 공간, 저장해야 할 다른 파일도 감안해서 최소 10퍼 가량의 오버레드를 고려해야한다. 카프카를 클러스터로 운영하는 경우 용량이 가득찰 때 브로커를 추가해줌으로써 전체 용량을 증대시킬 수 있다.

메모리

카프카 컨슈머는 보통 프로듀서가 막 추가한 메시지를 바로 뒤에서 쫓아가서 읽어온다. 이러한 상황에서 최적의 작동은 디스크가 아닌 시스템의 페이지 캐시에 저장되어 있는 메시지를 읽어오는 것이다. 따라서 시스템에 페이지 캐시로 사용할 수 있는 메모리를 더 할당해 줌으로써 컨슈머 클라이언트의 성능은 향상된다. 여기서 중요한건 JVM 힙 메모리가 아닌 시스템 페이지 캐시(OS 메모리 캐시)를 적극 활용함으로써 카프카가 운영되는 것이다. 따라서 카프카를 사용하는 환경에서는 오직 카프카만 실행되고 다른 어플리케이션은 실행하지 않는 것을 권장한다.

네트워크

카프카에서는 다수의 컨슈머가 붙어서 처리하기 때문에 유출되는 네트워크 사용량이 많아질 수 있다. 만약 네트워크 인터페이스가 포화상태에 빠질 경우, 클러스터 내부의 복제 작업이 밀려서 클러스터가 취약한 상태로 빠질 수 있다. 이러한 사고를 방지하기 위해 최소 10GB 이상 처리 가능한 네트워크 인터페이스 카드를 사용하는 것을 권장한다.

CPU

네트워크와 디스크 사용량을 최적화하기 위해 클라이언트가 메시지를 압축해서 보내고, 카프카 브로커는 각 메시지의 체크섬 확인 및 오프셋 부여하기 위해 압축을 해제하는 데 CPU 처리가 사용된다. 그러나 앞서 디스크, 메모리 만큼이나 중요하지 않기에 카프카 운영 환경에서 낮은 우선순위로서 고려한다.

AWS 에서 사용하기

  • 지연이 매우 낮아야 할 때는 로컬 SSD 저장소가 장착된 I/O 최적화 인스턴스가 필요 (r 인스턴스)
  • 그게 아니라면 EBS 와 같이 임시 저장소만으로도 충분 (m인스턴스 + EBS)

브로커 개수

카프카 클러스터 내 브로커 개수를 산정할 때는 다음 요소들을 고려한다.

디스크 용량

만약 클러스터가 10TB 를 저장해야하고, 브로커당 2TB 만 저장가능하다면 최소 5대가 필요하다. 여기에 복제기능까지 추가된다면 브로커 수는 배로 필요하다.(복제 팩터가 2라면 최소 10대 필요)

브로커 당 partition replica 용량

10개의 브로커를 가진 클러스터가 있는데 파티션 레프리카의 수는 백만 개(즉, 복제 팩터가 2인 파티션이 50만개 넘는 경우)일 때 분산이 매우 이상적으로 된 상황이라면 각 브로커 당 대략 10만개의 파티션 레플리카를 보유하게 된다. 이는 쓰기, 읽기, 컨트롤러 큐 전체에 병목 현상을 발생시킬 수 있다. 따라서 브로커 당 파티션 레플리카 개수를 14000개, 클러스터 당 100만개 이하로 유지할 것을 권장한다.

CPU 용량

CPU는 대개 주요한 병목 지점이 되지 않는다. 그러나 브로커 하나당 감당할 수 없는 수준으로 사용량이 올라갈 경우에는 확장해야될 수 있다.

네트워크 용량

피크 시간대 단일 브로커에 대해 네트워크 인터페이스 전체 용량의 80퍼를 사용하고 이 데이터를 읽어가는 컨슈머가 두 대 있다고 가정하자. 그럼 최소 2 대 이상의 브로커가 있어야만 피크 시간대 처리량을 받아낼 수 있다. 이와 같이 네트워크 사용량에 따라서 브로커 개수 조절이 필요할 수 있다.

0개의 댓글