7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pysparkをnotebookで書けるspark clusterをかんたんに構築できるdockerfile作った

Last updated at Posted at 2019-03-07

はじめに

学部3年、現在就活中の大木です。
現在インターン先でレコメンドシステムをsparkをもちいて構築しているのですが、
EMRでsparkを動かしてゴニョゴニョする前にローカルで色々試してみたく、
またどうせならspark clusterを構築してワチャワチャやりたいと思いそのためにdockerfileを作ったので共有します。

こちら
2357gi/apache-spark-cluster: localでspark clusterを立ち上げて遊ぶ用 pyspark用のnotebookもあるヨ!

🐰使い方

cloneして

$ git clone https://github.com/2357gi/apache-spark-cluster

jupyter notebookを使いたい場合はDockerfile内の以下の環境変数を有効化して

make run &&make notebookで立ち上がります。

Dockerfile
	PYSPARK_DRIVER_PYTHON=/usr/local/bin/jupyter \
	PYSPARK_DRIVER_PYTHON_OPTS="notebook --no-browser --port 8888 --ip=0.0.0.0 --allow-root"

\で環境変数を複数行に渡り書き連ねているので、その辺を気をつけてください。

pythonfileをsubmitしたい場合は上記の環境変数に関する記述を消してmake run &&make kick-py <pythonfile>でどうぞ。

UI用のポートも開放しているので
Spark Master at spark://master:7077

Spark Jobs(spark taskが実行されている瞬間のみ)
も使えるようになっています。

解説

Dockerfile

FROM ubuntu:18.04

ベースとなるイメージはUbuntu18.04を使用しています。
採用理由は個人的に使い慣れているだけです。

python等のイメージを使用しても良かったのですが、理解しながら作業を進めたかったのであえてこちらを使用しました。

# Environment variables
ENV SPARK_VERSION=2.4.0 \
	HADOOP_VERSION=2.7 \
	SPARK_HOME=/spark \
	PATH=$SPARK_HOME/bin:$PATH \
	PYSPARK_PYTHON=/usr/bin/python3 \
	PYSPARK_DRIVER_PYTHON=/usr/local/bin/jupyter \
	PYSPARK_DRIVER_PYTHON_OPTS="notebook --no-browser --port 8888 --ip=0.0.0.0 --allow-root"

環境変数を設定します。
SPARK_VERSIONやHADOOP_VERSIONを変数として登録し、後のsparkをダウンロードする際のダウンロードUrlに変数を使用しています。
これによりバージョン変更に強くなります。

ミソとなるのがPYSPARK_PYTHON, PYSPARK_DRIVER_PYTHON, PYSPARK_DRIVER_PYTHON_OPTSです。
PYSPARK_PYTHONここでpysparkのpythonのバージョン指定を行なっています。
PYSPARK_DRIVER_PYTHON, PYSPARK_DRIVER_PYTHON_OPTSこちらでpysparkがjupyter notebookで立ち上がるように設定しています。

githubに上がっているDockerfileにはこの2種の変数の記述はないので、
もしnotebookを使用したいのであれば適宜追加してください。

notebookの引数諸々はdocker内で起動したjupyter notebookをホスト側から接続するための諸々です。
この辺はすこしセキュアではないのですが、ローカルで遊ぶだけなので許容範囲としました。

# Install required apt package and ensure that the packages were installed
RUN apt-get update && apt-get install -y \
	bc \
	curl \
	default-jdk \
	git \
	python3 \
	python3-pip \
	scala

(説明略)

# Install spark
RUN mkdir spark &&\
	curl -sL \
	http://ftp.tsukuba.wide.ad.jp/software/apache/spark/spark-${SPARK_VERSION}/spark-${SPARK_VERSION}-bin-hadoop${HADOOP_VERSION}.tgz \
	| tar zx -C spark --strip-components 1

sparkを引っ張ってきて展開し、/sparkに設置しています。
近さ的に筑波のミラーから引っ張ってきていますがココらへんはあんまりよくないかもしれません。

