2017-02-15 5 views
3

これは愚かな質問かもしれません。しかし、私はこのようなものがあるかどうかを知りたいです - rdd.mapPartitions(func)funcのロジックはスレッドセーフであるべきですか?あなたは "rdd.mapPartitions(FUNC)" を行うとSpark変換とアクションのロジックはスレッドセーフである必要がありますか?

おかげで

+0

RDD操作は常に不変であるため、スレッドセーフティの問題は、RDDを変換する基本機能には関係ありません。 –

答えて

3

短い答えはいいえ、スレッドセーフである必要はありません。

これは、sparkがパーティション間でデータを分割するためです。次に、各パーティションごとにタスクを作成します。作成する関数は、その特定のパーティション内でシングルスレッド操作として実行されます(つまり、他のスレッドは同じデータにアクセスしません)。

これは、RDDデータではないリソースにアクセスすることによって、手動で「安全でない」スレッドを作成しないようにする必要があるということです。たとえば、静的オブジェクトを作成してそのオブジェクトにアクセスすると、複数のタスクが同じエグゼキュータ(JVM)で実行され、そのオブジェクトにもアクセスする可能性があるため、問題が発生する可能性があります。あなたが何をしているのか正確に分かっていない限り、始めにそのようなことをするべきではありません...

-3

、funcが実際には別のJVMで実行することもできます!スレッドはJVM全体で意味を持ちません。

ローカルモードで実行していて、グローバルステートまたはスレッドの安全でない関数を使用している場合、ジョブは正常に動作する可能性がありますが、動作は定義されていないかサポートされていません。

1

mapPartitions(または他のアクションや変換)に渡される関数は、スレッドセーフでなければなりません。 JVM上でスパークする(これはゲスト言語では必ずしも当てはまりません)エグゼキュータスレッドを使用し、個々のタスク間の分離を保証するものではありません。

これは、関数で初期化されていないが、main関数で初期化されたが関数で参照されているオブジェクトなどのクロージャで渡されたリソースを使用する場合に特に重要です。

明示的に許可されていない限り、引数を変更しないでください。

関連する問題