← 목록으로
단계 09

Spark + HDFS / S3 연동

저장소와 처리 엔진을 잇기 — HDFS 경로 읽기, S3 인증(s3a)과 경로, MinIO로 로컬 S3 실습.

큰 그림

지금까지 저장(5단계)처리(7단계) 를 따로 배웠습니다. 이제 둘을 연결합니다. 핵심은 경로의 scheme만 바뀌고 코드는 같다는 것.

spark.read.parquet("file:///data/sales.parquet")    # 로컬
spark.read.parquet("hdfs://namenode:9000/data/sales.parquet")   # HDFS
spark.read.parquet("s3a://my-bucket/data/sales.parquet")        # S3

HDFS 연동 (12주차)

준비 (Docker)

git clone https://github.com/big-data-europe/docker-hadoop
cd docker-hadoop && docker compose up -d
# NameNode UI: http://localhost:9870
docker exec -it namenode bash
hdfs dfs -mkdir -p /data
hdfs dfs -put /tmp/sales.csv /data/
hdfs dfs -ls /data

Spark에서 읽기

spark = (SparkSession.builder.appName("hdfs")
         .config("spark.hadoop.fs.defaultFS", "hdfs://localhost:9000")
         .getOrCreate())

df = spark.read.csv("hdfs://localhost:9000/data/sales.csv", header=True, inferSchema=True)
df.groupBy("region").sum("amount").show()
df.write.parquet("hdfs://localhost:9000/data/sales_parquet")

S3 연동 (13주차)

개념

  • 버킷(bucket): 최상위 컨테이너. 전 세계 유일한 이름
  • 키(key): data/2026/08/sales.parquet — 폴더처럼 보이지만 실은 문자열
  • 인증: Access Key ID + Secret Access Key (또는 IAM 역할)
  • Spark는 s3a 커넥터(hadoop-aws)로 접근

로컬 실습: MinIO (S3 호환)

docker run -d -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=minio -e MINIO_ROOT_PASSWORD=minio123 \
  quay.io/minio/minio server /data --console-address ":9001"
# 콘솔 http://localhost:9001 → 버킷 "lake" 생성, 파일 업로드

Spark 설정

spark = (SparkSession.builder.appName("s3")
  .config("spark.jars.packages", "org.apache.hadoop:hadoop-aws:3.3.4")
  .config("spark.hadoop.fs.s3a.endpoint", "http://localhost:9000")   # 실제 AWS면 생략
  .config("spark.hadoop.fs.s3a.access.key", "minio")
  .config("spark.hadoop.fs.s3a.secret.key", "minio123")
  .config("spark.hadoop.fs.s3a.path.style.access", "true")           # MinIO용
  .getOrCreate())

df = spark.read.csv("s3a://lake/sales.csv", header=True, inferSchema=True)
df.groupBy("region").sum("amount").show()
df.write.mode("overwrite").parquet("s3a://lake/cleaned/sales/")

자격 증명은 코드에 직접 쓰지 말고 환경변수(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)나 ~/.aws/credentials로. GitHub에 키가 올라가면 몇 분 안에 악용됩니다.

boto3로 직접 다루기

import boto3
s3 = boto3.client("s3", endpoint_url="http://localhost:9000", aws_access_key_id="minio", aws_secret_access_key="minio123")
s3.upload_file("sales.csv", "lake", "sales.csv")
for obj in s3.list_objects_v2(Bucket="lake")["Contents"]:
    print(obj["Key"], obj["Size"])

연습 과제

  1. 같은 sales.csv를 로컬·HDFS·S3(MinIO)에 올리고, 경로만 바꿔 동일한 집계 실행
  2. 결과를 각 저장소에 Parquet으로 저장하고 파일 목록 확인
  3. hadoop-aws 버전이 Spark의 Hadoop 버전과 맞지 않을 때 나는 오류를 겪어보고 해결해보기 (실무에서 가장 흔한 문제)