본문 바로가기
[ Concept ]

[ Concept ] 대용량 / 실시간 데이터 처리를 위한 오픈 소스 (Apache Kafka)

by 환이s 2024. 5. 17.


Apache Kafka (아파치 카프카) 란?

 

실무 프로젝트에서 개발을 끝내고 테스트를 진행하던 중 대용량 데이터를 처리하는 과정에서 접하게 된 오픈 소스에 대해 포스팅을 진행해 보겠습니다.

 

 

아파치 카프카? 실무에서 가끔씩 선배님들과 대화하면서 들어본 적은 있지만 실질적인 제어 코드나 실시간으로 제어하는 서비스를 이번에 진행하는 프로젝트에서 처음 접해봤습니다.

 

카프카는 웹 사이트, 애플리케이션, 센서 등에 취합한 데이터를 스트림 파이프라인을 통해 실시간으로 관리하고

보내기 위한 분산 스트리밍 플랫폼이며, 데이터를 생성하는 애플리케이션과 데이터를 소비하는 어플리케이션 간의 중재자 역할을 함으로써 데이터의 전송 제어, 처리, 관리 역할을 합니다.

 

카프카 시스템은 여러 요소(노드)와 함께 구성될 수 있어 카프카 클러스터라고 하기도 하는데

다른 메시징 시스템과 마찬가지로 어플리케이션과 서버 간의 비동기 데이터 교환을 용이하게 하고,

하루에 수 조개의 이벤트 처리가 가능하게 하는 역할을 합니다.

 

즉, 카프카는 플랫폼에 서비스를 연결하여 다양한 서비스에서 나오는 데이터 흐름을 실시간으로 제어하는 서비스의 중추역할을 하는 플랫폼입니다.

 


Apache Kafka (아파치 카프카) 특징

 

먼저 아래 그림을 살펴보면

출처: https://www.confluent.io/blog/event-streaming-platform-1

 

카프카가 등장하기 전 linked-in(링크드인)의 아키텍처입니다.

각 서비스 혹은 데이터 저장소가 End-To-End로 연결되어 아주 복잡한 구조를 가지고 있습니다.

이런 구조는 시스템을 확장하기 어려운 구조입니다.

 

 

위 그림은 카프카가 등장한 이후의 아키텍처입니다.

카프카가 등장하기 전과 후 그림만 봐도 유동적인 흐름으로 연결되어 있는 게 보이실 거예요.

 

모든 이벤트와 데이터의 흐름이 카프카를 중심으로 모이고 전달됩니다.

이벤트나 데이터가 발생했다면 발생 주체가 카프카로 데이터를 전달해 주고

해당 데이터가 필요한 곳에서 직접 가져다 사용합니다.

 

예시로 회원 서비스에 새로운 회원이 가입되었다고 가정해 봅니다.

 

새로운 회원이 가입되었다면 해당 메시지를 카프카로 전달하고

이 메시지를 멤버십 서비스가 컨슘 하여 해당 유저에 대한 데이터를 빅데이터에 저장해 분석합니다.

추가적으로 동시에 로그 스태시(로그 수집 시스템)는 이 메시지를 컨슘하여 개발자가 디버깅할 때 사용할 수 있도록 로그를 생성합니다.

 

카프카가 없었다면 회원 서비스가 멤버십 서비스, 하둡, 로그 스태시로

각각 다른 데이터 파이프라인을 통해 데이터를 전송해야 했을 텐데,

카프카를 사용해서 데이터 흐름을 중앙화한다면, 복잡도가 훨씬 낮아지는 것을 확인할 수 있습니다.

 

그렇다면 카프카만 갖는 특징은 무엇이 있을까요?

중요한 특징만 가져와서 알아보자면 다음과 같습니다.

 

  • 높은 처리량과 낮은 지연시간
    • 카프카는 대용량 데이터를 실시간으로 처리할 수 있도록 설계되었습니다.
    • 따라서 높은 TPS를 가지고 있고, 실시간 데이터 스트림, 로그 집계, 이벤트 드리븐 아키텍처 구현에 적합합니다.
  • 메시지 내구성
    • 데이터는 디스크에 지속적으로 저장되며, 복제 기능을 통해 데이터 손실을 방지합니다.
  • 분산 아키텍처
    • 카프카는 카프카 클러스터 내부에 여러 대의 브로커 서버를 구성하여 높은 확장성(scalability)내결함성(fault tolerance)을 갖습니다.
    • 이는 다른 MOM과 비교했을 때 카프카만이 가지고 있는 차별점입니다.
  • 유연성
    • 다양한 데이터 형식을 지원하며, 실시간 및 배치 처리에 모두 적합합니다.

