Kafka

1. MSA와 Apache Kafka

초코chip 2024. 10. 19. 21:39

MSA

개요

  • 하나의 대규모 모놀리식 애플리케이션보다 여러 개의 작은 애플리케이션으로 시스템을 구축하는 방식
  • 각 마이크로서비스는 특정 작업을 담당하며, 다른 것에 의존하지 않고 독립적으로 배포되도록 설계된 매우 작은 응용 프로그램

특징

  • 작고 느슨하게 결합된 애플리케이션 -> 필요한 경우 수평으로 쉽게 확장 가능
    • 예를 들어 필요한 경우 동일한 MSA 인스턴스를 10개 더 시작 할 수 있어야함 -> 이거는 모두 그룹으로 작동
  • 스프링 프레임워크는 MSA 구축을 위한 다양한 기능을 제공

 

vs 모놀로식

 

  모놀로식 MSA
변경사항 발생 전체 시스템의 재빌드 요구 변경된 서비스만 독립적으로 배포
DB구조 하나의 DB에 모든 데이터 저장
(사용자, 상품, 주문...)
각 서비스마다 별도의 DB를 사용
-> 서비스간 DB 접근이 불가
-> 서비스간 통신 필요

 

 

MSA간 통신

HTTP 요청/응답 방식

  • MSA 서비스간 HTTP 요청/응답 방식으로 소통 가능
  • 그러나 HTTP 방식은 한 서비스에서 여러 서비스에 동시에 메시지를 전달해야할 때 몇가지 문제가 존재
    • 새로운 서비스가 생길 때마다 기존 서비스에 새로운 통신 로직을 추가
    • 서비스 중 하나에 문제가 생긴다면, 계속 그 부분에서 불필요한 패킷 손실 발생하고, 해당 이벤트를 다시 볼 수 없음
  • 즉, HTTP 방식은 여러 MSA에게 메세지를 동시에 전달해야할때 너무 비효율적 -> 이벤트 기반 아키텍처로 가자!

 

이벤트 중심 통신 방식

 

  • 이벤트를 생성하는 서비스(게시자, Producer)와 이벤트를 처리하는 서비스(구독자, Consumer)간의 느슨한 결합을 통해 발생
  • 게시자는 특정 이벤트가 발생했음을 알리기 위해 이를 중앙의 이벤트 저장소(토픽 등)에 게시(publish)하며,
  • 구독자는 해당 이벤트를 저장소에서 구독(subscribe)하여 가져와 처리하는 방식

 

특징

  • 게시자는 구독자가 몇명이고, 몇 명이 이벤트를 성공적으로 처리했는지 알 수 없음
  • 구독자는 게시자에게 직접 응답을 다시 보내지 않음
  • 구독자 중 하나가 다운되도, 다시 복구후 해당 이벤트를 받아와 처리 가능 -> 엄청난 장점!

 

Apache Kafka를 사용하면 MSA 간의 통신을 이벤트 중심으로 전환 가능! 

 

Apache Kafka

  • 대규모 데이터 수집, 처리, 저장 및 통합을 위한 분산 이벤트 스트리밍 플랫폼

주요 구성 요소

  • 생산자(Producer): 이벤트를 생성하여 브로커에게 전달
  • 브로커(Broker): 생산자로부터 게시된 이벤트를 수락하고 저장하는 서버로, 하드 디스크에 데이터를 저장
    • 고가용성을 위해 여러 개의 브로커와 파티션 복제를 사용
  • 토픽(Topic): 브로커 내에서 이벤트가 저장되는 공간
    • 여러 파티션으로 나뉘어 짐
    • 파티션은 이벤트를 병렬로 처리할 수 있도록 분할된 저장 공간
    • 각 파티션 내의 에 이벤트가 순차적으로 저장
  • 소비자(Consumer): 토픽에서 이벤트를 읽어 처리
    • 이벤트는 소비된 후에도 일정 기간 동안 토픽에 남아 있어 다른 소비자들도 해당 이벤트를 읽을 수 있음 ( 기본 7일 )

 

더보기

질문:

카프카를 쓰면 MSA 인스턴스를 자유롭게 오토 스케일링 할 수 있다?

  • 여기서 소비자에 대한 오토 스케일링이 자유로움

 

메세지(Message)와 이벤트(Event)

이벤트

  • 이벤트는 시스템에서 발생한 중요한 동작이나 상태 변화를 나타내는 것
    • 즉, 시스템내에서 무언가가 발생했다는 것을 나타내는 것
  • 이벤트의 명명 규칙:
    • <명사><과거형>Event
    • 예: ProductCreatedEvent (상품 생성됨)
  • 이벤트 값은 String, Json 등 페이로드 정보를 담고있는 Bytes 정보

 

