Sparkのパフォーマンスに影響を与えるローカリティについてまとめてみました。
Sparkのローカリティ
Sparkではジョブがタスクに分解されて各executorで実行されますが、その際に入力されるデータがタスクに近い(ローカリティが高い)ほど転送コストが少なくなり素早く実行を開始することが出来ます。
ただ、一番近いexecutorのリソース(VCoreやメモリなど)が足りない時は、ローカリティが高い物から順番にリソースに余裕のあるexecutorを探して実行を行わせます。
Sparkに登場する各ローカリティ
左の物ほどローカリティが高く転送コストが少なく済む傾向があります。
[PROCESS_LOCAL] > [NODE_LOCAL] > [RACK_LOCAL] > [ANY]
PROCESS_LOCAL
Sparkアプリケーションを実行中のJVM上にデータが存在する状況です。
NODE_LOCAL
データが同じノード(サーバ)上に存在する状況です。
JVMプロセス間で転送が行われます。
RACK_LOCAL
データが同じラック上に存在する状況です。
ノードからノード間でネットワーク(スイッチ)を経由した転送が行われます。
ANY
データがネットワークのどこかに存在する状況です。
ノードからノード間でネットワークを経由した転送が行われます。
NO_PREF
上の比較に存在しないローカリティです。
ローカリティを特定出来ない状況です。
この場合Sparkはローカリティを考慮しないで実行を行います。
ローカリティ関連の設定値
Sparkがタスクの実行の際にそのローカリティで実行を待機する時間をコンフィグから調整することが出来ます。
3秒たってもそのローカリティで実行出来ない場合は次の優先度のローカリティで実行を待機します。
デフォルトだと3秒に設定されているのでRACK_LOCAL
に移行するのに9秒かかることになります。
※ 実際には待機する時間+転送時間がかかります
spark.locality.wait
spark.locality.wait.node
spark.locality.wait.process
spark.locality.wait.rack
Spark Streamingでのローカリティ
ストリーム処理の場合、タスクがPROCESS_LOCAL
以外のローカリティで実行される時は安定して処理を継続できなくなるできなくなる可能性があります。
アプリケーションや実行環境の調査を行ったほうが良いと思います。
参考資料
https://spark.apache.org/docs/latest/tuning.html#data-locality
https://stackoverflow.com/questions/36616897/task-data-locality-no-pref-when-is-it-used
https://spark.apache.org/docs/latest/configuration.html#scheduling