Apache Kafka Architecture (아파치 카프카 아키텍처) 

 

지금까지 특징에 대해 알아봤습니다.

다음으로 카프카의 구성도를 명확하게 이해하기 위해 기본 구성요소를 하나씩 살펴보겠습니다.

 

 

  • Kafka Cluster(카프카 클러스터)
    • 카프카 클러스터는 다양한 브로커, 토픽 및 해당 파티션으로 구성된 시스템입니다.
    • 데이터는 클러스터 내의 주제에 기록되고 클러스터 자체에서 읽혀집니다.
  • Producer(생산자)
    • 생산자는 클러스터 내의 주제에 데이터/메시지를 보내거나 사용합니다.
    • 엄청난 양의 데이터를 저장하기 위해 애플리케이션 내의 다양한 생산자가 카프카 클러스터에 데이터를 보냅니다.
  • Consumer(소비자)
    • 소비자는 카프카 클러스터에서 메시지를 읽거나 소비하는 소비자입니다.
    • 클러스터에서 다양한 유형의 데이터를 소비하는 여러 소비자가 있을 수 있습니다.
    • 카프카의 장점은 각 소비자가 어디에서 데이터를 소비해야 하는지를 알 수 있다는 것입니다.
  • Broker(브로커)
    • 카프카 서버는 브로커로 알려져 있습니다.
    • 브로커는 생산자와 소비자 사이의 다리 역할을 합니다.
    • 생산자가 클러스터에 데이터를 쓰려는 경우 해당 데이터는 카프카 서버로 전송됩니다.
    • 모든 브로커는 카프카 클러스터 자체 내에 있습니다. 또한 여러 브로커가 있을 수 있습니다.
  • Topics(주제)
    • 유사한 유형의 데이터를 나타내기 위해 부여된 공통 이름 또는 제목입니다.
    • 아파치 카프카에서는 클러스터에 여러 주제가 있을 수 있습니다.
    • 각 주제는 다양한 유형의 메시지를 지정합니다.
  • Partition(파티션)
    • 데이터 또는 메시지는 파티션이라는 작은 하위 부분으로 나뉩니다.
    • 각 파티션에는 오프셋 값이 있는 데이터가 포함되어 있습니다.
    • 데이터는 항상 순차적으로 기록됩니다.
    • 무한한 오프셋 값을 갖는 무한한 수의 파티션을 가질 수 있지만, 메시지가 어느 파티션에 기록될 지는 보장되지 않습니다.
  • OffSet(오프셋)
    • 파티션에 저장된 레코드는 증가하는 정수 ID를 갖고, 이를 오프셋이라고 부릅니다.
    • 오프셋은 0부터 시작하고 파티션에 레코드가 저장될 때마다 시퀀셜하게 증가합니다.
    • 특정 파티션의 각 레코드는 고유한 오프셋을 갖지만, 서로 다른 파티션 간에는 고유하지 않습니다.
    • 파티션에서 데이터를 읽을 때 작은 것부터 큰 순서대로 읽습니다.
  • ZooKeeper(주키퍼)
    • 주키퍼는 카프카 클러스터에 대한 정보와 소비자 클라이언트의 세부 정보를 저장하는 데 사용됩니다.
    • 브로커 목록을 유지하여 관리하고 파티션의 리더를 선택하는 역할을 담당합니다.
    • 브로커가 죽거나 새로운 주제 등의 변경 사항이 발생하면 주키퍼는 아파치 카프카에 알림을 보냅니다.
    • 주키퍼는 홀수의 카프카 서버와 함께 작동하도록 설계되었습니다.
    • 주키퍼에는 모든 쓰기를 처리하는 리더 서버가 있고 나머지 서버는 모든 읽기를 처리하는 팔로어 서버입니다.
      • 그러나 사용자는 주키퍼와 직접 상호 작용하지 않고 브로커를 통해 상호 작용합니다.
      • 사육사 서버 없이는 카프카 서버를 실행할 수 없습니다.
      • 사육사 서버를 실행하는 것은 필수입니다.

 

