Notepad

카프카 기본 개념과 구조

책을 읽고 정리를 위해 메모한 내용에 대해 작성했습니다.

카프카 기초 다지기

카프카를 구성하는 주요 요소

  • 주키퍼: 카프카의 메타데이터 관리 및 브로커의 정상상태 점검을 담당
  • 카프카 또는 카프카 클러스터: 여러 대의 브로커를 구성한 클러스터를 의미
  • 브로커: 카프카 애플리케이션이 설치된 서버 또는 노드
  • 프로듀서: 카프카로 메시지를 보내는 역할을 하는 클라이언트를 총칭
  • 컨슈머: 카프카에서 메시지를 꺼내가는 역할을 하는 클라이언트를 총칭
  • 토픽: 카프카는 메시지 피드들을 토픽으로 구분하고, 각 토픽의 이름은 카프카 내에서 고유함
  • 파티션: 병렬 처리 및 고성능을 얻기 위해 하나의 토픽을 여러 개로 나눈 것
  • 세그먼트: 프로듀서가 전송한 실제 메시지가 브로커의 로컬 디스크에 저장되는 파일
  • 메시지 또는 레코드: 프로듀서가 브로커로 전송하거나 컨슈머가 읽어가는 데이터 조각

리플리케이션

  • 리플리케이션이란 각 메시지들을 여러 개로 복제해서 카프카 클러스터 내 브로커들에 분산시키는 동작을 의미
  • 리플리케이션 동작 덕분에 하의 브로커가 종료되더라도 하나의 브로커 종료되더라도 카프카는 안정성을 유지할 수 있음
  • replication-factor : 카프카 내 몇 개의 리플리케이션을 유지하겠다는 의미의 옵션
    • replication-factor 가 1이라면 리플리케이션이 1개, 3이라면 원본을 포함한 리플리케이션이 총 3개라는 뜻
    • peter-overview01 토픽을 리플리케이션 팩터 수 3으로 설정한 후 브로커에 배치된 상태
      peter-kafka01
      peter-overview01
      peter-kafka02
      peter-overview01
      peter-kafka03
      peter-overview01
  • 실제로는 카프카에서 토픽이 리플리케이션되는 것이 아닌 토픽의 파티션이 리플리케이션되는 것
  • 안정성을 목적으로 모든 토픽에 대해 각 3개의 리플리케이션으로 설정할 수 있음
  • 리플리케이션 팩터 수가 커지면 안정성은 높아지지만 그만큼 브로커 리소스를 많이 사용하게 됨
  • 복제에 대한 오버헤드를 줄여서 최대한 브로커를 효율적으로 사용하는 것을 권장
  • 토픽 생성 시 다음과 같이 기준을 세워두고 리플리케이션 팩터 수를 설정해 사용한다면 좀 더 효율적으로 카프카를 운영할 수 있음
    • 개발이나 테스트 환경: 리플리케이션 팩터 수를 1로 설정
    • 운영 환경(로그성 메시지로서 약간의 유실 허용): 리플리케이션 팩터 수를 2로 설정
    • 운영 환경(유실 허용하지 않음): 리플리케이션 팩터 수를 3으로 설정
  • 안정성을 높이기 위해 리플리케이션 팩터 수를 늘릴 수도 있지만 저자의 경험 상 리플리케이션 팩터 수가 3일 경우에 충분히 메시지 안정성도 보장하고 적절한 디스크 공간을 사용할 수 있다고 함

파티션

  • 파티션이란 하나의 토픽이 한 번에 처리할 수 있는 한계를 높이기 위해 토픽 하나를 여러 개로 나눠 병렬 처리가 가능하게 만든 것
  • 하나를 여러 개로 나누면 분산 처리도 가능하며 이렇게 나뉜 파티션 수만큼 컨슈머를 연결할 수 있음
  • 토픽과 파티션의 관계
      브로커  
    토픽1 토픽2 토픽3
    토픽1
    파티션0
        토픽3
    파티션0 파티션1 파티션2
    • 토픽1: --partition 1 옵션으로 파티션 1개를 가지는 토픽
    • 토픽3: --partition 3 옵션으로 파티션 3개를 가지는 토픽
  • 파티션 번호는 0부터 시작

