카프카란?

GwanMtCat·2023년 10월 10일
0

아파치 소프트웨어 재단이 스칼라로 개발한 오픈소스 메시지 브로커 프로젝트
여러 대의 분산 서버에서 대량의 데이터를 처리하는 분산 메시징 시스템

실시간 데이터를 높은 처리량과 임의 타이밍에 데이터를 읽어 다양한 제품과 시스템에 쉽게 연동하는데에 초점을 둔다.

큐잉 모델에서 여러 컨슈머가 분산 처리로 메시지를 소비하는 모델과
pub/sub 메시징 모델에서 여러 Subscriber에 동일한 메시지를 전달하고, 토픽 기반으로 전달 내용을 변경하는 모델로 되어 있다.

카프카는 메시지 디스크에 저장함으로써 영속화를 보장하고, 그럼에도 불구하고 높은 처리량을 제공하는 특징이 있다.


카프카 기초

  • 브로커 (Broker)

    • 카프카 클라이언트와 데이터를 주고받기 위해 사용되는 주체, 데이터를 분산 저장하여 장애가 발생하더라도 안전하게 사용할 수 있도록 한다.
    • 브로커 서버를 여러대로 묶어, 클러스터로 운영할 수 있다.
    • 카프카 클러스터로 묶인 브로커들은 프로듀서가 보낸 데이터를 안전하게 분산 저장하고 복제하는 역할을 수행한다.
  • 토픽 (Topic)

    • 카프카에서 데이터를 구분하기 위해 사용하는 단위
    • 카프카 클러스터의 브로커에서 데이터를 관리할 때 기준이 되는 개념
    • 토픽은 1개 이상은 파티션을 소유 한다.
    • 파티션에는 프로듀서가 보낸 데이터들이 들어가 저장된다.
  • 파티션 (Partition)

    • 하나의 토픽이 한 번에 처리할 수 있는 한계를 높이기 위해, 토픽 하나를 여러 개로 나눠 병렬 처리가 가능하게 만든 것
    • 파티션 수 만큼 컨슈머를 연결할 수 있는 특징이 있다.
    • 파티션 번호는 0번 부터 시작한다.
    • 파티션 수는 초기 생성 후, 언제든지 늘릴 수 있지만, 반대로 줄일 수는 없다는 점을 명심해야 한다. (초기에는 작게 생성 추천)
    • 컨슈머의 LAG (프로듀서 보낸 메시지 수 - 콘슈머가 가져간 메시지 수) 를 모니터링하여 조금씩 늘려가는 방법을 택해야한다.
    • 파티션에서는 오프셋을 통해 메시지의 순서를 보장하고, 컨슈머에서는 마지막까지 읽은 위치를 알 수 있다.
    • 카프카에서는 컨슈머가 데이터를 가져가더라도 삭제하지 않아 컨슈머 그룹들이 토픽의 데이터를 여러 번 가져갈 수 있다.
  • 리플리케이션 (Replication)

    • 각 메시지들을 여러 개로 복제해서 카프카 클러스터 내 브로커들에 분산시키는 동작을 의미
    • 이러한 리플리케이션 동작 덕분에 하나의 브로커가 종료되더라도 카프카는 안정성을 유지 가능
    • 카프카에서 토픽이 리플리케이션되는 것이 아니라, 토픽의 파티션이 리플리케이션 됨
    • 리플리케이션 팩터 수가 커지면 안정성 높아지나, 그만큼 브로커 리소스를 많이 사용하게 되므로 복제에 대한 오버헤드를 줄여 최대한 브로커를 효율적으로 사용해야 한다.
    • 테스트나 개발엔 1, 운영 환경엔 2, 유실 허용하지 않을 경우 3
  • 세그먼트 (Segment)

    • 프로듀서에 의해 브로커로 전송된 메시지가 토픽의 파티션에 저장되며, 각 메시지들은 세그먼트라는 로그 파일의 형태로 브로커의 로컬 디스크에 저장된다.
    • 각 파티션마다 N개의 세그먼트 로그 파일들이 존재한다.

카프카 특징

  • 분산 시스템
    • 카프카도 분산 시스템으로 최초 구성한 클러스터의 리소스가 한계치에 도달하여 더욱 높은 메시지 처리량이 필요한 경우, 브로커를 추가하는 방식으로 확장 가능하다.
  • 캐시 시스템
    • 높은 처리량을 얻기 위한 기능 중 하나로 페이지 캐시를 이용한다.
  • 배치 전송 처리
    • 단건을 통신할 때에 비해 네트워크 오버헤드를 중, 장기적으로는 더욱 빠르고 효율적으로 처리 가능하다.
  • 압축 전송
    • 메시지 전송 시, 좀 더 성능이 높은 gzip, snappy, lz4, zstd 등에 압축 타입을 권장하며 이를 통해 대역폭과 회선 비용을 줄일 수 있다.
  • 고가용성 보장

    • 리플리케이션 기능을 통해 토픽의 파티션을 복제하고 이를 구분하기 위해 리더와 팔로워라고 지칭한다. 리더는 1을 유지한채 팔로워 수만 증가한다

      • 리더는 프로듀서, 컨슈머로 부터 오는 모든 읽기와 쓰기 요청을 처리
      • 팔로워는 가만히 있는 것이 아니라 오직 리더로부터 리플리케이션하고 이슈가 있을 상황을 대비함
      • 리플리케이션 팩터가 3이라면 (리더 1, 팔로워 2), 4라면 (리더 1, 팔로워3)
      • 리플리케이션 중 리더가 하나가 선정되며 모든 읽기와 쓰기는 그 리더를 통해서만 가능하다, 프로듀서는 모든 리플리케이션에 메시지를 보내는 것이 아니라, 리더에게만 메시지를 보내며 컨슈머도 오직 리더로부터 메시지를 가져온다.
    • 팔로워 수가 많다고 안정적이고 좋을 거라 생각할 수 있지만, 그만큼 브로커의 디스크 공간도 소비되므로 이상적인 리플리케이션 팩터 수를 유지해야한다.

  • 주키퍼(zookeeper)

    • 카프카의 중요한 메타데이터를 저장하고, 각 브로커를 관리하는 중요한 역할을 한다.
    • 현재에는 제거된 버전이 릴리즈 되어 있다.

