社内se × プログラマ × ビッグデータ

プログラミングなどITに興味があります。

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)は、配列やプリミティブ型以外を扱う場合、非常に効率が悪くなる

→別のライブラリを使用するか

→独自のシリアライゼーションルーチンを実装する

 

まとめ

・ブロードキャスト変数を使えば、各ノード上にキャッシュされたリードオンリーの変数を保持することができる

・大きな変数を共有したい場合、ブロードキャスト変数を使うことで通信回数が減り、通信コストを下げることが出来る

・ブロードキャストされたデータはシリアライズされた形式でキャッシュされ、各タスクを実行する前にデシリアライズされる

→明示的なブロードキャスト変数の生成は複数のステージを横断したタスクが同じデータを必要とするか、デシリアライズ形式のデータのキャッシュが重要な場合にのみ有用なことを意味する

 

ひとり言

・結局、どの程度の大きさのデータであれば、ブロードキャスト使った方がいいんだろうか?

・仮にデータサイズが小さくとも、各エグゼキュータと共有するべき情報(例えば認証情報など)は、ブロードキャスト変数として共有されているのだろうか?