파티션 수

  • 파티션 수도 토픽을 생성할 때 옵션으로 설정하게 됨
  • 파티션 수를 정하는 기준은 다소 모호한 경우가 많음
  • 파티션 수는 각 메시지 크기나 초당 메시지 건수 등에 따라 달라지므로 정확하게 예측하기가 어려움
  • 파티션 수는 초기 생성 후 언제든지 늘릴 수 있지만, 반대로 한번 늘린 파티션 수는 절대로 줄일 수 없음
  • 초기에는 토픽 생성 시 파티션 수를 작게 2 또는 4 정도로 생성한 후 메시지 처리량이나 컨슈머의 LAG 등을 모니터링하면서 조금씩 늘려가는 방법이 가장 좋음
    • LAG: 프로듀서가 보낸 메시지 수(카프카에 남아 있는 메시지 수) - 컨슈머가 가져간 메시지 수

세그먼트

  • 프로듀서에 의해 브로커로 전송된 메시지는 토픽의 파티션에 저장되며, 각 메시지들은 세그먼트라는 로그 파일의 형태로 브로커의 로컬 디스크에 저장됨
  • 파티션과 세그먼트의 관계
        토픽3
    파티션0 파티션1 파티션2
    파티션0  
    세그먼트0 세그먼트1
        파티션2
    세그먼트0 세그먼트1 세그먼트2
  • 각 파티션마다 N개의 세그먼트 로그 파일들이 존재
  • 로그 파일 예
// 1. 로그 파일 위치로 이동
cd /data/kafka-logs/

// 2. 파일 목록 확인
ls

// 3. 0번 파티션 디렉토리로 이동
cd peter-overview01-0

// 4. 파일 목록 확인
ls
  • 토픽, 파티션, 세그먼트의 관계도
    • 프로듀서 -> 카프카 -> 컨슈머
      • 카프카 -> 토픽 -> 파티션 -> 세그먼트:00.log
  • 프로듀서는 카프카의 peter-overview01 토픽으로 메시지 전송
  • peter-overview01 토픽은 파티션이 하나뿐이므로, 프로듀서로부터 받은 메시지를 파티션0의 세그먼트 로그 파일에 저장
  • 브로커의 세그먼트 로그 파일에 저장된 메시지는 컨슈머가 읽어갈 수 있음
  • 컨슈머는 peter-overview01 토픽을 컨슘해서 해당 토픽 내 파티션0의 세그먼트 로그 파일에서 메시지를 가져옴

카프카의 핵심 개념

  • 카프카의 높은 처리량, 빠른 응답 속도, 안정성 때문에 많이 도입되고 있음
  • 카프카가 높은 처리량과 안정성을 지니게 된 특성들을 하나씩 살펴보며 카프카를 좀 더 깊이 설명

분산 시스템

  • 분산 시스템은 높은 성능을 목표로 하며 하나의 서버 또는 노드 등에 장애가 발생할 때 다른 서버 노드 또는 노드가 대신 처리하므로 장애 대응이 탁월하며, 부하가 높은 경우에는 시스템 확장이 용이함
  • 카프카도 분산 시스템으로 최초 구성한 클러스터의 리소스가 한계치에 도달해 더욱 높은 메시지 처리량이 필요한 경우, 브로커를 추가하는 방식으로 확장이 가능함
  • 카프카에서 브로커는 온라인 상태에서 매우 간단하게 추가할 수 있음
  • 최초에는 하나의 카프카 클러스터가 총 3대의 브로커로 운영 중이어도, 서비스가 폭발적으로 증가할 경우 나중엔 총 30대 또는 50대 그 이상의 브로커 수로 확장할 수 있음

페이지 캐시

  • 높은 처리량을 얻기 위해 몇 가지 추가한 기능 중 하나로 페이지 캐시가 사용됨
  • OS의 페이지 캐시를 활용하는 방식으로 설계되어 있음
  • 페이지 캐시는 직접 디스크에 읽고 쓰는 대신 물리 메모리 중 애플리케이션이 사용하지 않는 일부 잔여 메모리를 활용하여 디스크 I/O에 대한 접근이 줄어들므로 성능을 높임
  • 카프카가 직접 디스크에서 읽고 쓰기를 하지 않고 페이지 캐시를 통해 읽고 쓰기를 한다고 이해

배치 전송 처리

  • 카프카가 프로듀서, 컨슈머 클라이언트들과 서로 통신하며 수많은 메시지를 주고받는데 이때 발생하는 수많은 통신을 묶어서 처리하여 단건으로 통신할 때에 비해 네트워크 오버헤드를 줄일 수 있을 뿐만 아니라 장기적으로는 더욱 빠르고 효율적으로 처리할 수 있음
  • 카프카에서는 지연 없이 실시간으로 처리되어야 하는 작업이 아니라면 배치 전송을 권장