프로듀서 디자인 및 동작

위의 ProducerRecord라고 표시된 부분은 카프카로 전송하기 위한 실제 데이터
토픽, 파티션, 키, 밸류로 구성이 된다.
토픽과 밸류는 필수값이고, 특정 파티션을 지정하기 위한 파티션과 그 레코드들을 정렬하기 위한 레코드의 키는 필수값이 아닌 선택사항이다.

Send() 를 통해 시리얼라이저, 파티셔너를 거치게 된다.
만약 프로듀서 레코드의 선택사항인 파티션을 지정했다면, 파티셔너는 아무 동작도 하지 않고 지정된 파티션으로 레코드를 전달한다.

파티션을 지정하지 않은 경우 키를 가지고, 파티션을 선택해 레코드를 전달하는데 기본적으로 라운드 로빈 방식으로 동작한다.

프로듀서 내부에서는 레코드들을 파티션별로 잠시 모아 두는데 그 이유는 카프카로 전송하기 전에 배치 전송을 하기 위함이다.
전송이 실패하면 재시도 동작이 이뤄지고, 지정된 횟수만큼의 재시도가 실패하면 최종 시패를 전달하며, 전송이 성공하면 메타데이터를 리턴하게 된다.


컨슈머 동작

프로듀서가 카프카의 토픽으로 메시지를 전송하면 해당 메시지들은 브로커들의 로컬 디스크에 저장된다.

그리고 컨슈머를 이용해 토픽에 저장된 메시지를 가져올 수 있다.

컨슈머 그룹은 하나 이상의 컨슈머들이 모여 있는 그룹을 의미, 컨슈머는 반드시 컨슈머 그룹에 속하게 된다.
컨슈머 그룹은 각 파티션의 리더에게 카프카의 토픽에 저장된 메시지를 메시지를 가져오기 위한 요청을 보낸다.

이때 파티션 수와 컨슈머의 수(하나의 컨슈머 그룹안에 있는 컨슈머 수)가 일대일로 매핑되는것이 이상적이다. (토픽의 파티션과 1대1로 매핑되어 메시지를 가져오게 된다.)

파티션 수와 컨슈머의 수를 반드시 일대일로 매핑해야 하는 것은 아니지만 파티션 수보다 컨슈머가 수가 많게 구현하는 것은 바람직한 구성이 아닌다.
컨슈머 수가 파티션 수보다 많다고해서 더 빠르게 토픽의 메시지를 가져오거나 처리량이 높아지는 것이 아니라 대기상태로만 존재하기 때문이다.

토픽의의 파티션은 그 컨슈머 그룹과 1:n 매칭. 즉, 자신이 읽고 있는 파티션에는 같은 그룹내 다른 컨슈머가 읽을 수 없다.

액티브/스탠바이 개념으로 추가 컨슈머가 더 있으면 좋을 것이라고도 생각할 수 있으나, 컨슈머 그룹내에서 리밸런싱 동작을 통해 장애가 발생한 컨슈머의 역할을 동일한 그룹에 있는 다른 컨슈머가 그 역할을 대신 수행하므로 굳이 할당하지 않아도 된다.

컨슈메에서 메시지를 가져오는 방법은 총 3가지가 있다.

  • 오토 커밋
    • 기본값, 오프셋을 주기적으로 커밋하여 관리자가 오프셋을 관리하지 않아도 된다.
    • 컨슈머 종료 등이 빈번히 일어나면 일부 메시지를 못 가져오거나, 중복으로 가져오는 경우가 있다.
    • 하지만 카프카가 굉장히 안정적으로 잘 동작하고, 컨슈머 역시 한번 구동하고 나면 자주 변경되거나 종료되는 현상이 없으므로 오토 커밋을 사용하는 경우가 많다.
  • 동기 가져오기
    • 오토커밋과 달리 poll()로 메시지를 가져온 후에 처리까지 완료하고 현재의 오프셋을 커밋한다.
    • 가져오는 속도는 느리지만, 메시지 손실은 거의 발생하지 않는다.
    • 메시지가 손실되면 안 되는 중요한 처리 작업들은 동기 방식으로 진행하는 것이 권장되나 메시지 중복 이슈는 피할 수 없다.
  • 비동기 가져오기
    • 동기 가져오기와 달리 오프셋 커밋을 실패하더라도 재시도 하지 않고, 마지막의 비동키 커밋만 성공한다면 안정적으로 오프셋을 커밋한다.

컨슈머들은 하나의 컨슈머 그룹 안에 속해 있으며, 그룹 내의 컨슈머들은 서로의 정보를 공유하고, 한 컨슈머에 문제가 생겼다면, 다른 컨슈머가 그 컨슈머를 대신하여 토픽의 파티션을 컨슘한다.


참조한 책 및 사이트

실전 아파치 카프카
실전 카프카 개발부터 운영까지
https://team-platform.tistory.com/32

0개의 댓글