본문 바로가기
개발공부 개발새발/etc

Kafka ) 변신의 카프카가 아니라 Apache Kafka 에 관하여

by 휴일이 2024. 6. 13.

Kafka

링크드인에서 개발한 오픈소스 프로젝트. 데이터 운송 매커니즘. 데이터 흐름에 몸을 맡겨보자.

  • 메시징.
  • 활동 추적.
  • 다양한 위치에서 메트릭 수집.
  • 애플리케이션 로그 수집.
  • 최근에는 스트림 처리.
    • 마이크로 서비스 발행/구독…

사용법

소스 시스템과 타겟 시스템 사이에 카프카를 둔다.

이름 예시
소스 시스템 웹사이트 이벤트, 가격 데이터 등 사용자 상호 작용 → 데이터 스트림 생성
타깃 시스템 데이터베이스, 분석 시스템, 이메일 시스템, 감사 시스템
  • 소스 시스템은 카프카에 데이터를 전송한다.
  • 타깃 시스템이 데이터를 받아야할 경우 Apache Kafka 로부터 받는다.

예시

  • 넷플릭스를 보는 동안 Kafka 를 사용해 실시간 추천 사항 적용.
  • Uber 에서 사용자,택시 여행 데이터를 실시간으로 수집하고 수요 계산, 예측. 실시간 요금 계산.
  • LinkedIn 에서는 스팸을 방지하고 사용자 상호 작용을 수집해 실시간으로 더 나은 관계 추천

 

Kafka Topic

Kafka 클러스터 안에 있는 데이터 스트림. 한 클러스터에는 많은 토픽이 있을 수 있다.

  • 데이터 스트림을 뜻한다. 테이블과 비슷하지만 제약 조건이 없다.
  • 원하는 건 모두 Kafka topic 에 전송할 수 있으며 데이터 검증이 없다..!
  • 이름을 통해 토픽을 식별한다.
  • 모든 종류의 메시지 형식을 지원한다. (Json, Avro, txt, binary …)

Data Stream

카프카 토픽 안에 있는 메시지들의 순서

  • 카프카를 데이터 스트리밍 플랫폼이라고 부르는 이유. → 토픽을 통해 데이터 스트림을 만드니까!

Partitions

토픽을 파티션들로 분할할 수 있다. 예시로 하나의 토픽이 100개의 파티션으로 구성될 수 있다.

offset

파티션이 가지는 id

중요 사항

  • 토픽은 immutable 이므로 데이터를 파티션에 기록하면 변경할 수 없다.
    • 삭제 X , 변경 X , 오직 기록만 가능.
  • 데이터는 일정 시간만 유지된다. 기본값은 일주일.
  • 오프셋은 특정한 파티션에만 의미가 있다.
    • 파티션 0의 오프셋3과 파티션 1의 오프셋3은 다르다.
  • 앞의 메시지가 삭제되었어도 그 오프셋을 재사용할 수 없다.
  • 메시지 순서가 한 파티션에서만 보장됨.
    • 각 파티션에는 메시지가 있고, 오프셋 순서로 그걸 읽음.
    • 하지만 다른 파티션에서는 자기꺼 말고 다른 오프셋을 제어할 수 없음.
  • 키를 제공하지 않으면 데이터가 Kafka 토픽으로 전송되면 그 데이터는 임의의 파티션에 할당 됨.
  • 토픽은 원하는 만큼의 파티션을 가질 수 있으나. 토픽에 맞는 적절한 파티션 갯수가 있음.

프로듀서

어느 파티션에 기록할지 결정하며 파티션과 토픽에 데이터를 기록한다.

  • Kafka 가 파티션에 기록하는 것이 아니라, 프로듀서가 기록하며 결정한다.
  • 파티션 복구도 얘가 한다.

메시지 키

프로듀서가 메시지 안에 갖고 있는 메시지 키. 메시지 자체가 데이터를 보유할 수 있음. 그게 메시지 키. (문자 바이너리 뭐든 가능)

  • 키 == null ? → 데이터 라운드 로빈으로 저장 (순서대로)
    • 자동 로드밸런싱
  • 동일한 키를 공유하는 모든 메시지들은 해싱 전략때문에 같은 파티션에 등록 됨.

