본문 바로가기

Spark

[부록] Jupyter ( IPython ) 에서 pyspark 사용하기


참조 링크 : http://blog.cloudera.com/blog/2014/08/how-to-use-ipython-notebook-with-apache-spark/


일단 IPython 과 PySpark 가 깔려 있어야 한다.

$ ipython profile create pyspark

 이라고 치면 ~/.ipython/profile_pyspark 라는 폴더가 자동으로 생성되고 안에 내용이 채워진다.


그럼 config 파일을 열고 ( 위 사이트처럼 ipython_notebook_config.py 파일을 생성해도 되고 그냥 ipython_config.py 에 잘 써넣어도 된다. )

c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8880 # or whatever you want; be aware of conflicts with CDH

python notebook 에 비밀번호를 걸기를 원한다면

$ python -c 'from IPython.lib import passwd; print passwd()' > ~/.ipython/profile_pyspark/nbpasswd.txt

위 명령어를 치고 아까 추가했던 ipython_config.py 파일에 아래 내용을 추가한다.

PWDFILE='~/.ipython/profile_pyspark/nbpasswd.txt'
c.NotebookApp.password = open(PWDFILE).read().strip()

이렇게까지 해놓고 위 링크에서는 shell.py 를 실행시켜서 하는 방법들을 설명하는데 저 방식대로 해보니 이상한 버그가 하나 있더라... ( 이게 내가 하는 버전만 그런건지는 모르겠는데...)

from __future__ import unicode_literals
import os
import sys
if sys.version_info < (3,):
    #from __future__ import unicode_literals
    reload(sys)
    sys.setdefaultencoding("utf-8")
 
SPARK_HOME = '/bin/spark-xxx-bin-x.x.x-cdhx.x.x'
dep_jars = ['/app/hive/lib/mysql-connector-java-x.x.x-bin.jar',]
 
def yarnclient_spark():
    boot_spark('yarn-client','2g')
 
def boot_spark(master, driver_mem):
    MASTER=master
    DRIVER_MEM=driver_mem
    EXECUTOR_CORES=2
    NUM_EXECUTORS=4
    QUEUE='default'
    EXECUTOR_MEM='2g'
    PYSPARK_OPT=' --master=%s ' % MASTER +\
    '  --driver-memory %s ' % DRIVER_MEM +\
    '  --executor-cores %s ' % EXECUTOR_CORES +\
    '  --num-executors %s ' % NUM_EXECUTORS +\
    '  --queue %s ' % QUEUE +\
    '  --executor-memory %s ' % EXECUTOR_MEM +\
    '  --deploy-mode client ' +\
    '  --jars %s ' % ','.join(dep_jars) +\
    'pyspark-shell'
    print(PYSPARK_OPT)
 
    os.environ['SPARK_HOME'] = SPARK_HOME
    os.environ['PYSPARK_PYTHON'] = '/bin/python/bin/python'
    os.environ['IPYTHON'] = '1'
    os.environ['PYSPARK_SUBMIT_ARGS'] = PYSPARK_OPT
    #os.environ['PYSPARK_DRIVER_PYTHON_OPTS'] = 'notebook'
    sys.path.insert(0, os.path.join(SPARK_HOME, 'python'))
    sys.path.insert(0, os.path.join(SPARK_HOME, 'python/lib/py4j-0.9-src.zip'))
    sys.path.insert(0, os.path.join(SPARK_HOME, 'python/lib/pyspark.zip'))
    spark_cmd = os.path.join(SPARK_HOME, 'python/pyspark/shell.py')
    print(spark_cmd)
    if sys.version_info < (3,):
        execfile(os.path.join(SPARK_HOME, 'python/pyspark/shell.py'), globals())
    else:
        exec(compile(open(spark_cmd).read(), 'shell.py', 'exec'), globals())

위에 pyspark 를 셋팅하는 식을 실행시키고 나서

In [1] : print("hello wolrd")


