Apache Spark ブロードキャスト変数について調べてみる
Apache Spark プログラミングの機能に、ブロードキャスト変数というものがあるらしい。
どういうものか、調べてみる。
出来ればどういったケースで有用であるかを理解したい。
概要
・ブロードキャスト変数は、ドライバで定義した定数を各エグゼキュータに転送するための変数
・アキュムレータと同じく、ドライバとエグゼキュータ間での共有変数
・すべてのエグゼキュータに送信される
用途
・大規模なリードオンリーのルックアップ用のテーブルを全ノードに送信
・機械学習のアルゴリズムの大規模な特徴ベクトルを全ノードに送信
前提
・Sparkでは、クロージャの中で参照されたすべての変数を自動的にエグゼキュータに送信する
→便利ではあるが、Sparkが操作の度にその変数を送信してしまう
→非効率になる場合がある
→ブロードキャスト変数を使えば、送信は一度で済む
→ただ小さいサイズの定数であれば、ブロードキャストする方がオーバヘッドが大きい可能性
使い方
1. Broadcast[T] を生成する。
2. 値にアクセスするには value プロパティを使う。
3. この変数は各ノードに1回だけ送信される。リードオンリーとして扱う。
→値を更新しても、他のノードには伝達されない
注意点
・ブロードキャスト変数の値は変更しないこと
→後から追加されたノードにブロードキャスト変数が送信されるため
→値が変更されていると、他のノードに送信済みの値と差が生じてしまう
実践
・ブロードキャスト変数を使う場合、使わない場合
https://github.com/blueskyarea/scala/blob/master/spark/broadcast/sample1.scala
注意点(応用)
・大きなデータをブロードキャストする場合、値のシリアライズに時間がかかったり、ネットワーク経由での送信に時間がかかる可能性がある
→大きなボトルネック
→JavaAPIデフォルトのシリアライゼーションライブラリ(Java Serialization)は、配列やプリミティブ型以外を扱う場合、非常に効率が悪くなる
→別のライブラリを使用するか
→独自のシリアライゼーションルーチンを実装する
まとめ
・ブロードキャスト変数を使えば、各ノード上にキャッシュされたリードオンリーの変数を保持することができる
・大きな変数を共有したい場合、ブロードキャスト変数を使うことで通信回数が減り、通信コストを下げることが出来る
・ブロードキャストされたデータはシリアライズされた形式でキャッシュされ、各タスクを実行する前にデシリアライズされる
→明示的なブロードキャスト変数の生成は複数のステージを横断したタスクが同じデータを必要とするか、デシリアライズ形式のデータのキャッシュが重要な場合にのみ有用なことを意味する
ひとり言
・結局、どの程度の大きさのデータであれば、ブロードキャスト使った方がいいんだろうか?
・仮にデータサイズが小さくとも、各エグゼキュータと共有するべき情報(例えば認証情報など)は、ブロードキャスト変数として共有されているのだろうか?