메시지 구성

  • 밸류(메시지 값)
  • 메시지 압축 매커니즘 (메시지 압축이 가능하므로 압축을 원한다면 추가)
  • 헤더 (키, 값 쌍을 가진 리스트)
  • 파티션, 오프셋
  • 타임스탬프

이렇게 구성된 메시지가 Kafka 로 전송되어 저장 됨.

Kafka Message Serializer

우리 메시지를 직렬화(데이터→바이트) → 프로듀서로부터 입력값으로 직렬로 된 바이트만을 받고 출력값으로 바이트 값을 컨슈머에게 전송한다.

  • 키, 값으로 이루어진 객체가 있으면 KeySerializer 를 통해 직렬화함(to Binary)
  • 카프카 파티셔닝
    • 레코드를 받아서 어느 파티션에 저장할지 지정.
    • 키 해싱 프로세스는 파티션에 대한 키 매핑을 결정하는 데 사용.
    • 기본으로 murmur2 알고리즘으로 해싱된다.
      • 키의 바이트를 확인하고 알고리즘을 적용해서 타깃 파티션이 어떤 파티션인지 알아냄.

Consumers

토픽에서 데이터를 읽기 위해 사용함.

  • 카프카 브로커, 서버에 요청을 보내고 응답을 받기 위한 → pull 모델 구현
  • 데이터를 컨슈머에게 푸싱하는 건 Kafka 브로커가 아니라 → 풀 모델.
  • 파티션에서 데이터를 읽는 컨슈머는 자동으로 어떤 브로커에서 읽을지 알게 됨.
  • 브로커가 고장나면 컨슈머가 복구법도 알음.
  • 파티션 데이터는 순서대로 읽힘 : 정순
  • 파티션으로부터 데이터를 읽고 변환한다.

Deserializer

파티션으로부터 데이터를 읽어와 역직렬화 한다.

  • binary → objects/data
  • Kafka 에 포함되어있고 컨슈머가 사용하여 역직렬화한다.
  • 프로듀서에는 Serializer, 컨슈머는 Deserializer 가 있음.
  • 컨슈머는 키 값 포맷을 미리 알고있어야 함. → 토픽이 생성될 때 프로듀서가 전송하는 데이터 타입을 변경하지 말아야 함. → 안 그럼 컨슈머가 아는 타입과 달라서 역직렬화 못함.
    • 토픽 자료형 변경하고 싶다면 새 토픽을 만들어야 함.

컨슈머 그룹

말 그대로 컨슈머 그룹, 애플리케이션 안에 컨슈머들이 그룹 형태로 데이터를 읽을 것이다.

  • 이렇게 한 컨슈머 그룹에 여러 컨슈머들이 있고 각자 맡은 파티션에서 데이터를 읽어온다.
  • 그룹이 토픽 전체를 읽어온다.

만약 파티션 갯수보다 컨슈머가 많다면?

  • 컨슈머가 파티션 하나씩 맡고 남은 컨슈머는 비활성화(stand-by) 상태가 됨.

하나의 토픽에 다중 컨슈머 그룹이 있다면?

  • 이렇게 사이좋게 나눠서 읽는다.

이렇게 다수의 컨슈머 그룹이 있는 이유?

  • 서비스당 하나의 컨슈머 그룹을 갖는데, 데이터 스트림 하나에 여러 서비스가 있다면 (예: 위치서비스, 알림서비스) 컨슈머 그룹이 여러 개 있을 수도 있다.

컨슈머 오프셋

컨슈머 그룹 내에서 지정할 수 있음. 컨슈머 그룹이 읽고 있는 오프셋을 저장한다.

  • Kafka 토픽 내부에서 __consumer_offsets 라는 이름으로 가지고있는다.
  • 컨슈머는 오프셋을 커밋하고 읽는다.
    • 데이터 처리를 컨슈머가 완료하면 종종 오프셋을 커밋하고 내부 오프셋 토픽에 기록함.
    • 어디까지 성공적으로 읽었는지 브로커에게 알려줄 수 있음.
    • 만약 컨슈머가 죽어도 읽었던 곳에서부터 다시 읽을 수 있다!

커밋 설정

  • 세 가지 모드가 있음.

