すのふら

すのふら

日々の備忘録

apache Saprkについて最初の調査

仕事でpySparkを使うことになりそうなので、事前学習中。
まずはそもそものSparkについて勉強するために以下あたりで勉強。

初めてのSpark

初めてのSpark

この本、Sparkバージョンが1.4でめちゃくちゃ古い(本日時点で最新バージョン2.1.2)ので、詳細なところというよりは根本を抑える。
併せて、ここにも目を通す。

mogile.web.fc2.com

英語さっぱりな俺にはホンマ神のようなサイトやで……。

更に更に併せてqiita等先人のお力もお借りする。ありがてえありがてえ

めちゃくそ素人なので、間違っていること書いている可能性かなりあるよって予防線張っとく。
自信ニキ指摘オナシャス

Apache Sparkについて

Apache Hadoopという、大きなミドルウェアの中のひとつのフレームワークという考え方でいいのかな?
SparkのほかにMapReduceがいて、MapReduceよりも処理が速いってことで今主流のフレームワーク

f:id:snofra:20171109165423p:plain

YARNってやつがいるが詳細はまだよくわからないので一旦置いておく。
あの日見たYARNのお仕事を僕達はまだ知らない。


Sparkはどのような特徴があるのか

Sparkのサイト翻訳を見ると

Apache Sparkは高速で汎用的なクラスタコンピュータシステムです。Java, Scale, PythonおよびRの高レベルのAIPを提供し、一般的な実行グラフをサポートする最適化されたエンジンを提供します。SQLおよび構造データのためのSpark SQL機械学習のためのMLlib、グラフ処理のためのGraphX およびSpark Streamingを含む高レベルのツールの充実したセットもサポートします。 概要 - Spark 2.0.0 ドキュメント 日本語訳

要はめちゃ速で汎用的で、いろんな言語に対応しているし、機械学習とかそういうのもできるよってことかな。

なんでめちゃ速なのか?ってSparkのwikipediaにも書いてあるとおり、

フォールトトレラントシステムで管理され、複数マシンのクラスタに分散されたデータ項目の読み取り専用多重集合であるRDD(resilient distributed dataset)と呼ばれるデータ構造を中心とするアプリケーションプログラミングインターフェイスを備えている。
SparkのRDDは、 分散共有メモリの (意図的に)制限された形式で提供する分散プログラムのワーキングセットとして機能する。
Apache Spark - Wikipedia

という2点あるから。


1点目 RDDというデータ構造

と書いておいてアレだが、Sparkのバージョン2.0以降はRDDよりもRDDを基盤としたDataFrameがよく使われるので、RDDベースでの話はやや古すぎるかも。
って前札幌の勉強会で聞いた。

www.slideshare.net

RDDっていう思想はDataFrameになってもあると思うので、詳細よりも考えかたを押さえておく。

RDDはその言葉から障害耐性を持つ並列可能なデータ構造。
「フォールトトレランス *2 で並列処理可能なコレクション」・「コレクションはイミュータブル」とのこと。

RDDのフォールトトレランスは

RDDのいずれかのパーティションが喪失すると、最初にそれを生成した変換を使って自動的に再計算されます。 Spark プログラミング ガイド - Spark 2.0.0 ドキュメント 日本語訳

とあるので、データが壊れたやノードの速度が低下した場合は再実行してデータを再計算するという感じ。

再計算をしても同じ結果が出るようにイミュータブルにしなくてはならない。
前のデータ書き換えることが可能だったら、データがぶっ壊れるので。


2点目 データをキャッシュしておくという考え

MapReduceとの比較になるのが主だけど、それと比べてなぜめちゃ速なのかって、HDFSへのアクセス数を極力抑えるという思考だから。IOのオーバヘッド減らせば速いよね的な。

ここの23p~24pがかなりわかりやすいが、クソ適当な絵で描くと

www.slideshare.net

f:id:snofra:20171109165426p:plain

ジョブが多ければ多いほどHDFSからデータをロードする時間がかかって、その分実行時間がかかってしまう。
その点からSparkはデータをメモリ内に取り込んで(インメモリ内)で処理してしまうので、IOのオーバヘッド時間を減らせるのでより速い。

f:id:snofra:20171109165429p:plain

また、上記Sparkの考え方から何度も使用するRDDは毎度計算すると時間かかるから、RDD自体をメモリに確保しとこうねってことが可能。
これがRDDの永続化ってやつ。

f:id:snofra:20171109165433p:plain


クラスターについて

最初にも書いたけど、Sparkはクラスタコンピューティングフレームワークなので、複数のクラスタで分散する。

Spark公式の概要図 f:id:snofra:20171109170503p:plain


Driver Program

Spark アプリケーションの実行管理や制御を行うもので、main メソッドを含むプロセスとなります。またドライバはSpark アプリケーション毎に1つ存在し、アプリケーションの環境(SparkContext)を作る役割を担っています。 Spark のアーキテクチャ概要

ということなので、マスターノードに該当するところ。こいつから処理が開始する。


実行時にSparkContextってやつで環境の仕込みをする。

そうはいってもこいつがいったい何者なのか、『初めてのSpark』を読んでもよくわからんかったので、sparkのドキュメントを読む。

Main entry point for Spark functionality. A SparkContext represents the connection to a Spark cluster, and can be used to create RDDs, accumulators and broadcast variables on that cluster. SparkContext (Spark 2.0.2 JavaDoc)

google翻訳曰く

