data engineering

spark 로컬 테스트 관련.

qkqhxla1 2018. 2. 20. 10:31

난 spark를 hue안에서 코딩하는거로 처음 접해서 아래와 같이 메모장같은 불편한곳에서 코딩을 했다.

일단 바빠서 그냥 저기에 코딩을 하지만, 당연히 인텔리제이같은 ide에 익숙해져서 너무 불편하다. 심지어 '를 하나 빼먹는다거나 해도 틀렸다고 말을 안해준다. 거기에 한번 잘 돌아가는지 테스트하는데 드는 비용이 너무 크다. 프로세스 탭에 가서 로그를 살펴보고 어쩌구...


처음에는 급해서 그냥 저 위에서 짰다. 알고리즘적으로 검증이 필요한 부분은 spark를 다운받아서 pyspark를 실행시킨 후 쉘에서 한줄 한줄.. 실행시켜가며 로직을 확인 후 코드에 넣고 돌려봐서 검증. 하는 식으로 했었는데.. 뭔가 코드는 자꾸 틀리고, 어디가 틀리는지 확인하기도 힘들고 한번 돌리는게 너무 짜증나서 로컬에서 테스트를 해야할 필요성을 느꼈다.

쉬운 테스트의 조건을 생각해보니. 

1. 로컬에서 빠르게 실행시켜볼수있어야 하고 

2. 문법 에러등이 있으면 알수 있게 ide에서 코드를 짤수 있어야 한다. 였다.(pyspark쉘에서 프로그래밍을 해보면 얼마나 짜증이 나는지 알것임. 함수같은경우 한줄만 틀려도 다시 짜야된다.)


구글링하던 도중 https://had00ping.wordpress.com/2017/11/14/setting-intellij-for-pyspark/ 를 발견했다.

하지만 현재 파이썬 2.7을 쓰고있고, 3.6을 깔고 환경변수 설정하다 보면 뭔가 꼬일수도 있다는 두려움과... 맥에서 환경변수 설정이 제대로 안되서 포기했다. 

아직까지 모르겠는데 왜 맥에서는 export가 잘 안먹는지, 왜 환경변수 설정시 언제는 launchctl setenv ~~ 명령어로 해야하는지 아직 차이를 잘 모르겠다. 환경변수가 설정되도 해당 열려있는 터미널에만 적용된다거나 한다. .bash_profile에 넣는것도 안되고..(뭔가 인텔리제이에서 인식을 못함. 아니면 인텔리제이를 껐다 켜야 인식된다던가.)

하여튼 환경변수 설정관련 삽질을 하다 또 포기하고 이것저것 찾아보다가

https://stackoverflow.com/questions/23256536/importing-pyspark-in-python-shell 요 글을 발견했다.


findspark라는 모듈을 사용하라는건데... https://github.com/minrk/findspark

아주아주아주 간단하다. 맥 기준으로 brew install apache-spark로 spark를 설치한다.
그럼 스파크 경로는 대부분 /usr/local/opt/apache-spark/libexec에 저장된다. (알아만 두기)


findspark를 설치 후 pyspark를 임포트하기전에 findspark.find()를 실행시켜 주기만 하면 된다.

import findspark
findspark.init()

from pyspark import SparkConf, SparkContext


sconf = SparkConf().setAppName("PySpark")
sconf.set('spark.kryoserializer.buffer.max', '1024')
sparkContext = SparkContext(conf=sconf)

a = sparkContext.parallelize(['1','1','2','3','1','2']).distinct()

print a.collect()

겨우 이거 하나 찾으려고 고생했다..

또 하둡 서버에서 스파크를 돌리는것과 로컬에서 하둡 서버로 연결해서 돌리는건 차이가 있다. 예를들어 하둡 파일 시스템에 접근할 때이다. 네임 노드 주소를 알아야 접근을 할 수 있어서 여기저기 돌아다니며 config정보를 찾아봤다. 구글링결과로
– /etc/hosts
– core-site.xml
– hdfs-site.xml
– mapred-site.xml
– yarn-site.xml
– slaves
가 중요한 config리스트라는걸 알 수 있었고 저기를 뒤적여 namenode 주소를 찾을 수 있었다.

테스트 환경이 원격 서버에서 직접 하다가 로컬로 왔으니 hdfs주소도 다르게 써야 한다.
pyspark에서 로컬에서 원격으로 일반적으로 접속할때 쓰는 방법이다.

from pyspark import SparkConf, SparkContext

sconf = SparkConf().setAppName("PySpark")
....
sparkContext = SparkContext(conf=sconf)
path = 'hdfs://10.10.10.10:8020/a/b/c/aaa.csv'
f = sparkContext.textFile(path)

path를 위처럼 hdfs://네임노드주소:하둡 포트/절대경로 로 줘야 한다. 테스트를 완료하고 코드를 서버에 직접 올렸을때, 문제가 있다. 네임노드가 바뀔 때마다 네임노드주소를 바꿔줘야 한다는것이다.(사실 그리 자주 바뀔일이 없긴 하지만.)

서버에 올리기 전에는 path = 'hdfs:/절대경로'(위의 경우에는 hdfs:/a/b/c/aaa.csv) 이런식으로 /네임노드주소를 생략해서 서버에 올려주면 서버에서 알아서 네임노드 주소를 인식해서 폴더를 찾아간다.