압축 전송

  • 카프카는 메시지 전송 시 좀 더 성능이 높은 압축 전송을 사용하는 것을 권장
  • 카프카에서 지원하는 압축 타입
    • gzip, snappy, lz4, zstd 등
  • 배치 전송과 결함해 사용한다면 네트워크 대역폭이나 회선 비용 등을 줄이는데 높은 효과를 얻을 수 있음
    • 파일 하나를 압축하는 것보다 비슷한 파일 10개, 혹은 20개를 압축하는 쪽의 압축 효율이 더 좋음
  • 일반적인 압축 권장
    • 높은 압축률이 필요한 경우라면 gzip이나 zstd를 권장
    • 빠른 응답 속도가 필요하다면 lz4나 snappy를 권장
  • 메시지 형식이나 크기에 따라 또 다른 결과를 나타낼 수 있으니 실제로 메시지를 전송해보면서 압축 타입별로 직접 테스트를 해보고 결정하는 것이 가장 좋음

토픽, 파티션, 오프셋

  • 토픽이라는 곳에서 데이터 저장
  • 이메일 주소 정도의 개념으로 이해하면 접근하기 쉬움
  • 토픽은 병렬 처리를 위해 여러 개의 파티션이라는 단위로 다시 나뉨
  • 파티셔닝을 통해 단 하나의 토픽이라도 높은 처리량을 수행할 수 있음
  • 파티션의 메시지가 저장되는 위치를 오프셋이라고 부르며, 오프셋은 순차적으로 증가하는 숫자(64비트 정수) 형태로 되어 있음
  • 각 파티션에서의 오프셋은 고유한 숫자로, 카프카에서는 오프셋을 통해 메시지의 순서를 보장하고 컨슈머에서는 마지막까지 읽은 위치를 알 수 있음

고가용성 보장

  • 카프카는 분산 시스템이기 때문에 하나의 서버나 노드가 다운되어도 다른 서버 또는 노드가 장애가 발생한 서버의 역할을 대신해 안정적인 서비스가 가능함
  • 이러한 고가용성을 보장하기 위해 리플리케이션 기능을 제공함
  • 카프카에서의 리플리케이션
    • 토픽 자체를 복제하는 것이 아닌 토픽의 파티션을 복제하는 것
    • 토픽을 생성할 때 옵션으로 리플리케이션 팩터 수를 지정할 수 있으며, 이 숫자에 따라 리플리케이션들이 존재
    • 원본과 리플리케이션을 구분하기 위해 리더와 팔로워라고 부름
    • 리더는 하나이며, 리플리케이션 팩터 수에 따라 팔로워 수가 증가
    • 팔로워 수가 늘면 안정적이고 좋을 것 같지만 디스크 공간도 소비되므로 이상적인 리플리케이션 팩터 수를 유지해야 함
    • 일반적으로 권장하는 리플리케이션 팩터 수는 3으로 구성하는 것을 권장

주키퍼의 의존성

  • 주키퍼는 다양한 분산 애플리케이션에서 코디네이터 역할을 하는 애플리케이션으로 사용되고 있음
  • 주키퍼는 여러 대의 서버를 앙상블(클러스터)로 구성하고, 살아 있는 노드 수가 과반수 이상 유지된다면 지속적인 서비스가 가능한 구조
  • 주키퍼는 반드시 홀수로 구성해야 함
  • 지노드(znode)를 이용해 카프카의 메타 정보가 주키퍼에 기록되며, 주키퍼는 이러한 지노드를 이용해 브로커의 노드 관리, 토픽 관리, 컨트롤러 관리 등 매우 중요한 역할을 하고 있음
  • 최근 들어 카프카가 점점 성장하면서 주키퍼 성능의 한계가 드러나기 시작하여 주키퍼의 한계에서 벗어나고자 카프카에서 주키퍼에 대한 의존성을 제거하려고 진행 중이며 주키퍼가 제거된 카프카 버전이 릴리스 예정
  • 카프카의 중요한 메타데이터를 저장하고 각 브로커를 관리하는 중요한 역할을 하는 것이 주키퍼

프로듀서의 기본 동작과 예제 맛보기

(추가 예정)

컨슈머의 기본 동작과 예제 맛보기

(추가 예정)

 

참고 서적

  • 실전 카프카 개발부터 운영까지(고승범, 책만)
profile

Notepad

@Apio

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!