Spark機能のメインエントリポイント。SparkContextは、Sparkクラスタへの接続を表し、そのクラスタRDD、アキュムレータ、およびブロードキャスト変数を作成するために使用できます。

とのことなので、多分以下のようなことをやっているんだと思う。
1. マスターノードとスレーブノード間の接続
2. ワーカーノードに、RDDと、アキュムレータ、ブロードキャスト変数を渡す。

ここで、アキュムレータとブロードキャスト変数というものが出てきたので、確認すると

アキュムレータ

CPUで出てくるやつ。Pythonだとitertools.accumulateね。
要は前の値と加算して、その結果を蓄積していくもの。1,2,3,4,5だったら、1,3,6,10,15みたいに前までの計算結果と加算させていく。

Sparkでの使い方は主にデバッグ用で、処理実行時のクラスタのイベント数をカウントしておく。


ブロードキャスト変数

要は定数で、Driver Programで作成した定数を各ワーカーノードに渡す。
ブロードキャスト変数がいい理由は、読み取り専用という点と、大きいサイズの定数の場合オーバヘッドが少ないから。逆に小さいサイズの定数はオーバヘッドが大きい可能性がある。
Spark 共有変数


ContextはSparkContext以外にもContext系はHiveContextとSQLContextがある。 *3

SQLContextは

Spark SQLを利用するためには、SparkContextに加えてSQLContextが必要。SQLContextはDataFrameの作成やテーブルとしてDataFrameを登録、テーブルを超えたSQLの実行、キャッシュテーブル、そしてperquetファイルの読み込みに利用される。 Spark SQLサンプルアプリの実行

とのことなので、DataFrameを使用する今のSparkでは必須で準備しておかなくてはいけないものっぽい。

HiveContextはHiveQLを使用するために必要。とさらっと


Cluster Manager

Spark アプリケーションをクラスタ上で実行するためには、クラスタのリソース(メモリやCPU など)の確保を行ったり、スケジューリング管理を行う必要があります。それを行うのがCluster Manager の主な役目となります Spark のアーキテクチャ概要

Cluster Managerには3つのオプションがあって、そのうちひとつを選択するよう。
ジョブスケジューリング - Spark 2.0.0 ドキュメント 日本語訳


スタンドアロンモード

Sparkに組み込まれている標準モード

YARN

YARN上でSparkを起動する。
YARNはHadoopクラスタのリソース管理や、Hadoop上で動作するアプリケーションのスケジューリングを担当するので、そちらに一任する形?
あの日見たYARNのお仕事を僕達はまだ知らない。

Mesos

Apache Mesosで管理されるハードウェアクラスタ上で実行。
利点は、Sparkと他のフレームワークの間の動的なパーティションと、Sparkの複数のインスタンス間のパーティションのスケール
Mesos上でSparkを実行 - Spark 2.0.0 ドキュメント 日本語訳


Worker Node

クラスター。これら(executer)が分散して作業を行う。
処理の最小単位はtask


セキュリティ

共通鍵暗号方式をサポート。
*4 認証はspark.authenticate 設定パラメータを使って設定。
共通鍵暗号方式なので、Spark側と通信側で同一鍵を持っておく必要がある。
セキュリティ - Spark 2.0.0 ドキュメント 日本語訳


Jobの実行状況を覗かれたくない(Cluster Managerを見られたくない)場合、javax servlet filtersで認証等ができるようになるみたい。 Secure Spark


Sparkはコンポーネント間の通信を暗号化することが可能。プロトコルごとでSSL/TLSにできる。
Secure Spark
認証はSASLをサポート。


うーん、SASL認証って何ぞや?

SASLとはSimple Authentication and Security Layer
インターネットプロトコルにおける認証とデータセキュリティのためのフレームワークである。
Simple Authentication and Security Layer - Wikipedia

また、

SASLとはSimple Authentication and Security Layerの略であり,簡単に言ってしまうと認証のためのフレームワークのようなものです。SASLを使用することにより,開発者は既存のライブラリや仕組みを再利用することができ,利用者にはチャレンジ・レスポンス認証などの安全な認証方式を提供することができます。 第18回 OpenLDAPとSASL:そろそろLDAPにしてみないか?|gihyo.jp … 技術評論社

とあるので、どうやらチャレンジ・レスポンス認証 *5で認証する方式っぽい?


うーんなんとなくわかったけど、全体はよくわからないので触ってみて感じつかむしかないかなー。

*1:そもそもクラスタって何ぞや?っていう場合はここで。
http://wa3.i-3-i.info/word12487.html
複数のコンピュータがひとつのコンピュータっぽくふるまうこと。
ということなので、マスターノード(mainがいるところ。基本1つ)とスレーブノード(分散処理するところ。複数)が1つの処理しているってこと。

*2:フォールトトレランスってなんだって人は以下で。要は障害に対してどう備えるか。身近なパターンだと地震起きたときどうする的な?
http://wa3.i-3-i.info/word14813.html

*3:HiveContextとSQLContextの性能比較
SparkSQL - HiveContext/SQLContextの性能比較

*4:共通鍵暗号方式が分からない場合はここで。
http://wa3.i-3-i.info/word1837.html

*5:チャレンジ・レスポンス認証が分からない場合はここ。
http://wa3.i-3-i.info/word12765.html
要は認証サーバ側から要求される毎度異なる値(チャレンジ)とパスワードを合わせた値(レスポンス)とIDを認証サーバに送って、認証サーバ側はレスポンスからパスワード抽出する認証方法。