展開の方法ですがcurlで引っ張ってきたものをtarにパイプで渡すことによってcurl &&tar &&mv && rm などといったナンセンスなコマンドの羅列にならないように工夫しましたがココらへんは悔しさが残ります。(詳細

RUN pip3 install jupyter ipyparallel \
	&& ipcluster nbextension enable

jupyterをpipでinstallします。
pipでjupyterを導入するとpython3のkernelを読み込んでくれない?ここがすこしうまく行かなかったので
別途ipyparallelをpipでインストールしてnbextensiionをenableします。
これでjupyter notebook上でpython3がつかえるようになります。

Docker-compose

みんな大好きdocker-compose

docker-compose.yml
version: '3'

services:
  master:
    image: 2357gi/apache-spark
    hostname: master
    ports:
      - 4040:4040
      - 6066:6066
      - 8080:8080
      - 7077:7077
    environment:
        MASTER: spark://master:7077
        SPARK_CONF_DIR: /conf
        SPARK_PUBLIC_DNS: localhost
    volumes:
      - ./work:/work
      - ./data:/data
    command: /spark/bin/spark-class org.apache.spark.deploy.master.Master -h master

  worker1:
    image: 2357gi/apache-spark
    hostname: worker1
    depends_on:
     - master
    ports:
        - 8081:8081
    environment:
        SPARK_CONF_DIR: /conf
        SPARK_WORKER_CORES:
        SPARK_WORKER_MEMORY: 2g
        SPARK_WORKER_PORT: 8081
        SPARK_WORKER_WEBUI_PORT: 8081
        SPARK_PUBLIC_DNS: localhost
    volumes:
      - ./work:/work
      - ./data:/data
    command: /spark/bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077

  worker2:
    image: 2357gi/apache-spark
    hostname: worker1
    depends_on:
     - master
    ports:
        - 8082:8082
    environment:
        SPARK_CONF_DIR: /conf
        SPARK_WORKER_CORES:
        SPARK_WORKER_MEMORY: 2g
        SPARK_WORKER_PORT: 8082
        SPARK_WORKER_WEBUI_PORT: 8082
        SPARK_PUBLIC_DNS: localhost
    volumes:
      - ./work:/work
      - ./data:/data
    command: /spark/bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077

$ docker-compose up --scale worker=nでスケールするようにしたかったのですが、
ポートの変更とSPARK_WORKER_PORTの変数を連動させるのが難しかったのでこの形に落ち着きました。

誰か氏〜〜〜!w

Makefile


WORKER=1

build_docker: Dockerfile
	@echo "\n📦 build 2357gi/apache-spark"
	@docker build ./ -t 2357gi/apache-spark

build_compose:
	@echo "\n🏗  Pile up containers"
	@docker-compose up -d --scale worker=$(WORKER)

run: docker-compose.yml
	@echo "\n✨ apache-spark cluster setup is start!"
	@make build_docker
	@make build_compose
	@echo "\n🍾 set up is finished! \n you wanna access ⚡spaek shell, hit it! \n$$ make  s-shell"
	@echo "or you wanna start 📔 pyspark notebook, hit it! \n$$ make notebook"
	@echo "... if u wanna open 🐚 shell? do this. \n$$ make shell"

s-shell:
	@echo "\n⚡ start spark-shell...."
	@docker-compose exec master /spark/bin/spark-shell --master spark://localhost:7077

notebook:
	@echo "\n📔 start pyspark notebook...."
	@docker-compose exec master /spark/bin/pyspark
	@docker-compose exec

shell:
	@echo "\n🐚 start master shell...."
	@docker-compose exec master /bin/bash

WORKERを変数にすることによって$ make run WORKER=<任意のworker node数を指定できるようにしました。
あとは普通な感じです。

これは蛇足ですが、
makefileに絵文字を入れると可愛くていいですね。

7
3
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
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?