いろいろ難しい Python
副題は「Python と Jupyter で活用する Spark 2 エコシステム」。 原題は "Learning PySpark"。
本書は、私には難しい。いたるところで RDD ということばが出てくる。 RDD は Resilient Distributed Datasets の頭文字語であり、 耐障害性分散データセットと訳される。 レジリエントあるいはその名詞形であるレジリエンスという概念は、 データのみならず個人や組織にまで、リスク対応能力などの意味で通用するようになっている。
まずそもそも、Spark のことがわからない。
Spark は、Apache Spark が正式な名称である。
訳者まえがきでは、
Spark はすっかり分散処理のフレームワークとして定着した感がありますが(後略)
そもそも何を分散処理するのか、ということがわからなかった。
本書の1章では、次のように述べられている。
Apache Spark は、オープンソースの強力な分散クエリおよびデータ処理エンジンです。
これを読んで、わたしは巨大なデータベース(いわゆるビッグデータ)を扱え、 また耐障害性の高い DBMS のようなものだと理解した。 それがあっているかどうかは、よくわからない。
わたしは PySpark を WSL の Ubuntu 20.04 にインストールした(後述)。 そして $ jupyter notebook を実行してサーバを起動し第2章を実行してみたが、いきなり sc がないと怒られた。
In [1]: | sc.parallelize([('troubles', 108), ('bottles', 50000)]) |
Out [1]: |
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-2-0475c644e3c4> in <module> ----> 1 sc.parallelize([('troubles', 108), ('bottles', 50000)]) NameError: name 'sc' is not defined |
しまった。$ pyspark で起動しなければならなかった。 pp.253-254 で、同じように sc の確認からやってみる。
In [1]: | sc |
Out [1]: | SparkContext Spark UI Version v3.0.1 Master local[*] AppName PySparkShell |
よし、大丈夫だ。
付録 A Apache Spark のインストールの A.8 Spark のインストール (p.242) で、 Spark をインストールする方法が3種類あると説明している。
- ソースコードをダウンロードし、自分自身でコンパイルする。この方法が最も柔軟です。
- ビルド済みのバイナリをダウンロードする
- pip で PySpark のライブラリをインストールする(http://bit.ly/2ivVhbH)
最も柔軟です、という甘言に載せられ、私は上記の1. の通り、自分自身でコンパイルすることにした。 私の環境は、WSL Ubuntu 20.04 である。下記は 2020-09-20 に行った。
まず、Download Apache Spark™ (spark.apache.org) にアクセスする。上記のページに次のように書かれている:
1. の Spark リリースの選択肢1では、 3.0.1 (Sep 02 2020 ) を選ぶ。 2. のパッケージタイプ選択肢2では、Source Code を選ぶ。 そうすると、3. のダウンロードのリンクは、 spark-3.0.1.tgz のようになっているのでこれをダウンロードする。
チェックサムを MD5 で確かめる。
$ md5sum spark-3.0.1.tgz 13ec0fbdc197e5200e469d79e8ffdacc spark-3.0.1.tgz
一方、Apache のページには md5 のページはなく、sha512 によるチェックサムしかない。 私の環境では、sha512 は使えない。
$ sha512 spark-3.0.1.tgz コマンド 'sha512' が見つかりません。次の方法でインストールできます: sudo apt install hashalot
sha512 が使えるように、泥縄式ではあるが hashalot をインストールした。
$ sudo apt install hashalot
こんどは sha512 が使えるだろう。
$ sha512sum spark-3.0.1.tgz
e0f2a6da77681423c860a56ebf8eda52e5cb952cb3d636a220f43efdc6a683803e82cc022c05e4759b924ef27c14734e23c4315cff9276d14e29c23f
eb7eaf35 spark-3.0.1.tgz
この値は、 https://downloads.apache.org/spark/spark-3.0.1/spark-3.0.1.tgz.sha512 から得た値と同じである。ということで大丈夫。そこでソースコードからのコンパイルを試してみた。
$ export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m" $ export JAVA_HOME="/usr/lib/jvm/java-14-openjdk-amd64 $ ./build/mvn -Pyarn -Phadoop-2.7 -Dhadoop.version=2.7.0 -Phive -Phive-thriftserver -DskipTests clean package (中略) [INFO] --- scala-maven-plugin:4.3.0:testCompile (scala-test-compile-first) @ spark-core_2.12 --- [INFO] Using incremental compilation using Mixed compile order [INFO] Compiler bridge file: /home/username/.sbt/1.0/zinc/org.scala-sbt/org.scala-sbt-compiler-bridge_2.12-1.3.1-bin_2.12. 10__58.0-1.3.1_20191012T045515.jar [INFO] Compiling 282 Scala sources and 27 Java sources to /mnt/c/Users/username/documents/spark/spark-3.0.1/core/target/sc ala-2.12/test-classes ... [ERROR] [Error] /mnt/c/Users/username/documents/spark/spark-3.0.1/core/src/test/scala/org/apache/spark/deploy/security/Had oopDelegationTokenManagerSuite.scala:145: method reset in class UserGroupInformation cannot be accessed in object org.ap ache.hadoop.security.UserGroupInformation [ERROR] one error found [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for Spark Project Parent POM 3.0.1: [INFO] [INFO] Spark Project Parent POM ........................... SUCCESS [07:37 min] [INFO] Spark Project Tags ................................. SUCCESS [01:10 min] [INFO] Spark Project Sketch ............................... SUCCESS [ 19.251 s] [INFO] Spark Project Local DB ............................. SUCCESS [ 31.748 s] [INFO] Spark Project Networking ........................... SUCCESS [ 38.369 s] [INFO] Spark Project Shuffle Streaming Service ............ SUCCESS [ 12.073 s] [INFO] Spark Project Unsafe ............................... SUCCESS [ 46.429 s] [INFO] Spark Project Launcher ............................. SUCCESS [07:20 min] [INFO] Spark Project Core ................................. FAILURE [08:18 min] [INFO] Spark Project ML Local Library ..................... SKIPPED [INFO] Spark Project GraphX ............................... SKIPPED [INFO] Spark Project Streaming ............................ SKIPPED [INFO] Spark Project Catalyst ............................. SKIPPED [INFO] Spark Project SQL .................................. SKIPPED [INFO] Spark Project ML Library ........................... SKIPPED [INFO] Spark Project Tools ................................ SKIPPED [INFO] Spark Project Hive ................................. SKIPPED [INFO] Spark Project REPL ................................. SKIPPED [INFO] Spark Project YARN Shuffle Service ................. SKIPPED [INFO] Spark Project YARN ................................. SKIPPED [INFO] Spark Project Hive Thrift Server ................... SKIPPED [INFO] Spark Project Assembly ............................. SKIPPED [INFO] Kafka 0.10+ Token Provider for Streaming ........... SKIPPED [INFO] Spark Integration for Kafka 0.10 ................... SKIPPED [INFO] Kafka 0.10+ Source for Structured Streaming ........ SKIPPED [INFO] Spark Project Examples ............................. SKIPPED [INFO] Spark Integration for Kafka 0.10 Assembly .......... SKIPPED [INFO] Spark Avro ......................................... SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 29:47 min [INFO] Finished at: 2020-09-20T16:13:13+09:00 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal net.alchim31.maven:scala-maven-plugin:4.3.0:testCompile (scala-test-compile-first) on pro ject spark-core_2.12: Execution scala-test-compile-first of goal net.alchim31.maven:scala-maven-plugin:4.3.0:testCompile failed.: CompileFailed -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException [ERROR] [ERROR] After correcting the problems, you can resume the build with the command [ERROR] mvn-rf :spark-core_2.12
甘言に載せられてはいけない。ソースコードからのコンパイルはあきらめた。
ということは、ビルド済みのバイナリをダウンロードするか、 pip で PySpark のライブラリをインストールするかだ。
ほかにインストールした例がないか調べると、下記のページがみつかった。
https://phoenixnap.com/kb/install-spark-on-ubuntu
これは、ビルド済みのバイナリをダウンロードする方法のようだ。 このページにしたがってインストールしてみよう。こちらのページは、 java (opensdk)、scala、git がインストールされていることを前提としているが、 これらは私の環境では幸いすでに入っている。以下、上記にしたがって、作業をしてみた。 まず、ファイルをダウンロードする:
$ wget https://downloads.apache.org/spark/spark-3.0.1/spark-3.0.1-bin-hadoop2.7.tgz
本当は、上記のサイト直接ではなく、日本から一番近いミラーサイトからダウンロードしてくるのがよいのだが、 私の力では見つけられなかった。私の環境では、上記コマンドでダウンロードをするのに30分弱かかった。 また、spark-3.0.1 のディレクトリには、hadoop が 3.2 の版もあるが、 hadoop 2.7 のファイルを指定している。その理由は不明である。
次に、解凍したディレクトリを /opt/spark というファイルに移す。ここはよい。
そして、~/.profile に環境変数を設定するのだが、 シェルで書き込む方法と、エディタで書き込む方法の両方が示されている。 私はエディタで書き込む方法をとった。そして、~/.profile の内容を有効にするために、 $ source ~/.profile コマンドを実行する。ここまではよい。
そして、マスターを動かすために次のコマンドを実行したがエラーとなる。
$ start-master.sh starting org.apache.spark.deploy.master.Master, logging to /opt/spark/logs/spark-username-org.apache.spark.deploy.master.Master-1-username-PC.out sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です failed to launch: nice -n 0 /opt/spark/bin/spark-class org.apache.spark.deploy.master.Master --host username-PC.localdomain --port 7077 --webui-port 8080 nice: 優先度を設定できません: 許可がありません full log in /opt/spark/logs/spark-username-org.apache.spark.deploy.master.Master-1-username-PC.out
許可がありません、ということはやはりこれは root で実行すべきなのだろう。
$ sudo /opt/spark/sbin/start-master.sh starting org.apache.spark.deploy.master.Master, logging to /opt/spark/logs/spark-root-org.apache.spark.deploy.master.Master-1-username-PC.out sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です $
「無効な引数です」が連続して出るのは癪に障るが、エラーではないだろう。 http://127.0.0.1:8080/ にアクセスしてみた。Spark の画面が出ている。やった。 マスターの次はスレーブである。
$ start-slave.sh spark://ubuntu1:7077 starting org.apache.spark.deploy.worker.Worker, logging to /opt/spark/logs/spark-username-org.apache.spark.deploy.worker.Worker-1-username-PC.out sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です sleep: 実時間の時計を読み取ることができません: 無効な引数です
私の環境では起動していない。どうやら、 spark://ubuntu1:7077 が誤りらしい。
私の環境では、URL で指定した画面は、
Spark Master at spark://username-PC.localdomain:7077
のように出ていたので、これを指定するといいだろう。
$ start-slave.sh spark://username-PC.localdomain:7077
sleep に関する表示は相変わらず出るが、エラーではないようだ。 しかし、Spark の Web 画面には反映されない。これも、root 権限が必要ではないか。
$ sudo /opt/spark/sbin/start-slave.sh spark://username-PC.localdomain:7077
これでやっと Workers の欄に Worker Id ほかの情報が表示された。State も alive である。
さて、spark シェルは走るだろうか。
$ spark-shell 20/09/20 18:43:14 WARN Utils: Your hostname, username-PC resolves to a loopback address: 127.0.1.1; → using 192.168.56.1 instead (on interface eth0) 20/09/20 18:43:14 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.apache.spark.unsafe.Platform → (file:/opt/spark/jars/spark-unsafe_2.12-3.0.1.jar) to constructor java.nio.DirectByteBuffer(long,int) WARNING: Please consider reporting this to the maintainers of org.apache.spark.unsafe.Platform WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release 20/09/20 18:43:15 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... → using builtin-java classes where applicable Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties Setting default log level to "WARN". To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel). Spark context Web UI available at http://192.168.56.1:4040 Spark context available as 'sc' (master = local[*], app id = local-1600595011976). Spark session available as 'spark'. Welcome to ____ __ / __/__ ___ _____/ /__ _\ \/ _ \/ _ `/ __/ '_/ /___/ .__/\_,_/_/ /_/\_\ version 3.0.1 /_/ Using Scala version 2.12.10 (OpenJDK 64-Bit Server VM, Java 14.0.1) Type in expressions to have them evaluated. Type :help for more information. scala>
警告がいろいろ出ている。どうすれば直るものかわからないが、とりあえず、scala プロンプトが出た。 次は pyspark である。やっと本書の p.248 に合流できる。
$ pyspark Python 3.8.2 (default, Jul 16 2020, 14:00:26) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. 20/09/20 18:51:24 WARN Utils: Your hostname, username-PC resolves to a loopback address: 127.0.1.1; using 192.168.56.1 instead (on interface eth0) 20/09/20 18:51:24 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.apache.spark.unsafe.Platform (file:/opt/spark/jars/spark-unsafe_2.12-3.0.1.jar) to constructor java.nio.DirectByteBuffer(long,int) WARNING: Please consider reporting this to the maintainers of org.apache.spark.unsafe.Platform WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release 20/09/20 18:51:26 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties Setting default log level to "WARN". To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel). Welcome to ____ __ / __/__ ___ _____/ /__ _\ \/ _ \/ _ `/ __/ '_/ /__ / .__/\_,_/_/ /_/\_\ version 3.0.1 /_/ Using Python version 3.8.2 (default, Jul 16 2020 14:00:26) SparkSession available as 'spark'. >>>
その後、私の環境は WSL から WSL2 に変わったが、運よく Spark 関係はそのままインストールされていた。 現在はコマンドラインインターフェースで pyspark と入力すると、Jupyter Notebook の環境となる (ブラウザの URL が表示される)。そのときの出力はSparkContext確認画面の通りであり、 p.254 とは異なる。
p.3 の下から4行目「有行非循環グラフ(Direct Acyclic Graph = DAM)」とあるが、 「有向非循環グラフ」が正しい。
p.24 の下半分にある次のコードがある。
data_2014_2 = data_from_file_conv.map(
lambda row: (row[16], int(row[16]):)
data_2014_2.take(5)
上記は誤りで、次が正しい。int row[16] のあとのカッコと take() の引数に注意。
data_2014_2 = data_from_file_conv.map(
lambda row: (row[16], int(row[16])))
data_2014_2.take(10)
書 名 | 入門 PySpark |
著 者 | Tomasz Drabas, Denny Lee |
訳 者 | 玉川 竜司 |
発行日 | 2017 年 11 月 21 日 初版第1刷 |
発行所 | オライリー・ジャパン |
発売元 | オーム社 |
定 価 | 3400 円(税別) |
サイズ | 版 |
ISBN | 978-4-87311-818-2 |
その他 | 越谷市南部図書室で借りて読む |
NDC |
まりんきょ学問所 > コンピュータの部屋 > コンピュータの本 > Python > Jacaueline Kazil and Katharine Jarmul:入門 PySpark