1. はじめに
Apache Sparkは巨大なデータに対して高速に分散処理を行うオープンソースのフレームワークです。
本格的に使うためには、複数のノードからなる Hadoop クラスタの構築が必要となりますが、手元のローカル環境でお試しに実行してみることも可能です。
特に spark-shell と呼ばれるツールは REPL (Read-Eval-Print-Loop) がベースになっており、Spark プログラムをインタラクティブに作成し、その場で実行結果をすぐに確認ができます。
今回は、Apache spark の Docker Image を使用し、ローカル環境で spark-shell を実行していきます。
2.(参考)実行環境
2-1. docker と docker-compose がインストールされている
それぞれがインストールされていることが前提になります。
$ docker -v
Docker version 19.03.6, build 369ce74a3c
$ docker-compose -v
docker-compose version 1.17.1, build unknown
2-2. スペック
メモリはトータルで8GB搭載されているマシンを使用しましたが、4GB程度でも問題なく動作します。
$ cat /etc/issue
Ubuntu 18.04.2 LTS
$ cat /proc/meminfo | grep Mem
MemTotal: 8168284 kB
MemFree: 6812556 kB
MemAvailable: 7545960 kB
3. docker network の作成
専用の docker network を使用し、コンテナに割り当てるIPアドレスを固定させるため、以下のコマンドで定義します。
$ docker network create spark-nw --subnet=172.30.0.0/16 --gateway=172.30.0.254
docker-compose.yml ファイル内で定義することも可能ですが、将来的に別の docker-compose.yml ファイルと共有することも想定し、敢えて予め作成する手段を取っています。
4. docker-compose の準備
以下のようなファイル(docker-compose.yml)を用意します。
ここでは、Apache spark の docker image として、"blueskyareahm/spark-base:latest" を指定していますが、他にも多くの image が公開されており、なんでも構いません。
ちなみに本イメージは alpine:3.10 を元に作成した spark version 2.3.2 になります。
version: '2'
services:
spark-master:
image: blueskyareahm/spark-base:latest
hostname: doc-spark-master101.local
container_name: spark-master101
ports:
- 4040:4040
- 8080:8080
- 7077:7077
mem_limit: 1g
networks:
spark-nw:
ipv4_address: 172.30.1.2
command: /spark/bin/spark-class org.apache.spark.deploy.master.Master --host 0.0.0.0
extra_hosts:
- "doc-spark-worker101.local:172.30.1.3"
spark-worker:
image: blueskyareahm/spark-base:latest
hostname: doc-spark-worker101.local
container_name: spark-worker101
depends_on:
- spark-master
ports:
- 8081:8081
mem_limit: 1g
networks:
spark-nw:
ipv4_address: 172.30.1.3
command: /spark/bin/spark-class org.apache.spark.deploy.worker.Worker spark://spark-master:7077 --host 172.30.1.3
extra_hosts:
- "doc-spark-master101.local:172.30.1.2"
networks:
spark-nw:
external: true
こちらの docker-compose.yml ファイルからは、spark-master と spark-worker それぞれ一つずつコンテナが生成されることになります。
5. コンテナのビルド・開始
docker-compose.yml が配置されているディレクトリで以下のコマンドを実行します。
$ docker-compose up --build -d
Pulling spark-master (blueskyareahm/spark-base:latest)...
(省略)
Creating spark-master101 ...
Creating spark-master101 ... done
Creating spark-worker101 ...
Creating spark-worker101 ... done
コマンドで確認すると、docker-compose.yml 内で指定した docker image がローカルにダウンロードされたことが確認できます。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
blueskyareahm/spark-base latest 434f57cb14db 3 days ago 344MB
また、spark-master と spark-worker それぞれ一つずつコンテナが起動されていることが確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8643575faa0b blueskyareahm/spark-base:latest "/spark/bin/spark-cl…" 7 minutes ago Up 7 minutes 8080/tcp, 0.0.0.0:8081->8081/tcp spark-worker101
1ac9774f5ff9 blueskyareahm/spark-base:latest "/spark/bin/spark-cl…" 8 minutes ago Up 7 minutes 0.0.0.0:4040->4040/tcp, 0.0.0.0:7077->7077/tcp, 0.0.0.0:8080->8080/tcp spark-master101
6. spark-shell の開始
以下のコマンドで spark-shell を開始します。
spark-master コンテナ内の spark-shell コマンドより開始しています。
$ docker-compose exec spark-master /spark/bin/spark-shell --master spark://localhost:7077
以下のようなインタラクティブ シェルが起動します。
Spark context Web UI available at http://doc-spark-master101.local:4040
Spark context available as 'sc' (master = spark://localhost:7077, app id = app-20200727141606-0000).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.3.2
/_/
Using Scala version 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_242)
Type in expressions to have them evaluated.
Type :help for more information.
scala>
以下のようにコマンドを実行してみます。
scala> val list = List(1,2,3)
list: List[Int] = List(1, 2, 3)
scala> val rdd = sc.parallelize(list)
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:26
scala> rdd.count
res0: Long = 3
scala> rdd.collect
res1: Array[Int] = Array(1, 2, 3)
val list = List(1,2,3) で配列を宣言しています。
そして、その配列を元に Apache spark の特徴的なデータである RDD を生成しています。
生成した RDD のインスタンスに対して、count を呼び出すことで、その配列のサイズが返ることが確認できます。
また、collect を呼び出すことで、その配列の中身が返ることが確認できます。
7. さいごに
Apache spark の特徴的なデータ型 RDD(など) には大きく2つに分けて "変換"と"アクション"と呼ばれるメソッド(API)群が用意されています。
※count と collect は "アクション"に分類されます。
これは Apache spark の特徴であり、適切に使用するにあたって、非常に大事な要素の一つになります。
提供されているAPIは spark-shell から実行させることが可能で、その動作を確認するのに便利です。
Streaming 処理や Machine learning のAPIを試用することも可能です。
docker image を使用することで、最短5分ほどで hbase-shell 実行環境まで用意することができます。