Spark 에서 S3 데이터 삽질기

AWS V4 API만 제공되는 리전에서 Spark 에서 S3 데이터 읽기

최근 회사의 인프라가 매우 크게 변동하게 되었다. 서비스 인프라는 AWS에서 IDC로 이동하고 내가 관여하는 분석 인프라는 AWS 싱가폴 리전에서 뭄베이 리전으로 이동하게 되었다.

여러 정책으로 인해 기존에 Java(Spring)으로 제작해둔 BI용 숫자 뽑는 프로그램도 더이상 쓰지 못하게 되는 상황이 되었고 이를 Pyspark로 새로 제작하게 되었다. 이 과정에서 S3와 관련된 삽질을 공유하고자 한다.

새 어플리케이션의 제작 과정 계획은

  1. 기존 싱가폴 리전에서 기존 싱가폴 S3 버킷을 바라보는 환경에서 작업하고
  2. 싱가폴 S3 버킷에서 뭄베이 S3 버킷으로 이동하고
  3. 어플리케이션을 뭄베이 리전으로 이동

으로 생각하고 개발을 시작했다. 우선 S3 싱가폴 버킷을 보는 Spark 어플리케이션을 제작했다.

나중에 리전과 버킷만 바꾸면 될거라 예상했다. 하지만 제대로 동작하지 않고 400 Bad Request 를 뿜어냈다.

이후 구글링을 통해 AWS API들이 API Signagure 로 인해 버전이 존재한다는 사실을 알게 되었다. 그리고 내가 추가한 hadoop-aws 라이브러리의 기본 동작이 V2라는 것을 알게 되었다. API 와 관련된 내용은 문서를 보면 된다.

물론 당장 문제를 해결하지 않고 개발환경 및 버킷을 뭄베이로 이전해서 작업하면 되지만 로컬환경에서 동작해야 개발과 이후의 테스트 과정에서 편할 것이라 생각해 바로 해결해야 했다. (그리고 뭄베이 리전의 SSH 접속을 붙어있는 환경은 너무 느렸다.)

아래 코드는 S3 요청시 V4를 활성화 하는 부분의 코드다. 이를 적용하면 로컬환경 또는 V4 전용 리전이 아닌 리전(싱가폴 리전은 V2와 V4 둘다 제공)에서 V4 전용 리전으로 S3 요청시 에러가 발생하지 않고 정상적으로 동작한다.

import pyspark
from pyspark.sql import SparkSession
# Initialize Spark Context
sc = pyspark.SparkContext(appName='YOUR_APP_NAME')
sc.setSystemProperty('com.amazonaws.services.s3.enableV4', 'true')
hadoop_config = sc._jsc.hadoopConfiguration()
hadoop_config.set('fs.s3a.impl', 'org.apache.hadoop.fs.s3a.S3AFileSystem')
hadoop_config.set('com.amazonaws.services.s3.enableV4', 'true')
hadoop_config.set('fs.s3a.access.key', 'YOUR_AWS_ACCESS_KEY_ID'))
hadoop_config.set('fs.s3a.secret.key', 'YOUR_AWS_SECRET_ACCESS_KEY')
hadoop_config.set('fs.s3a.endpoint', 's3.(YOUR_SERVICE_S3_BUCKET_REGION).amazonaws.com')
spark = SparkSession(sc)
# do something
spark.stop()

참고한 링크들

TECH | 08 Dec 2017 by ungikim