💡 Apache Kafka - 실시간으로 스트림 데이터를 수집하고 처리하는 데 최적화된 ‘분산 이벤트 스트리밍 플랫폼(Distributed Data Streaming Platform)’입니다. 이는 실시간으로 발생하는 대량의 데이터를 중앙 허브를 통해 흐르도록 설계되어 있습니다. 이를 통해 데이터의 일관성을 유지하고 시스템 전반의 복잡성을 줄일 수 있습니다.
- 이러한 다량의 데이터는 A 지점에서 B 지점까지만의 데이터가 이동되는 것뿐만 아니라, A 지점에서 Z지점까지의 필요한 모든 곳에 대규모 데이터를 동시에 전달할 수 있습니다. - 현대적인 데이터 파이프라인 구축에 필수적인 도구로 자리잡았으며, Netflix, LinkedIn, Uber 등 많은 기업들이 핵심 인프라로 사용하고 있습니다.
💡 Kafka에 의해 처리되는 스트림(Stream)과 스트리밍(Streaming)은 무엇일까?
- 스트림(Stream)이란 시간에 따라 연속적으로 발생하는 데이터의 흐름을 의미합니다. 예를 들어, 실시간 주식 거래 데이터, SNS 피드, IoT 센서 데이터 등이 스트림의 예시입니다. - 스트리밍(Streaming)은 이러한 데이터 스트림을 실시간으로 처리하는 과정을 말합니다
💡 분산 이벤트 스트리밍 플랫폼(Distributed Event Streaming Platform)이란?
- 여러 서버에 걸쳐 이벤트 데이터를 실시간으로 처리하고 저장하는 시스템을 의미합니다. 주요한 특징은 분산 처리를 실시간으로 처리하며, 데이터 복제를 통해 장애 상황에서도 데이터 손실을 방지하며, 이벤트 발생 순서대로 처리하여 데이터의 일관성을 보장합니다.
- LinkedIn 아키텍처 내에서는 “필요에 따라 시스템과 애플리케이션 간에 임시 파이프를 구축하고 모든 비동기 처리를 요청-응답 웹 서비스에 강제로 처리하였다”라고 이야기하고 있습니다.
- 그렇기에, 시간이 지남에 따라 이러한 설정은 점점 더 복잡해져서 결국 모든 종류의 다른 시스템 간에 파이프라인을 구축하게 되었습니다. 그렇지만, "각 파이프라인은 고유한 방식으로 문제가 있었습니다. 로그 데이터 파이프라인은 확장 가능했지만 손실이 있었고 지연 시간이 긴 데이터만 제공할 수 있었습니다.”
- 스트림 중심의 아키텍처로 구성이 되었습니다. 이 설정에서 Kafka는 일종의 범용 데이터 파이프라인 역할을 합니다. - 각 시스템은 이 중앙 파이프라인에 공급하거나 공급받을 수 있습니다. - 애플리케이션이나 스트림 프로세서는 이를 탭하여 새로운 파생 스트림을 생성할 수 있으며, 이는 다시 다양한 시스템에 공급되어 제공됩니다.
- 주요 사용되는 사례는 ‘실시간 스트리밍 애플리케이션’을 구축하거나 ‘실시간 스트리밍 데이터 파이프 라인’을 구축, 메시지 브로커로 사용합니다.
1. 실시간 스트리밍 애플리케이션 - 실시간으로 발생하는 데이터를 지속적으로 처리하고 분석하는 애플리케이션입니다. - 예를 들어 실시간 로그 분석, 실시간 모니터링 시스템 등이 있습니다.
2. 데이터 파이프 라인 - 데이터를 안정적으로 처리하고 한 시스템에서 다른 시스템으로 이동하며, 스트리밍 애플리케이션은 데이터 스트림을 소비하는 애플리케이션입니다. - 예를 들어서, 사용자 활동 데이터를 받아 사람들이 웹사이트를 어떻게 사용하는지 실시간으로 추적하는 데이터 파이프라인을 만들려면 Kafka를 사용하여 스트리밍 데이터를 수집 및 저장하면서 데이터 파이프라인을 구동하는 애플리케이션에 읽기 서비스를 제공할 수 있습니다.
3. 메시징 시스템(브로커) - 애플리케이션 간의 메시지 전달을 중개하는 미들웨어 시스템입니다. 발신자(Producer)와 수신자(Consumer) 사이에서 메시지를 전달하는 중간 역할을 수행합니다.
사용 사례
설명
스트리밍 애플리케이션
실시간 데이터 스트림을 처리하는 애플리케이션을 구축하여 즉각적인 분석과 대응이 가능합니다.
메시징 시스템
애플리케이션 간의 비동기 통신을 위한 메시지 브로커 역할을 수행하며, 시스템 간 안정적인 데이터 전달과 통신을 중재합니다.
데이터 파이프라인
실시간 데이터를 수집하고 저장하면서 다른 시스템으로 안정적으로 전달하는 파이프라인을 구축합니다.
활동 추적
웹사이트나 애플리케이션의 사용자 행동 데이터를 실시간으로 수집하고 분석하여 사용 패턴을 파악합니다.
- 주요한 차이점은 Apache Kafka의 경우는 ‘분산 스트리밍 플랫폼’이고, RabbitMQ의 경우는 ‘메시지 브로커’입니다. - 즉, Apache Kafka의 경우는 메시지 브로커의 역할도 수행하며, 데이터 스트림의 저장, 처리, 실시간 분석 등 더 광범위한 데이터 처리 추가 기능 제공하며 이는 더 포괄적인 개념이라고 할 수 있습니다.
- 생성자(Producer)가 생성한 데이터를 여러 소비자(Consumer)에게 분산하는 기능을 합니다. 해당 모델은 여러 소비자(Consumer)가 동시에 구독할 수 없다는 한계가 있습니다. - 즉, 생성자는 데이터를 큐에 적재하고 큐에서는 순차적으로 데이터가 추출되기에 모든 소비자에게 동시에 전달이 아닌 순차적으로 전달이 됩니다. - 이를 통해서 순서가 보장이 되며, 메시지 중복 처리를 방지하고 작업을 분산하는데 효과적인 방법입니다.
💡 대기열(Queue) 모델 처리 과정 1. 생성자(Producer) → 데이터(Data) → 대기열(Queue) - 생성자는 애플리케이션이나 서비스를 의미하며, 대기열(Queue)로 스트림 데이터를 전송합니다. - 전송된 데이터는 대기열(Queue)에 FIFO(First In First Out) 형태로 순차적으로 적재가 됩니다.
2. 대기열(Queue) → 소비자(Consumer) - 대기열(Queue)에 있는 데이터는 소비자(Consumer)가 하나씩 가져가서 처리합니다. - 데이터는 순차적으로 처리되며, 하나의 데이터는 하나의 소비자에 의해서만 처리됩니다. - 소비자가 데이터를 성공적으로 처리하면 해당 데이터는 대기열에서 제거됩니다.
- 게시자(Publisher)가 발행한 메시지를 여러 소비자(Consumer)가 동시에 구독하고 처리할 수 있습니다. 각 소비자는 독립적으로 메시지를 받아 처리할 수 있습니다.
- 작업 부하를 분산하기 위해서는 각 구독자가 서로 다른 메시지를 처리해야 하는데, 게시-구독 모델에서는 모든 구독자가 동일한 메시지를 받기 때문에 이것이 불가능합니다. - 즉, 해당 모델에서는 하나의 메시지가 모든 구독자에게 복사되어서 전달이 됩니다. 예를 들어서, 메시지 A가 발행되면 구독자 1, 2, 3에게 모두 동일한 메시지 A가 전달이 됩니다.
1. 게시자(Publisher) → 데이터(Data) → PubSub(Publisher Subsciber) - 게시자는 애플리케이션이나 서비스를 의미하며, 데이터를 스트림 형태로 발행(Publish)합니다.
2. PubSub(Publisher Subsciber) → 구독자(Subscriber) - 발행된 스트림 데이터는 이를 구독(Subscribe)하고 있던 모든 구독자(Subsciber)에게 전달이 됩니다. - 전달된 구독자는 Single Consumer에게 전달되거나 혹은 여러 Consumer(Consumer Group)에게 다시 전달이 됩니다.
- Kafka Topic으로부터 메시지를 구독(Subscribe)하고 읽어오는 애플리케이션이나 서비스를 의미합니다. - 하나 이상의 토픽을 구독(Subscribe)하여 메시지를 지속적으로 소비합니다. 구독 과정에서 특정 토픽의 파티션에 할당되어 메시지를 읽어옵니다. - Consumer Group을 통해 여러 Consumer가 협력하여 병렬 처리가 가능합니다.
- 하나의 토픽에 대해 협력하여 메시지를 처리하는 소비자(Consumer)들의 집합을 의미합니다. 즉, 동일한 토픽을 구독하는 소비자들의 논리적인 그룹입니다.
- 하나의 파티션은 동일한 Consumer Group 내에서 하나의 Consumer에만 할당됩니다. - 파티션의 수보다 Consumer가 많으면 일부 Consumer는 유휴 상태가 됩니다. - 예를 들어서 하나의 토픽에는 3개의 파티션이 있고 Consumer Group 내에 2개의 Consumer가 있다고 가정합니다. - 이때는, Consumer 1은 파티션 1, 2를 처리하고, Consumer 2는 파티션 3을 처리하여 하나의 토픽에 대해 협력하여 처리합니다.
- 예를 들어서, 하나의 토픽 내에 파티션이 6개가 있고, Consumer Group 내에는 3명이 있다고 가정하에 있습니다. - 이때, Consumer 1은 P1, P2를 처리하고 Consumber2는 P3, P4를 처리하고 Consumer 3에서는 P5, P6를 처리합니다. - 이를 통해서 독립적으로 분산 처리를 수행하게 됩니다.
- Kafka에서 데이터를 전송하는 기본 단위입니다. - 키(Key), 값(Value), 타임스탬프(Timestamp)로 구성되며, 선택적으로 헤더(Headers)를 포함할 수 있습니다. - 메시지는 한번 기록되면 변경할 수 없는 불변(Immutable) 특성을 가집니다.
💡 파티션(Partition) - 토픽을 여러 개의 파티션으로 나누어 병렬 처리를 가능하게 하는 물리적 단위입니다 - 각 파티션은 순서가 있는 불변의 시퀀스로 구성되며, 고유한 오프셋을 가집니다 - 파티션을 통해 데이터를 여러 브로커에 분산 저장하여 높은 처리량과 확장성을 제공합니다
기능
설명
세부사항
병렬 처리
토픽의 데이터를 여러 파티션으로 분할하여 동시 처리를 가능하게 합니다.
- 높은 처리량 제공 - 수평적 확장성 지원 - 다중 컨슈머 병렬 처리
순서 보장
각 파티션 내에서 메시지의 순서가 보장됩니다.
- 파티션 내 순차적 오프셋 - FIFO(First In First Out) 방식 - 파티션 간 순서는 보장되지 않음
- 파티션 내에서 각 메시지를 고유하게 식별하는 순차적인 ID 번호입니다. - 파티션 내에서 순차적으로 증가하는 정수값으로, 메시지의 위치를 나타냅니다. - Consumer가 어디까지 메시지를 읽었는지 추적하는 데 사용됩니다.
- 예를 들어서, 데이터가 1, 2, 3, 4, 5, 6이라는 값이 순차적으로 Topic 내에 파티션에 들어갔다고 가정하에 Consumer는 3개 있을 때를 가정하에 있습니다. - 이는 Consumer Group을 이루어서 Consumer 1은 1, 4 오프셋을 찾아서 데이터를 가져오고, Consumer 2는 2,5를 가져오고 Consumer 3는 3, 6의 값을 가져오는 서로 다른 파티션을 병렬 처리를 수행합니다.
💡 아래의 그림에서 Consumer 1, Consumer2에서는 Topic 내에 Partition을 가져오는 역할을 수행하고 있습니다.
- Consumer 1은 offset 4라는 값과 Consumer2는 offeset 3이라는 값을 가리키고 있어서 각각의 순차적인 ID 번호 값을 가져오는 역할을 수행합니다.
- Kafka 클러스터를 구성하는 서버 단위입니다. 이는 메시지를 수신하고 저장을 담당하는 역할을 의미합니다. - 생성자(Producer)로부터 전달받은 토픽의 파티션을 저장하고 관리하는 역할을 합니다. - 소비자(Consumer)로부터 요청에 따라 저장된 메시지를 전달하는 역할을 수행합니다. - 생성자와 소비자 간의 메시지 전달을 중개하는 역할을 수행합니다.
- 카프카 클러스터(Kafka Cluster)내에서 각 브로커 마다 고유한 ID를 가지며, 다른 브로커들과 협력하여 데이터를 복제하고 동기화를 수행합니다.