YARN上でSpark Streamingを使うときのクラスのバージョンアップについて


Spark SteamingのアプリケーションをJavaなりScalaなりで書いて、YARNクラスタ上で実行するべくspark submitする。
このとき、すでに実行中のSpark StreamingアプリケーションとFQCNが同一のクラスの新しいバージョンがsubmitしたJARファイルに含まれていると、トラブルに巻き込まれる。

Spark Streamingの場合、DAGを構成する処理をLambdaオブジェクトにしてserializeし、エクゼキュータプロセスの走っているノードにネットワーク越しに転送し、実行させる。エクゼキュータプロセスは、serializeされたLambdaオブジェクトをdesrializeし、メモリ上に復元しようとするわけだが、そこでdeserializeしようとするオブジェクトのクラスのバージョンと、エクゼキュータプロセスのメモリ上にロード済みのクラスのバージョンが衝突することがある。バージョンが違うから、deserializeできないよ、とInvalidClassExceptionが生じるわけだ。

InvalidClassExceptionを回避するだけなら、工夫することは可能だろうが、われわれとしては、新しいアプリケーションには新しいバージョンのクラスを利用したいわけで、メモリのロード済みのクラスは使ってほしくない。

そういうわけで、私は、各アプリケーションの利用しているクラスを把握しておいて、衝突が起きる場合には、先行して稼働中のアプリケーションを止めて、バージョンアップする運用をしている。

しかし...これって、自分で開発したクラスの範疇なら良いけれど、依存関係の中に入っているクラスで起きてしまったら厄介すぎる問題だよね。

特に、そのYARNクラスタを多数のユーザで共有している場合には...