data engineering

spark processing parquet file from s3 with pass credentials.

qkqhxla1 2019. 2. 17. 13:29

회사 내에 Amazon emr cluster서버가 있고, 현재 데이터 백업용으로 s3를 쓴다. ec2의 이슈 때문에 데이터가 날라가서 데이터를 s3에서 가져와서 다시 내 몽고디비 서버에 넣어야 했다. 새로 삽질한 경험을 적어놨다. 


처음엔 단순히 내 서버에 spark를 설치 후 s3에서 데이터를 가져와 돌리려고 했다. 서버에 스파크를 설치하고, s3 parquet데이터를 가져오는 방법을 찾아보았더니 아래처럼 되었다. parquet은 파일 저장 포맷중 하나라고 한다. (https://spark.apache.org/docs/latest/sql-data-sources-parquet.html)

from pyspark.sql import SparkSession
spark = SparkSession.builder \
    .appName("spark test") \
    .getOrCreate()

df = spark.read.parquet("s3a://버킷이름/파일/파일/")

그런데 문제가 있다. 현재 내 서버에서 s3로 접근 권한이 없다는것이다. 위 코드는 s3접근권한이 있는 서버에서는 잘 동작했지만, 일반 로컬 pc등에서는 권한이 없어 동작하지 않는다. 이것저것 삽집을 한 결과 아래의 글들을 발견했다.


https://markobigdata.com/2017/04/23/manipulating-files-from-s3-with-apache-spark/

https://sungminoh.github.io/posts/development/use-s3-for-spark/

둘중 아래의 글이 더 도움되었다.(한글임.)


아래는 spark에서 s3의 데이터를 다운받기 위한 방법을 정리해놨다.

1. https://sdk-for-java.amazonwebservices.com/latest/aws-java-sdk.zip 에서 aws java sdk다운로드

2. https://talend-update.talend.com/nexus/content/repositories/libraries/org/talend/libraries/hadoop-aws-2.7.3-amzn-2/6.0.0/hadoop-aws-2.7.3-amzn-2-6.0.0.jar 에서 하둡 aws sdk 다운로드.


그리고 jar파일을 적당한 위치로 옮긴후 환경변수에 추가해주고 실행시키면 된다. 그런데 여기에 +로 나처럼 s3가 접근 권한이 있어야 하는경우에 혹시나 access key나 secret key가 있다! 싶으면 아래와 같이 설정해주면 잘 동작한다!

from pyspark.sql import SparkSession
from pyspark.conf import SparkConf

conf = SparkConf().setAll([('spark.driver.extraClassPath',
                            '/Users/go/Downloads/hadoop-aws-2.7.3-amzn-2-6.0.0.jar:'
                            '/Users/go/Downloads/aws-java-sdk-1.11.500.jar')])
spark = SparkSession.builder \
    .appName("spark test") \
    .config(conf=conf) \
    .getOrCreate()

spark._jsc.hadoopConfiguration().set('fs.s3a.access.key', 'aws 엑세스 키')
spark._jsc.hadoopConfiguration().set('fs.s3a.secret.key', 'aws 시크릿 키')
df = spark.read.parquet("s3a://버킷이름/파일/파일/")
print df.take(1)

그런데 또 삽질을 해본 결과 당연하지만 s3의 데이터가 조금 커지면(나같은경우는 한번에 3G정도 크기) 스파크의 연산시간이 오래걸린다. 얼마나 오래걸리냐면 차라리 s3의 데이터를 다운로드받고, parquet로 로컬 데이터를 읽어서 연산하는게 오히려 더 빠를정도이다.(테스트했는데 훨씬 빠름)


바로 이전 글이 s3에서 데이터를 다운받는법을 정리한 글이었는데, 차라리 다운받아서 쓰는게 더 속편하고 빠르니 이 방법을 추천해준다.