Apache Beam 실무 스터디 가이드

데이터 엔지니어 · 데이터 사이언티스트를 위한 핵심 요약

데이터 엔지니어 데이터 사이언티스트 Unified Processing Batch Stream

1. Apache Beam이란?

Apache Beam은 배치(batch)와 스트리밍(stream) 데이터 처리를 통합적으로 지원하는 오픈 소스 통합 프로그래밍 모델입니다. Google의 Dataflow SDK에서 시작되어 Apache 프로젝트로 발전했습니다. Beam을 사용하면 한 번의 코드로 다양한 실행 환경(Runner)에서 파이프라인을 실행할 수 있습니다.

주요 특징은 언어 독립성, 런너 포터빌리티, 통합 처리(unified processing)입니다. 데이터 엔지니어와 데이터 사이언티스트가 대규모 데이터 ETL, 실시간 분석, ML 파이프라인을 구축할 때 필수적입니다.

Unified Processing

배치와 스트리밍을 하나의 모델로 처리. Windowing, Triggering으로 스트리밍 지연 문제를 해결.

Portable Runners

DirectRunner(로컬), Dataflow(Google Cloud), Flink, Spark 등 다양한 러너 지원. 코드 변경 없이 배포.

Multi-Language SDK

Python, Java, Go, Scala 지원. Python SDK가 가장 직관적이며 실무에서 인기.

실무 적용 예: 일별 배치 보고서와 실시간 대시보드를 하나의 Beam 파이프라인으로 구현.

2. 왜 써야 하는가?

전통적인 도구들은 배치(Spark)와 스트리밍(Flink)을 별도로 관리해야 하지만, Beam은 통합합니다. 비용 효율적이고 유지보수가 쉽습니다.

기능 Apache Beam Apache Spark Apache Flink Kafka Streams
Batch + Stream ✅ 통합 ❌ 별도 (Spark Streaming) ✅ 통합 ❌ Stream만
Runner 포터빌리티 ✅ Dataflow, Flink 등 ❌ Spark 전용 ❌ Flink 전용 ❌ Kafka 전용
Python 지원 ✅ 네이티브 ✅ PySpark ✅ PyFlink ❌ Java/Kotlin
Windowing 유연성 ✅ Session, Sliding ⚠️ 제한적 ✅ 고급 ✅ 기본
클라우드 네이티브 ✅ Google Dataflow 최적화 ✅ EMR 등 ✅ EKS 등 ✅ MSK
주의: Spark 사용자라면 Beam의 DoFn이 MapReduce-like하지만, 상태 관리(Stateful Processing)가 Flink만큼 강력하지 않음.

3. 핵심 개념

Beam의 세계관은 Pipeline → PCollection → Transform → Runner로 구성됩니다.

주요 개념

아키텍처 다이어그램 (ASCII)

PCollection ──[Read]──> Pipeline ──[ParDo/Map]──> PCollection ──[GroupByKey]──> PCollection │ │ │ │ └─[IO: Kafka/GCS] └─[Window/Trigger] └─[Combine/Sum] └─[IO: BigQuery/Sink] │ └─ Runner (Direct/Dataflow/Flink) │ └─[Bundle/Worker] ──> Executors

위 다이어그램에서 Pipeline은 논리적 그래프, Runner가 물리적 실행을 담당합니다.

4. 퀵스타트

1. 설치

pip install apache-beam[interactive]  # 로컬 테스트용
pip install apache-beam[gcp]  # Google Cloud용

2. 첫 예제: WordCount (Batch)

import apache_beam as beam

with beam.Pipeline() as pipeline:
    (
        pipeline
        | 'Read' >> beam.io.ReadFromText('input.txt')
        | 'FindWords' >> beam.FlatMap(lambda line: line.split())
        | 'PairWords' >> beam.Map(lambda word: (word, 1))
        | 'Group' >> beam.CombinePerKey(sum)
        | 'Format' >> beam.Map(lambda word_count: f"{word_count[0]}: {word_count[1]}")
        | 'Write' >> beam.io.WriteToText('output')
    )

3. CLI로 실행 (DirectRunner)

python -m your_pipeline \
  --input=gs://bucket/input.txt \
  --output=gs://bucket/output \
  --runner=DirectRunner

4. 스트리밍 예제 (Pub/Sub → BigQuery)

options = beam.options.pipeline_options.PipelineOptions(
    flags=[
        '--runner=DataflowRunner',
        '--project=your-project',
        '--region=us-central1',
        '--streaming'
    ])

with beam.Pipeline(options=options) as p:
    (p
     | 'ReadPubSub' >> beam.io.ReadFromPubSub(topic='projects/.../topics/your-topic')
     | 'ParseJSON' >> beam.Map(lambda x: json.loads(x))
     | 'Window' >> beam.WindowInto(beam.window.FixedWindows(60))
     | 'Group' >> beam.GroupByKey()
     | 'WriteBQ' >> beam.io.WriteToBigQuery('project:dataset.table'))
p.run()
팁: 로컬 테스트는 DirectRunner, 프로덕션은 DataflowRunner 사용.

5. 핵심 설정 레퍼런스

옵션 설명 예제 런너
--runner 실행 엔진 지정 DirectRunner / DataflowRunner 모두
--project GCP 프로젝트 ID --project=my-project Dataflow
--region 클라우드 리전 --region=asia-northeast3 Dataflow
--streaming 스트리밍 모드 --streaming Dataflow/Flink
--max_num_workers 최대 워커 수 --max_num_workers=10 Dataflow
--temp_location 임시 스토리지 --temp_location=gs://bucket/temp Dataflow
--experiments=use_runner_v2 실험적 기능 Runner V2 활성화 Dataflow

6. 실무 팁 & 트러블슈팅

팁

자주 겪는 문제

문제 1: "No module named 'apache_beam'"
해결: pip install --upgrade apache-beam[gcp] 재설치.
문제 2: Dataflow "Permission Denied"
해결: GCS 버킷에 Dataflow Service Account 권한 부여 (Storage Object Admin).
문제 3: Late Data 누락
해결: Trigger(AfterWatermark().withAllowedLateness()) 추가.
문제 4: OOM (Out of Memory)
해결: --machine_type=n1-standard-4 업그레이드 또는 ParDo 배치 크기 조정.

실무에서 80% 문제는 권한/스토리지 설정입니다.

7. 참고 자료