SparkStreamingで発生した問題の調査を行うためにJMXを有効化し接続する手順について記述します。
Spark executorでJMXを有効にする
JavaアプリケーションでJMXを有効にした際には-Dcom.sun.management.jmxremote.port
オプションでで任意のポート番号を指定すると思いますが
Sparkアプリケーションの場合、一台のサーバで複数のexecutorが立ち上がる場合がありポート番号が重複した場合に後から起動したexecutorが全てエラー終了します。
値を0にすると空いているポート番号を適当に選んで使用するようになるので、そのように設定してspark-sumitを行います。
spark2-submit \
--master yarn \
--conf "spark.executor.extraJavaOptions= \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=0 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false"
--class SparkApp \
sparkApp.jar
ちなみにdriverの調査を行いたい場合はspark.driver.extraJavaOptions
に同じオプションを渡せばJMXを有効化出来ます。
JMXを接続する
Sparkアプリケーションを実行しているサーバーを明らかにする
Sparkはクラスター上で実行されるので実行されているサーバーがいつも同じとは限りません。
色々方法があると思いますが私はSparkのWEB UI上からexecutorタブを開いて調べることが多いです。
executorがバインドしているポートを調べる
ランダムに割り当てられるので実行中のサーバーに上でJVMがバインドしているポートの一覧を出します。
lsofとgrepなどを駆使すれば出せると思います。
JMXクライアントを接続する
JMXクライアントは様々な物がありますが今回はJavaに標準でついてくるJava VisualVMを選びました。
パスが通っていれば下記で起動できると思います
jvisualvm &
実行中のSparkStreamingの調査やヒープダンプを行うことができました。
(画像はイメージです)
参考資料
https://docs.oracle.com/javase/jp/1.5.0/guide/management/agent.html
https://stackoverflow.com/questions/45435237