아파치 카프카 (Apache Kafka)란?
정의
Apache Kafka는 실시간 데이터 스트리밍을 처리하기 위한 오픈 소스 분산형 Pub/Sub 메시징 플랫폼입니다. 주로 대규모 데이터 처리, 실시간 데이터 파이프라인 구축, 스트리밍 분석, 데이터 통합 등에 사용됩니다.
탄생 배경
Kafka는 LinkedIn에서 개발했습니다. LinkedIn은 사용자들의 활동, 컨텐츠 등 대량의 데이터를 실시간으로 추적하고 처리하려했습니다. 기존 데이터 처리 시스템으로 해결할 수 있었습니다. 하지만 서비스가 커지면서 처리해야할 데이터도 많아지고 노드도 많아졌습니다. 이에 따라 데이터 파이프라인은 매우 복잡해졌고, 대규모 데이터를 처리하는데 한계를 느끼게되었습니다.
이에 LinkedIn은 대용량의 데이터를 효율적으로 처리하고, 실시간으로 데이터를 수집하고 분배할 수 있는 시스템의 필요성을 느끼게 되었고, Kafka를 개발하게 되었습니다. 아래 이미지처럼 Kafka를 도입함으로써 모든 데이터와 데이터의 흐름을 중앙에서 관리할 수 있게 되었고, 신속한 데이터 처리와 유연한 확장이 가능해졌습니다.
Kafka 특징 및 장점
- 실시간 데이터 처리: Kafka 스트림 처리 API를 통해 실시간 데이터 스트림을 처리할 수 있어, 이벤트 드리븐 아키텍처와 같은 실시간 처리에 적합합니다.
- 고가용성: Kafka 클러스터는 여러 서버로 구성되어 있고, 데이터 복제를 통해 장애 발생시에도 데이터를 안전하게 처리할 수 있습니다.
- 높은 처리량: Kafka는 대용량 데이터를 실시간으로 처리할 수 있도록 설계되어 있어 높은 처리량(TPS)을 제공합니다. 이는 데이터를 프로듀서에서 브로커로 묶어서 전송하고, 데이터를 병렬 처리하여 가능합니다.
- Pull 기반 메시시징: Kafka는 컨슈머가 브로커로부터 메시지를 능동적으로 가져오는 Pull 방식을 사용하여 최적의 성능을 제공합니다.
- 내구성: Kafka는 메시지를 디스크에 저장하여 장애 시에도 데이터 유실이 없도록 보장합니다.
Kafka 사용 용도
- 로그 수집 및 이벤트 스트리밍:
대규모 시스템에서 발생하는 로그 데이터나 이벤트 데이터를 실시간으로 수집하고 처리하는 데에 Kafka를 사용할 수 있습니다. 실시간으로 발생하는 데이터 스트림을 효율적으로 처리하여 다양한 분석 및 모니터링 시스템에 전달할 수 있습니다. - 실시간 스트림 처리:
Kafka는 스트림 처리 기능을 제공하며, 이를 통해 데이터를 받아서 필터링, 변환, 집계 등의 작업을 수행하고 결과를 다른 시스템에 전달할 수 있습니다. - 메시지 큐 및 데이터 버스:
Kafka는 고성능 메시지 큐로써 사용될 수 있습니다. MSA에서는 서비스 간의 통신에 Kafka를 사용하여 이벤트 기반 통합을 구현할 수있습니다. 또한 데이터를 다양한 시스템 간에 안전하고 신속하게 전달하는 데이터 버스 역할을 수행합니다.
Kafka 동작원리
Kafka는 어떻게 데이터를 중앙 집중화하여 처리할 수 있었을까요?
바로 Pub/Sub (Publish/Subscribe) 모델을 기반으로 데이터 관리를 중앙 집중화할 수 있었습니다.
Pub/Sub 모델은 MOM(메시지 기반 미들웨어) 중 하나로, Publisher(=Producer)가 메시지를 발행하고, Subscriber(=Consumer)가 특정 주제(Topic)를 구독하여 해당 주제와 관련된 메시지를 받는 방식입니다.
이를 자세히 이해하기 위해 메시지 큐부터 설명하겠습니다.
메시지 큐
- MOM의 구성 요소 중 하나로, Publisher와 Subscriber 간의 메시지를 안전하게 전달하기 위한 시스템입니다.
- 메시지 큐는 Publisher가 메시지를 큐에 넣으면 보관하고, Subscriber는 해당 큐에서 메시지를 가져와 처리합니다.
- 메시지 큐가 메시지를 중개하기 때문에 Publisher와 Subscriber는 서로 의존하지 않게 됩니다. 이를 통해 느슨한 결합(loose coupling)이 이루어집니다.
- 수신하는 쪽에서 장애가 발생하더라도 메시지 큐에 메시지가 남아 있기 때문에 수신자는 메신저를 받을 수 있다는 보장이 있고, 발신한 쪽에서도 전달하고 나서 처리에 대해 고민할 필요가 없어집니다. 이 원리를 통해 비동기 통신도 구현할 수 있습니다.
Pub/Sub 모델
- Pub/Sub 모델은 메시지 큐의 한 방식입니다.
- Publisher는 메시지를 발생하고, Subscriber는 특정 주제(Topic)을 구독하여 해당 주제와 관련된 메시지를 받습니다.
- Publisher가 발행한 메시지는 Topic을 구독하는 모든 Subscriber에게 전달됩니다.
Kafka 아키텍처
- Producer:
Producer는 Kafka에 메시지를 발행(produce)하는 클라이언트입니다.
Producer는 특정 topic으로 메시지를 보내며, 메시지의 키(key)와 값을(value) 포함할 수 있습니다.
이러한 메시지들은 Kafka의 특정 topic에 저장되고, Consumer가 이를 읽어갑니다.
일반적으로 데이터를 생성하고 Kafka에 전송하는 역할을 합니다. - Consumer:
Consumer는 Kafka로부터 메시지를 소비(consume)하는 클라이언트입니다.
Consumer는 특정 topic의 파티션(partition)에서 메시지를 읽어옵니다.
읽어온 메시지들은 순차적으로 처리됩니다.
Consumer Group을 통해 여러 Consumer 인스턴스를 묶어 하나의 logical consumer로 구성할 수 있습니다. - Kafka Cluster:
Kafka Cluster는 하나 이상의 Broker로 구성된 집합입니다.
각 Broker는 데이터를 저장하고 클라이언트로부터 메시지를 받아들이고, 메시지를 클라이언트에 전달합니다.
클러스터는 데이터의 확장성과 내결함성을 보장합니다. - Broker:
Broker는 Producer로부터 메시지를 받아들이고, Consumer에게 메시지를 전달해주는 노드(서버)입니다. Broker는 여러 대가 운영될 수 있으며 이를 Kafka Cluster라고 합니다. Kafka Cluster 내부에 있는 Broker들의 여러 메타 정보들 관리해주기 위해 Zookeeper라는 도구가 필요합니다.
Borker는 받은 메시지를 Topic(주제)에 따라 partition에 메시지를 분산 저장해줍니다. 이를 통해 데이터의 병렬 처리와 안정성을 보장할 수 있습니다.
예를 들어, Topic A에 대한 데이터를 저장하기 위해 세 개의 Broker가 Kafka Cluster를 구성하고 있습니다. 이 경우, Topic A의 partition은 세 개의 Broker 중 하나 이상에 분산되어 저장됩니다. 각 partition은 복제(replication)되어 여러 Broker에 중복으로 저장될 수도 있습니다. 따라서 하나의 Broker가 고장날 경우에도 해당 partition의 데이터에 대한 안정성이 보장됩니다.
💁 어느 Partition에 저장할까?
partition에 분산 저장해줄 때 어느 partition에 저장할지 어떻게 결정할까요? 바로 메시지의 key 값을 설정하여 어느 partition에 저장할지를 결정합니다. 만약 key 값을 설정하지 않았다면 RR(Round-Robin) 방식으로 결정합니다. partition 같은 경우 내부에 들어온 메시지의 순서가 보장됩니다. 때문에 메시지 key 값을 지정하여 특정 partition에만 메시지가 저장되게 하여 들어온 메시지 순서를 보장할 수 있습니다. (물론 partition을 하나만 두는 방법도 방법일 수 있습니다.) 메시지 key값을 지정하지 않는 경우 RR 방식을 사용하게 되고, 이 방식은 여러 partition에 저장되기 때문에 메시지 순서를 보장할 수 없습니다.
따라서 메시지 순서가 매우 중요한 프로그램이라면 partition 수, 메시지 key 값 설정 등을 고려 필요가 있습니다. 하지만 메시지 순서를 위해 이러한 설정들을 강제하면, 메시지 병렬 처리라는 이점을 잃게되기 때문에 신중히 고려해봐야 합니다.
- Topic:
Topic은 메시지의 카테고리 또는 주제를 나타내는 논리적인 단위입니다.
Producer는 특정 topic으로 메시지를 보내며, Consumer는 특정 topic에서 메시지를 읽어옵니다.
메시지들은 topic에 저장되어 Consumer가 필요할 때 가져올 수 있습니다. - Partition:
논리적인 topic의 구분으로 하위 요소로, kafka가 실제 메시지를 저장하는 (물리적인) 단위입니다. 각 Partition은 별도의 파일로 저장되어 있습니다.
topic을 생성할 때 patition의 수와 ReplicationFactor를 최소 3으로 설정해주어야합니다. ReplicationFactor를 설정하지 않으면 default로 1이 설정되는데 이는 원본 메시지만 저장하고 복제를 하지 않겠다는 뜻이고 ReplicationFactor를 3으로 설정하면 두 개의 복제본을 생성하겠다는 의미입니다. 1개 Leader Partition과 2개의 Follower Partition이 만들어지는데 Leader Partition 에서는 모든 쓰기와 읽기가 가능하고, Follower Partition는 Leader Partition의 복제를 합니다.
만약 Leader Partition에 장애가 발생하는 경우 Follwer Partition 중 하나가 Leader Partition을 승계합니다. 이를 통해 장애를 대처 할 수 있습니다.
또한 하나의 topic에 대한 두 개 이상의 parition을 서로 다른 Broker에 구성함으로써, 메시지의 병렬 처리를 가능하게 하며, 확장성과 성능을 향상시킵니다.
💁 ISR (In-Sync-Replicas)
ISR은 Leader Partition과 Follower Partition들의 집합입니다. ISR에 속한 Partition들은 Leader Partition에 장애가 발생했을 때 새로운 Leader Partition이 될 수 있습니다. 즉, ISR에 속한 Follower Partition들은 Leader Partition이 될 수 있는 자격이 있다는 뜻(데이터 정합성 보장)입니다.
ISR에 속하는 지를 어떻게 확인할까요?
ISR그룹의 Leader Partition와 Follower Partition 사이에 주기적인 복제 요청이 발생하고, 이를 통해 동기화가 이루어집니다. 만약 Leader와 동기화되지 않으면 ISR에서 제외됩니다. Kafka는 각 복제본이 Leader Partition의 모든 메시지를 정상적으로 동기화했는지를 확인하기 위해 Offset을 사용합니다. Leader와 복제본의 Offset이 동일한 경우, 해당 복제본은 ISR에 속합니다.
- Zookeeper:
Zookeeper는 Kafka의 분산 처리를 위한 도구입니다. Zookeeper는 Kafka Cluster의 구성정보 즉, Broker들의 정보와 상태를 관리하고, 리더 선출 등의 작업을 조정합니다. Kafka Cluster의 Broker들은 Zookeeper를 통해 서로의 존재 및 메타데이터 정보를 공유하고, 이를 통해 Kafka의 메타데이터, 브로커 상태, 토픽 등을 관리할 수 있습니다.
💁 KRaft의 등장
ZooKeeper를 사용하게 되면 Kafka 클러스터 외부에 별도의 Zookeeper를 설정하고 운영해야합니다. 또한 Zookeeper는 분산환경에서 중앙 집중식으로 동작하기 때문에 단일 장애 지점이 될 수 있습니다. 이외에도 여러 이유가 있어 Kafka 자체에 메타데이터를 관리할 수 있는 KRaft가 나왔습니다. KRaft를 사용함으로써 ZooKeeper에 대한 종속성이 제거되고, KRaft는 Kafka 클러스터 내부에 내장되어 있기 때문에 간소화된 아키텍처를 제공합니다. 또한 KRaft는 Kafka 에 특화된 분산 리더 선출 알고리즘을 사용하여 단일 장애 지점을 제거하고, 높은 처리량과 낮은 지연 시간을 제공해줍니다.
'Kafka' 카테고리의 다른 글
Kafka Spring Boot 3으로 간단하게 Producer, Consumer 구현해보기 (0) | 2024.02.14 |
---|---|
Kafka Kafka명령어, local 환경에 Kafka Cluster 구축 (1) | 2024.02.13 |