LoginSignup
16
15

More than 5 years have passed since last update.

EMR上でPython3系でpysparkする

Posted at

概要

  • 機械学習・データサイエンスといえばpython(numpy/iPython/scikit-learn)なのでpythonで書いていきたい。
  • しかし、仕事柄大規模なデータを扱うことになるので、分散できるsparkのAPIで取り扱いたい。

  • ということで(EMR)クラスタ上でpysparkを動かしてみます。

  • 今からpython学ぶなら3系だろうということで3系(Anaconda3-4.0)で動かします。

  • 不安だったので確認したけど、sparkは1,4からpython3系に対応してますね。


手順

基本的にこちらの記事を参考にしました。丁寧に書かれていて素晴らしいです。

Spark + IPython環境をAmazon EMR上で構築し、簡単なData解析を動かして見る (第1回:環境構築編)

  • スクリプト準備
  • EMRクラスタ立ち上げ
  • iPython Notebook起動
  • 動作確認

スクリプト準備

以下の2つのshellを用意します。

  • EMRのbootstrap時に全ノードにanaconda3を入れるためのスクリプト
anaconda3-bootstrap.sh
#Environments
ANACONDA_VERSION=3-4.0.0

PYENV=~/.pyenv
PYENV_BIN=$PYENV/bin


##Install git and Anaconda
sudo yum -y install git
git clone https://github.com/yyuu/pyenv.git $PYENV

echo -e "\nexport PYENV_ROOT=$PYENV" | tee -a ~/.bash_profile  >> /dev/null
echo -e "\nexport PATH=$PYENV_BIN:$PATH" | tee -a ~/.bash_profile  >> /dev/null
echo -e "\neval '$($PYENV_BIN/pyenv init -)'" | tee -a ~/.bash_profile  >> /dev/null
source ~/.bash_profile

pyenv install anaconda$ANACONDA_VERSION
pyenv rehash
pyenv global anaconda$ANACONDA_VERSION

echo -e "\nexport PATH='$PYENV/versions/anaconda$ANACONDA_VERSION/bin/:$PATH'" | tee -a ~/.bash_profile  >> /dev/null
source ~/.bash_profile
conda update --yes conda

##Install addtional python libraries
conda install --yes seaborn
  • MasterNodeでiPyhtonの設定を行うスクリプト
setup-iPython.sh
#Environments
SPARK_PACKAGES=com.databricks:spark-avro_2.10:2.0.1,com.databricks:spark-csv_2.10:1.4.0
ANACONDA_VERSION=3-4.0.0
JUPYTER_LOG=/home/hadoop/.jupyter/jupyter.log

PYENV=~/.pyenv
PYENV_BIN=$PYENV/bin

##Configure Jupyter
jupyter notebook --generate-config

JUPYTER_NOTEBOOK_CONFIG=/home/hadoop/.jupyter/jupyter_notebook_config.py
sed -i -e "3a c.NotebookApp.ip = '*'" $JUPYTER_NOTEBOOK_CONFIG
sed -i -e "3a c.NotebookApp.open_browser =False" $JUPYTER_NOTEBOOK_CONFIG
sed -i -e "3a c.NotebookApp.port = 8080" $JUPYTER_NOTEBOOK_CONFIG
sed -i -e "3a c = get_config()" $JUPYTER_NOTEBOOK_CONFIG

IPYTHON_KERNEL_CONFIG=/home/hadoop/.ipython/profile_default/ipython_kernel_config.py
ipython profile create
sed -i -e "3a c.InteractiveShellApp.matplotlib = 'inline'" $IPYTHON_KERNEL_CONFIG


##Launch Jupyter by executing "pyspark"
JUPYTER_PYSPARK_BIN=/home/hadoop/.jupyter/start-jupyter-pyspark.sh

cat << EOF > $JUPYTER_PYSPARK_BIN
export SPARK_HOME=/usr/lib/spark/
export PYSPARK_PYTHON=$PYENV/versions/anaconda$ANACONDA_VERSION/bin/python
export PYSPARK_DRIVER_PYTHON=ipython
export PYSPARK_DRIVER_PYTHON_OPTS='notebook'
export SPARK_PACKAGES=$SPARK_PACKAGES
nohup pyspark --packages $SPARK_PACKAGES > $JUPYTER_LOG 2>&1 &
EOF

chmod +x $JUPYTER_PYSPARK_BIN

EMRクラスタ立ち上げ

基本は上記参考記事のままなのですが、

  • BootStrapActionで上記のanaconda3-bootstrap.shを読ませる。
  • とりあえず使うときはSpot Instanceを使うと安いよ。
  • Security-Groupは、とりあえず自分のマシンからMasterNodeにsshログインさえできればOK。
    • 実運用ではEMRを外に晒したくないので踏み台とか経由すると思います
    • が、ちょいと面倒なので、とりあえずKeyがないとsshできなくて、他のportが空いてなければいいかなと。
    • CoreNodeはとりあえずEmrManagedSlaveSecurityGroupを使っとけば大丈夫。

設定例の全体はこんな感じ。

aws emr create-cluster --applications Name=Hadoop Name=Spark Name=Ganglia --bootstrap-actions '[{"Path":"s3://<bucket>/anaconda3-bootstrap.sh","Name":"Custom action"}]' --ec2-attributes '{"KeyName":"","AdditionalSlaveSecurityGroups":[],"InstanceProfile":"EMR_EC2_DefaultRole","SubnetId":"","EmrManagedSlaveSecurityGroup":"","EmrManagedMasterSecurityGroup":""}' --service-role EMR_DefaultRole --enable-debugging --release-label emr-4.7.2 --log-uri '' --name 'jupyter pyspark' --instance-groups '[{"InstanceCount":1,"BidPrice":"0.1","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"SizeInGB":32,"VolumeType":"gp2"},"VolumesPerInstance":1}]},"InstanceGroupType":"MASTER","InstanceType":"m4.large","Name":"Master instance group - 1"},{"InstanceCount":2,"BidPrice":"0.1","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"SizeInGB":32,"VolumeType":"gp2"},"VolumesPerInstance":1}]},"InstanceGroupType":"CORE","InstanceType":"m4.large","Name":"Core instance group - 2"}]' --configurations '[{"Classification":"spark","Properties":{"maximizeResourceAllocation":"true"},"Configurations":[]}]' --region ap-northeast-1


iPython Notebook起動

立ち上げた後、MasterNodeにSSHして、上記のsetup-iPython.shを流し、

$JUPYTER_PYSPARK_BINを実行すればiPython notebookが立ち上がります。

後は自分のマシンから
ssh -i ~/.ssh/my.pem -ND 8157 hadoop@ec2-XXXX.comのようにsshトンネリングを行い、ブラウザにproxyを立てればOK(やり方はEMRに書いてある)

ブラウザからhttp://ec2-XXXX.com:8080に繋げたら設定完了。


動作確認

こんな感じになりました。試しにKMeansをscikit-learnと比較してみました。


まとめ

  • EMR使うとクラスタ上でのpyspark環境が楽に用意できますよ。
  • ただ、sparkContext張りっぱなしなので一度に複数のNOTEBOOKは操作できないかも。
  • iPyhtonで試して、上手く行ったらそれをそのままScalaに直して実運用!とかできそう。
  • MasterNodeにもWorkerNodeにもPython3系が必要です
    • もしバージョンが合ってないと実行時に怒られます。
16
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15