이렇게 실행시키면 Out [1] : hello world 라는 문구가 안나온다. 왜냐면 kernel 이 pyspark kernel 로 넘어가서 server 에서 돌고 있는 pyspark 로 커널이 넘어가서 실행되기 때문이다. 그래서 서버에서 직접 print( system output ) 를 봐야 되는 괴기한 상황이 발생한다. 

이를 해결하고자 직접 jupyter kernel 에 pyspark 을 붙이기로 결심했다.


참고 URL : http://thepowerofdata.io/configuring-jupyteripython-notebook-to-work-with-pyspark-1-4-0/ 


$ mkdir -p ~/.ipython/kernels/pyspark
$ touch ~/.ipython/kernels/pyspark/kernel.json

kernel.json

{
	"display_name": "pySpark (Spark 2.1.0)", 
	"language": "python", 
	"argv": [ 
		"/usr/bin/python", 
		"-m", 
		"ipykernel", 
		"-f", 
		"{connection_file}"
	], 
	"env": { 
		"SPARK_HOME": "{{your_spark_home_path}}", 
		"PYTHONPATH": "{{your_spark_home_path}}/python/:{{your_spark_home_path}}/python/lib/py4j-0.10.6-src.zip:{{your_spark_home_path}}/python/lib/pyspark.zip", 
		"PYSPARK_PYTHON" : "usr/bin/python",
		"PYSPARK_DRIVER_PYTHON" : "jupyter",
		"PYSPARK_DRIVER_PYTHON_OPTS" : "notebook",
		"PYTHONSTARTUP": "{{your_spark_home_path}}/python/pyspark/shell.py", 
		"PYSPARK_SUBMIT_ARGS": "--master=yarn-client --name 'pyspark.jupyter' --driver-memory 2g --executor-cores 2 --num-executors 4 --executor-memory 2g --deploy-mode client pyspark-shell" 
	}
}


이런식으로 kernel 파일을 생성하고


ipython 을 실행시킨다.

$ ipython notebook --config='~/.ipython/profile_pyspark/ipython_config.py'
이러면 8880 포트에서 jupyter가 뜨는 것을 볼수 있다.


오른쪽에 New 버튼을 눌러 notebook 을 추가하려고 하면




default 로 존재하는 python2 뿐 아니라 pySpark 가 추가됨을 볼 수있다.



그리고 이렇게 실행할 수가 있다. :) 

으아 진짜 낼부턴 pyspark 로 코딩 겁나해야지!!!


개인적으로 개발환경 셋팅에 엄청 시간을 쏟는 편이다. 실제로 본인이 해본결과 이게 나중에 작업할때도 덜 스트레스 받고 덜 짜증난다. 그리고 실제로 효율도 훨씬 빨라지는 느낌이 든다. 

spark 작업시에 회사 정책상 쫌 힘든게 java 나 scala 로 작업시 build 하고 빌드한 jar 파일을 서버에 올려서 돌려야 하는 번거로움이 있다. 그러다 보니 테스트 환경이 구리다(?) 는 생각이 쫌 들고 나 처럼 멍청한 사람은 뭔가 진도가 너무 더디다는 느낌이 있다. ( 사실 java 와 scala 로 spark 작업이 더 많은 이점을 가져다 주기도 한다.) 여튼 일반적인 환경이라면 나도 scala 나 java 를 쓰겠는데 뭔가 디버깅을 못한다는 사실이 너무 답답하고 매번 돌리다 실패하는 과정이 많은 나에겐 한방에 build & running 이란 꿈과 같은 존재라... 이런 삽질을 통해 jupyter 에서 간단하게 spark 를 써보자는 생각을 하게 되었다. :) 


*** pyspark 보다 java, scala spark 이 나은 이유라고 언급한 문서의 내용 참조 링크

-  http://www.cloudera.com/documentation/enterprise/5-5-x/topics/spark_python.html 




나중에 쫌 작업을 해보고 이게 얼마나 큰 이점을 가져다 주는지 한번 후기로 남겨볼 생각이다.