At least once (default)

  • 최소 한 번은 자동으로 커밋됨.
  • 처리가 잘못되면 메시지를 다시 읽을 수 있음. (메시지 읽기 반복 가능)
    • 멱등성인지 확인해야함 → 여러 번 반복해도 프로그램이 달라지지 않는가?

At most once

  • 메시지를 받자마자 오프셋이 커밋됨
  • 잘못 읽어도 다시 못읽음 → 읽기 전에 커밋해버림.

Exactly once

  • 반드시 한번만 읽음.
  • 카프카 내에서 처리할 때는 트랜잭션 api 사용 가능. (kafka 스트림 api)
  • 카프카 외부에서 처리할 때는 멱등 컨슈머를 사용해야 함.

→ 오프셋을 커밋하는 방법이나 시기에 모드를 정해서 사용하기.

브로커

데이터를 받고 보내는 서버. Kafka 클러스터는 다수의 브로커들로 구성되어 있다.

  • ID (정수) 로 식별
    • 브로커 101 , 브로커 102, 브로커 103 …
  • 각각의 브로커에는 특정한 토픽 파티션만 담긴다.
  • Kafka 브로커에 연결하면 클라이언트,프로듀서,컨슈머가 전체 Kafka 클러스터에 자동으로 연결됨.
    • 브로커 하나에만 연결하면
    • 그 브로커가 모든 브로커(부트스트랩 서버) 정보를 줌.

토픽 복제

브로커가 다운되어도 다른 브로커에 데이터 사본이 있어서 그걸 주고 받을 수 있다. 로드밸런서 개념이다.

  • 복제를 하더라도 리더 브로커가 있으며, 기본 설정으로는 리더브로커에게만 데이터를 주고 또 요청한다.

컨슈머 레플리카 페칭

컨슈머가 가장 가까운 레플리카에서 읽게 해주는 기능. (도 있다.)

프로듀서 확인

프로듀서는 데이터 쓰기를 확인받을 수 있다. 세 가지 셋팅이 있음.

 

acks 설명 데이터 유실 유무
0 프로듀서가 확인을 기다리거나 요청하지 않음. 유실 가능.
1 프로듀서가 파티션의 리더 브로커가 확인하기를 기다림. 데이터 유실 제한.
all 모든 레플리카 리더가 쓰기를 확인하라고 요청. 데이터 유실 없음.

토픽 내구성

  • 만일 복제 계수가 3인 토픽이 있다면 2개의 브로커가 손실나도 데이터를 보존할 수 있다.
  • 복제계수 n 개를 선택한다면, 최대 n-1 개의 브로커를 잃어도 데이터 사본이 클러스터 어딘가에는 존재한다.

주키퍼

브로커들을 관리하는 소프트웨어.

  • 브로커가 다운될 때마다 새로운 리더를 선출하는 걸 돕고
  • 변경 사항이 있으면 브로커들에게 알림을 전송해줌. → 브로커 다운, 토픽 삭제…
  • 원래는 카프카를 주키퍼 없이는 사용할 수 없었음.. 그러나 Kafka 3.x 부터는 주키퍼 없어도 실행할 수 있음.

정보

  • 주키퍼는 홀 수로 작동함.
  • 하나는 리더, 나머지는 팔로워로 사용. → 하나는 쓰기, 나머지는 읽기
  • 오래된 카프카 버전에서는 컨슈머를 이용해 오프셋을 주키퍼에 저장했었다.
    • 하지만 지금은 오프셋을 내부 토픽에 저장함!

사용 여부

  • 브로커를 관리한다면, 카프카 4.0 전까지는 주키퍼 없이 카프카 사용 불가.
  • 그냥 최신 카프카를 사용하려면 주키퍼 사용 ㄴㄴ 하세용~~

Kafka KRaft 모드

카프카가 주키퍼에 대한 의존성을 제거하려고 노력했고 대신 이 모드를 사용하라고 하네요~.

주키퍼와 차이

  • 주키퍼는 리더가 있고 나머지는 팔로워
    • Kafka 브로커들이 있고 그 중에 하나가 리더가 됨
  • KRaft 가 성능이 더 좋다.
    • 제어 셧다운 시간 우수
    • 무제어 셧다운 후의 복구 시간 우수
  •  
728x90