프로젝트 개요 및 선정 이유
주제명: 가상 IoT 센서 데이터 실시간 스트리밍 수집 및 저장
해당 프로젝트는 가상의 IoT 센서 데이터를 5초 정도의 딜레이 시간을 주어 실시간으로 생성하여 Apache Kafka를 통해 스트리밍하고, 이를 소비하여 데이터베이스에 저장 및 시각화하는 데이터 파이프라인 구축까지의 단계로 계획하였습니다.
해당 주제를 프로젝트로 선정한 이유는 다음과 같습니다:
| 항목 | 설명 |
| 손쉬운 데이터 생성 | 실제 센서는 없지만 Python 스크립트를 통해 가상의 온도, 습도, 기압 그리고 미세먼지 농도와 CO2 농도 등의 데이터를 랜덤 생성하여 쉽고 유연하게 프로젝트를 진행 가능함 |
| kafka 구조 심화 학습 | Producer가 데이터를 송신하고 Consumer가 데이터를 수신하는 Kafka의 스트리밍 모델을 명확하게 구현하고 이해할 수 있음 |
| DB 저장 및 시각화 | InfluxDB(또는 PostgreSQL)에 데이터를 저장하고 Grafana로 실시간 데이터 변화를 모니터링할 수 있어, 데이터 흐름과 저장 구조를 시각적으로 체득할 수 있음 |
| 확장성 확보 | 센서 종류 추가, 이상치 탐지 기능 개발, 알림 시스템 추가 등 다양한 확장 프로젝트로 연결이 가능하므로 학습 깊이를 넒히는 데에 유연함 |
프로젝트의 목표
데이터 엔지니어링 실무에서 수행되는 핵심 역할(데이터 수집, 처리 및 정제, 저장, 데이터 파이프라인 구축 및 운영, 모니터링 및 최적화)을 직접 체험하고, 각 단계에서 주로 사용되는 대표적인 기술 스택을 사용함으로써 엔드 투 엔드(End-to-End) 데이터 파이프라인 구축하고 운영해봅니다. 실제 기업 현장에서의 데이터 흐름을 모사함으로써, 해당 직무에 필요한 기술적 이해와 문제 해결 능력을 키워 성장을 목표로 삼았습니다.
- 가상의 IoT 센서 데이터 생성 및 스트리밍 환경 구축
- Kafka Producer/Consumer 구조 이해 및 구현
- InfluxDB(PostgreSQL 대체 가능)를 통한 데이터 저장
- Grafana를 통한 실시간 데이터 시각화 대시보드 구축
- Airflow(선택)**를 통한 데이터 흐름 관리 및 모니터링
주요 사용 기술 스택
| 분류 | 기술 스택 |
| 프로그래밍 | Python 3.12 |
| 메시징 브로커 | Apache kafka |
| 데이터베이스 | InfluxDB |
| 데이터 시각화 | Grafana |
| 파이프라인 관리 | Apache Airflow |
| 컨테이너 오케스트레이션 | Docker-Compose |
Kafka란 무엇인가?

