Apache Spark アキュムレータについて調べてみる
Apache Spark プログラミングの機能に、アキュムレータというものがあるらしい。
どういうものか、調べてみる。
出来ればどういったケースで有用であるかを理解したい。
概要
・アキュムレータは主に情報を集計するためのものらしい。
・アキュムレータは書き込みだけが許された変数。
前提
・map() の関数などを Spark に渡す場合、外部のドライバプログラム内で定義された変数を使うことが出来る。
・ただし、エグゼキュータは各変数のコピーを受け取ることになるため、エグゼキュータ内での変更はドライバ側には反映されない。
→RDDメソッド内から、メソッドのスコープ外にあるドライバの変数を直接書き換えはできない
→RDDメソッド内から書き換える必要がある場合に、アキュムレータを使う
→でも JavaScript で言うクロージャでは、普通に外部の変数書き換えられているよね?
・アキュムレータは、ドライバとエグゼキュータで共有可能な変数である。
用途
・もっとも一般的な用途の一つは、ジョブの実行中に発生したイベント数をカウントすること。
・同じ値を並列プログラムの複数の場所から加算処理を行う場合に便利?
実践
・アキュームレータを用いて、テキストファイル内の空行をカウント
https://github.com/blueskyarea/scala/blob/master/spark/accumulator/sample1.scala
注意点
・アキュムレータでのカウント結果が分かるのは、アクションを実行した後。(変換処理は遅延評価されるから)
・エグゼキュータからは、アキュムレータの value プロパティにアクセス出来ない。(ドライバからのみ)
まとめ
・アキュムレータは、ドライバプログラム内で sc.accumulator() メソッドを使って生成する。
・エグゼキュータは、アキュムレータの += メソッドを使って加算する。
・ドライバプログラムから、アキュムレータの値にアクセスするには、value メソッドを使う。
注意点(応用)
・Sparkは障害が発生したマシンや、低速なマシンがあった場合、その処理を他のノードで実行するように調整することがある
→同じ変換処理(関数)が何度も実行されるかもしれない
→アキュムレータの処理が重複されてしまうかもしれない
→変換処理でアキュムレータを使うのは、デバッグ用途に限定すべき
・アクション内で使われたアキュムレータは、必ず1回のみ実行される
→絶対的な値のカウンタが必要な場合は、変換処理ではなく、アクション内にアキュムレータを置く必要がある
実践2
・アキュムレータをアクション内に置く
https://github.com/blueskyarea/scala/blob/master/spark/accumulator/sample2.scala
実践3
・カスタムアキュムレータ
https://github.com/blueskyarea/scala/blob/master/spark/accumulator/sample3.scala
→思ったとおりの動きではない(なんでリストに0も追加されるのだろう?)
ひとり言
・クロージャについても調べたけど、まだ理解が出来ていない気がする。
→外側の関数のスコープにある変数が更新出来ないというのは、Scalaでのクロージャであって、JavaScriptのクロージャとはまた別なのでは?と思う
→外側の関数のスコープにある変数を使用出来るという意味ではScalaでもJavaScriptでも共通していると思う。
参考リンク
・API
https://spark.apache.org/docs/latest/api/java/org/apache/spark/Accumulator.html
http://spark.apache.org/docs/latest/programming-guide.html#accumulators-a-nameaccumlinka
・accumulator
http://imranrashid.com/posts/Spark-Accumulators/
http://bigdatafindings.blogspot.jp/2015/08/learning-spark-notes-advanced-spark.html
https://groups.google.com/forum/#!topic/spark-users/ydFmOx8RSrw
・Sample
https://github.com/blueskyarea/scala/blob/master/spark/accumulator/sample3.scala
http://amkt922.hatenablog.com/entry/2014/02/20/181059