메시지

  • 이벤트를 포함하는 컨테이너
  • 구성 요소:
    • 키(Key): 이벤트를 특정 파티션에 매핑하는 데 사용
    • 값(Value): 이벤트의 실제 데이터(페이로드)
      • 키와 값은 JSON, String, Null 등의 형태를 가짐
    • 타임스탬프(Timestamp): 이벤트가 생성된 시간
    • 헤더(Headers): 추가 메타데이터(선택 사항)
  • 메시지의 페이로드는 직렬화되어 저장되며, 소비자는 이를 역직렬화하여 사용
  • +) 이벤트 객체는 이벤트에 대한 모든 정보를 포함해야하지만, 규모가 커진다면 최적화를 고민해야함 ( ex: 이미지, 동영상 )

 

토픽(Topic)과 파티션(Partition)

토픽

  • 특정 유형의 이벤트를 구분하기 위한 이름 공간
  • 각 토픽은 여러 개의 파티션으로 구성
    • 파티션을 사용하면 이벤트를 병렬로 처리할 수 있어 시스템의 확장성이 향상
    • 동일한 토픽 내의 파티션 수를 늘리면 소비자를 수평으로 확장 가능
더보기

질문:

  • Topic을 여러개 파티션으로 구성하면, 구독자 MSA를 수평으로 확장할 수 있다고? 이게 뭔 개소리
  • 서로 다른 파티션마다 서로 다른 양의 이벤트가 저장될 수 있다?? -> 이게 뭔 개소리
    • Events are in order within a partition. Order across partitions is not maintained,?? 

 

파티션

  • 파티션에는 여러개의 셀이 존재하고, 각 셀에 번호 존재 → Offset
  • 파티션은 추가 전용으로, 이벤트가 저장되면 변경이나 삭제가 불가하며 항상 끝에 추가
    • 새로운 이벤트 들어오면 Offset 증가하며 저장( 예: 첫 번째 이벤트는 offset 0, 이후는 1 ) 
  • 파티션 내에서는 순서 유지, 파티션 간 순서 보장 안 됨
  • 이벤트는 소비 후에도 7일간 유지 (기본값)

 

Events Ordering(이벤트 순서)

문제점

  • 메시지 키가 제공되지 않으면 이벤트는 임의의 파티션에 저장
    • 메시지 키가 제공되지 않으면, 카프카가 이벤트를 로드 밸런싱해서 하나의 파티션에 넣으려고 함
  • 이로 인해 이벤트 처리 순서가 보장되지 않음
  • 소비자들은 여러 파티션에서 이벤트를 병렬로 읽기 때문에 순서가 중요한 경우 문제가 발생

  • 사용자 A가 프로필을 A → B → C로 변경하여 3개의 이벤트가 발생했다고 가정
  • 메시지 키를 사용하지 않으면 이 이벤트들은 서로 다른 파티션에 저장될 수 있으며, 소비자가 이벤트를 처리하는 순서가 보장되지 않음

 

해결방안

  • 따라서 이렇게 순서대로 이벤트가 처리되아야 하는 상황에서는 메시지 키를 제공해라!
  • 메시지 키가 제공되면 해당 이벤트가 어느 파티션에 저장될지 결정할 수 있다.
  • 동일한 메시지 키를 사용하면 이벤트는 동일한 파티션에 저장되어, 해당 파티션 내에서 순서가 유지
    • 카프카는 생산자(producer)에 의해 도착한 순서대로 이벤트를 읽도록 순서를 보장

 

  • 메시지 키로 사용자 ID(User ID)를 사용하여 이벤트들이 동일한 파티션에 저장되어 순서가 유지

 

더보기

 

  • 힝 그러면 파티션이 가득차서 생기는 문제는 어떻게 처리하지?!

 

 

 

 

  • 아래 MSA는 고유한 포트번호에서 실행되는 작은 웹 서비스
  • 빨간색 상자는 MSA를 지원하는 Spring Cloud기 존재
  • API Gateway는 독립형 스프링 부트 애플리케이션이기도 함
  • 구성 서버(config server)와 서비스 검색(Service Discovery) 모두 스프링 애플리케이션
  • 서로간의 정보에 접근을 해야한다면, 바로 DB에 접근하는것은 허용하지 않으며, 서로간의 HTTP 요청/응답을 통해 주고 받음
  • 즉, HTTP는 MSA의 소통 수단 중 하나 -> 이때, 동기/비동기 HTTP 방식 둘다 목적에 따라서 잘 활용됨

 

'Kafka' 카테고리의 다른 글

2. Kafka를 위한 도커 컴포즈 파일 설정  (0) 2024.10.23