먼저, kafka가 무엇인지 알기 위해선 "왜 탄생하게 되었는가?"에 대한 원초적인 질문에 답이 되어야 합니다.
kafka는 미국의 구인 구직 및 직장인 커뮤니티와 같은 인터넷 기업인 LinkedIn에서 처음으로 개발되었습니다. LinkedIn은 매 분마다 사용자 활동 이벤트(로그인, 페이지뷰, 클릭 등)와 운영 지표(서비스 콜 지연 시간, 오류, 시스템 리소스 사용률 등)를 포함한 방대한 양의 로그 데이터를 생성해 냅니다. 이는 현시점 대략적으로 하루 평균 7조 건의 메시지를 다룬다고 알려져 있습니다.
여기서 로그 처리 요구 사항을 충족하기 위해서 Jay Kreps가 이끄는 LinkedIn 내부 개발 팀에서 기존 로그 수집기와 게시/구독 메시징 시스템을 장점을 결합한 kafka라는 메시징 시스템을 구축하게 됩니다. 이는 높은 처리량과 확장성을 제공하며, 메시징 시스템과 유사한 API를 제공함으로써 애플리케이션이 실시간 로그 이벤트를 사용할 수 있게 됩니다.
게다가 kafka 개발 당시 대부분의 기존 시스템은 브로커가 컨슈머에게 데이터를 푸시하는 "푸시" 모델을 사용합니다. 하지만 LinkedIn 팀은 컨슈머가 감당할 수 있는 최대 속도로 메시지를 검색할 수 있고, 감당할 수 있는 것보다 빠르게 푸시되는 메시지의 폭주를 피할 수 있기에 "풀" 모델이 요구사항에 더 적합하다고 판단하게 됩니다.
정리하자면, kafka는 분산형 스트리밍 플랫폼으로써, 대용량 데이터를 빠르게, 안정적으로, 실시간으로 전달할 수 있는 메시지 큐 시스템입니다.
여기서 잠깐,
그렇다면 kafka에서 검색도 되고, 푸시도 되는 "메시지(Message)"란 무엇인지 짚고 넘어가겠습니다.
메시지란 카프라의 데이터 단위를 말합니다. 데이터베이스의 행이나 레코드(DB를 구성하는 값)와 유사하다고 생각하시면 될 것 같습니다.
메시지의 특성은 다음과 같습니다:
- 메시지는 키라는 선택적 메타 데이터를 가질 수 있습니다. 내부적으로 메시지와 키는 바이트 배열로 구성됩니다.
- kafka 브로커에서 주고받는 메시지를 이벤트(Event)라고 함
- 사용자가 파티셔닝을 더 세밀하게 제어하고 싶을 때 키를 사용할 수 있습니다.
- 예시로 kafka는 키에 대한 일관된 해싱을 사용하여 동일한 키를 가진 메시지가 동일한 파티션에 배치되도록 보장할 수 있습니다.
- kafka에 저장된 메시지에는 명시적인 ID가 없어 논리적 오프셋으로 주소가 지정됩니다.
- 해당 방식은 메시지 ID를 실제 메시지 위치에 매핑하는 인덱스 구조를 유지하는데 지정됩니다.
Kafka 핵심 용어 #01: Topic & Partitions
kafka의 메시지는 토픽(Topic)으로 구성됩니다. 이는 데이터베이스 시스템의 테이블과 같습니다. 토픽은 여러 파티션(Partitions)으로 분할될 수 있습니다.
kafka는 파티션을 통해서 중복성과 확장성을 제공합니다. 파티션은 다른 서버에 호스팅될 수 있으며, 이는 토픽을 여러 서버에 걸쳐서 수평적으로 확장할 수 있음을 의미합니다.
토픽의 각 파티션은 논리적 로그에 해당합니다. 물리적으로 로그는 대략 동일한 크기(예: 1GB)의 세그먼트 파일 집합으로 구현됩니다. 메시지가 파티션에 기록될 때마다 브로커는 해당 메시지를 마지막 세그먼트 파일에 추가합니다.
Kafka 핵심 용어 #02: Producer
토픽에 메시지를 게시하는 클라이언트를 프로듀서(Producer)라고 합니다. 프로듀서는 특정 파티션에 메시지를 작성합니다.
이 작업은 메시지 키와 파티셔너를 사용하여 키의 해시값을 생성하고 특정 파티션에 매핑합니다.
기본적으로 프로듀서는 모든 토픽 파티션에 메시지를 균등하게 분배하여 경우에 따라 특정 파티션으로 메시지를 전송할 수 있으며, 이는 메시지 키에 특정 파티션 체계를 적용하여 수행됩니다.
Kafka 핵심 용어 #03: Consumer
클라이언트는 하나 이상의 구독된 토픽에서 메시지를 가져와 읽습니다. 여기서 컨슈머(Consumer)는 파티션에 기록된 순서대로 메시지를 읽습니다. 컨슈머는 메시지 오프셋을 사용하여 소비량을 추적합니다.
컨슈머가 특정 메시지 오프셋을 확인·응답하면, 해당 파티션에서 해당 오프셋 이전의 모든 메시지를 수신했음을 의미합니다.
컨슈머는 컨슈머 그룹의 일부로 동작하며, 한 명 이상의 컨슈머가 함께 토픽을 소비합니다.
Kafka 핵심 용어 #04: Broker
게시된 메시지는 브로커(Broker)라고 불리는 서버 집합에 저장됩니다.
브로커는 프로듀서로부터 메시지를 수신하고, 오프셋을 할당하며 디스크에 기록합니다. 또한 메시지 가져오기 요청에 응답하여 소비자에게 서비스를 제공합니다.
Kafka 핵심 용어 #05: Cluster
kafka 브로커는 클러스터(Cluster)의 일부로 한 브로커는 클러스터 내에서 클러스터 컨트롤러 역할을 하며, 관리 작업을 담당합니다.
카프카에서 복제(Replication)는 파티션 내 메시지 중복성을 제공하여 브로커 장애 발생 시 팔로워 중 하나가 리더십을 이어받을 수 있도록 합니다. 모든 프로듀서는 메시지를 발행하기 위해 리더에 연결해야 하지만, 컨슈머는 리더 또는 팔로워 중 하나로부터 메시지를 가져올 수 있습니다.
클러스터에는 파티션을 소유하는 단일 브로커가 있습니다. 이 브로커를 파티션의 리더라고 합니다. 복제된 파티션은 파티션의 팔로워라고 하는 추가 브로커에 할당됩니다.
Kafka 구성 요소 정리
마지막으로 표로 정리하면 다음과 같겠습니다:
| 구성 요소 | 설명 |
| Producer | 데이터를 Kafka로 보내는 역할 (발행자) |
| Consumer | Kafka에서 데이터를 읽는 역할 (구독자) |
| Broker | 메시지를 저장하고 전달하는 Kafka 서버 |
| Topic | 메시지를 분류하는 논리적 단위 |
| Partition | Topic을 나눈 물리적 단위 (병렬 처리) |
| Offset | 각 메시지의 고유 순번 (Consumer가 어디까지 읽었는지 기억함) |
| Zookeeper | Kafka 브로커의 메타데이터 관리 (2.x까지 필수, 3.x부터는 선택) |
프로젝트 내 Kafka의 역할
가상 센서 데이터 흐름을 실시간으로 Kafka를 통해 흘려보내고, Kafka가 데이터를 중간에서 중개자 역할을 수행하였습니다.
sensor_generator.py → producer.py → [Kafka Topic: sensor_data] → consumer.py → InfluxDB
Kafka 관련 주요 파일 역할
| 파일 경로 | 역할 |
| producer/producer.py | Kafka Producer. 센서 데이터를 생성하고 Kafka로 전송 |
| consumer/consumer.py | Kafka Consumer. Kafka에서 메시지를 읽고 InfluxDB에 저장 |
| consumer/config.py | Kafka 서버 주소, 토픽 이름 등 환경설정 |
| .env | 환경변수를 외부 파일로 분리 (보안, 유지보수 측면) -> (보안으로 github 내 확인 불가) |
| docker-compose.yml | Kafka, Zookeeper를 컨테이너로 구동 (포트, 네트워크 설정 포함) |
Kafka를 사용하며 배운 점과 느낀 점
1. 메시지 브로커의 필요성 실감
이번 프로젝트 이전까지는 센서 데이터 → 바로 DB 저장이라는 구조만 익숙했지만, Kafka 도입을 통해 "중간 브로커를 둔 설계가 얼마나 유연하고 견고한지"를 체감할 수 있었습니다.
센서 데이터가 한쪽에서 쏟아져 들어오고, 다른 쪽에선 데이터를 다양한 방식으로 소비할 수 있는 구조에서 분산 시스템의 기본 흐름을 Kafka를 통해 실무적인 시선으로써 확인해볼 수 있었습니다.
2. Producer/Consumer의 명확한 역할 분리 이해
Producer는 데이터를 보내는 데만 집중하고, Consumer는 Kafka에서 데이터를 읽어서 DB에 저장하는 데만 집중합니다.
이러한 역할의 분리로 인해 서로 영향을 주지 않고 독립적으로 개발 및 운영이 가능했으며, 장애도 서로 전파되지 않아 더 안정적인 시스템을 설계할 수 있었음을 배웠습니다.
3. 실전에서의 Kafka 구성 요소를 직접 다뤄보기
가장 중요한 요소 중 하나로써 Kafka 개념 공부로는 모호했던 것들이 직접 Docker-Compose와 Zoopkeeper를 띄우고, producer.py와 consumer.py를 개발하면서 명확해짐을 체감하였습니다.
4. 실시간 스트리밍 파이프라인의 진짜 의미 체득하기
Kafka → Consumer → InfluxDB → Grafana로 연결된 흐름을 실시간으로 데이터가 흐르는 스트리밍 파이프라인으로 구축해 보니 각 구성 요소가 어떤 책임을 갖고 있는지, 데이터 흐름을 어떻게 추적하고 디버깅해야 하는지, 시스템 병목이 어디서 발생하는지를 직접 실습하며 체감할 수 있었다.
참고 URL
- 개인 사이드 프로젝트 Repo: https://github.com/givemechocopy/iot-kafka-streaming-project
GitHub - givemechocopy/iot-kafka-streaming-project: [Personal-Side Project #01] Virtual Real-Time IoT Sensor Data Streaming
[Personal-Side Project #01] Virtual Real-Time IoT Sensor Data Streaming - givemechocopy/iot-kafka-streaming-project
github.com
- Apache Kafka - Overview: https://blog.det.life/apache-kafka-overview-b04c4ab8ef49
Apache Kafka — Overview
The terminology and the architecture.
blog.det.life
- 데브필(DevPill): https://maily.so/devpill/posts/g0zm85weoql
메시지 큐? 이제 Kafka로 끝내세요
복잡한 분산 시스템 아키텍처가 단숨에 이해되는 Kafka 완전 정복
maily.so
Kafka 메시지 중복 및 유실 케이스별 해결 방법 | 올리브영 테크블로그
올리브영 WMS 인터페이스 개편 과정에서 Kafka 메시지의 중복 및 유실을 방지한 고가용성 보장 방법 대공개!
oliveyoung.tech
'📊 Data Engineering' 카테고리의 다른 글
| [Data Engineering] 데이터 웨어하우스와 ETL/ELT는 어떻게 구성되는가? (0) | 2025.05.12 |
|---|---|
| [Data Engineering] 데이터 팀의 역할과 조직은 어떻게 구성되는가? (1) | 2025.05.12 |
| [Data Engineering] 개인 사이드 프로젝트#01 복기 2편 (feat. influxdb란?) (3) | 2025.04.30 |
| [Data Engineering] 데이터 파이프라인이란? (0) | 2025.04.27 |
| [Data Engineering] 데이터 엔지니어란? (0) | 2025.04.27 |