ZooKeeper(주키퍼)분산 코디네이션 서비스를 제공하는 오픈소스로 카프카를 공부하면서 주키퍼 또한 폭이 적은 편이 아니라서 다음 포스팅으로 알아보려고 합니다. 그래서 별도의 부가적인 설명은 생략하겠습니다.

 

지금까지 카프카의 특징 및 아키텍처에 대해 알아봤습니다.

하지만 카프카를 이해하기엔 다소 어렵고 좀 더 추가적인 내용을 찾아보지 않으면 다가가기 어렵습니다.

 

그래서 저도 카프카를 이해하기 위해 먼저 메시지 큐와 MOM에 대해 알아봤습니다.


Message Queue(MQ)

 

메시지 큐(Message Queue)는 프로세스 또는 프로그램 간에 데이터를 교환할 때 사용하는 통신 방법 중에 하나로, 메시지 지향 미들웨어(Message Oriented Middleware: MOM)를 구현한 시스템을 의미합니다.

 

메시지 지향 미들웨어(MOM)비동기 메시지를 사용하는 응용 프로그램들 사이에서 데이터를 송수신하는 것을 의미합니다. 여기서 메시지란 요청, 응답, 오류 메시지 혹은 단순한 정보 등의 작은 데이터가 될 수 있습니다.

 

다음 그림을 참고해 봅시다.

 

 

메시지 큐는 메시지를 임시로 저장하는 간단한 버퍼라고 생각하면 됩니다.

위 그림을 확인해 보면 메시지 전송 및 수신하기 위해 중간 다리 역할하는 걸 확인할 수 있습니다.

 

메시지 전송 시 생산자(Producer)로 취급되는 컴포넌트가 메시지를 메시지 큐에 추가합니다.

해당 메시지는 소비자(Consumer)로 취급되는 또 다른 컴포넌트가 메시지를 검색하고 이를 사용해 어떤 작업을 수행할 때까지 메시지 큐에 저장됩니다.

 

각 메시지는 하나의 소비자에 의해 한 번만 처리될 수 있는데, 이러한 이유로 메시지 큐를 이용하는 방식을 1:1 통신이라 부릅니다.

 

 

그렇다면 메시지 큐를 사용하는 가장 큰 이유는 뭘까?

 

메시지 큐를 사용하면 생산자와 소비자가 서로를 직접 알 필요 없으므로 낮은 결합도(Decoupling)를 만들어낼 수 있습니다. 생산자, 수신자 서로가 서로에게 의존하지 않으므로, 각자는 독립적으로 확장(Scalable)될 수 있습니다.

 

또한 소비자가 당장 장애 상황이더라도 발행된 메시지는 모두 메시지 큐에 남아있으므로 결국 발신자가 발생한 모든 메시지는 소비자 서비스에게 전달된다는 보장성(Guarantees) 갖고, 이러한 여러 특성으로 메시지 큐는 여러 마이크로 서비스가 서로 협력하는 MSA 환경에서 빛을 발합니다.

 

마지막으로 메시지 큐는 생산된 메시지의 저장, 전송에 대해 동기화 처리를 진행하지 않고, 큐에 넣어두기 때문에 나중에 처리할 수 있습니다.

여기서, 기존 동기화 방식은 많은 데이터가 전송될 경우 병목이 생길 수 있고, 뒤에 들어오는 요청에 대한 응답이 지연될 수 있기 때문에 메시지 큐를 사용하면 비동기(Asynchronous) 통신을 구현할 수 있습니다.

 


마치며

 

오늘은 Apache Kafka(아파치 카프카)에 대해 알아봤습니다.

결국은 서버가 사용자에게 얼마나 빠르고 안정적으로 정보를 전달할 수 있는지에 초점을 맞춘 기술이라고 생각합니다.

 

모든 애플리케이션에 카프카나 메시지 큐가 필요한 것은 아니지만,

서버의 뒷단에서 실행되는 일부 작업을 맡김으로써 웹 애플리케이션의 성능을 향상하는 것에 대해 생각해 보는 것도 좋을 것 같습니다.

 

다음 포스팅에서 뵙겠습니다.

 

728x90