본문 바로가기

OpenSource/Spark

[Trobule Shooting] Spark yarn-client 사용시 SparkContext 종료되는 이슈

Spark yarn-client 사용시 SparkContext 종료되는 이슈



Spark job을 클러스터 매니저를 통해 많이 실행하곤 하는데 그 중에 Yarn 클러스터 매니저, 특히 client모드로 사용시 어느 순간에 sc(SparkContext)가 종료되어 

job을 실행할 수 없는 이슈가 발생해서 글로 남깁니다.

크게 이슈가 없는 상황이라면 job을 재실행하면 되겠지만 하필 Zeppelin을 이용하여 이미 구축되어 있던 Yarn 위에서 동작을 하고 있었습니다.

Zeppelin은 처음 SparkInterpreter를 실행하게 되면 binding 모드에 따라 계속 SparkSession을 유지하게 되어 있습니다. (참고: Zeppelin Documentation)



출처: https://www.cloudera.com/documentation/enterprise/5-6-x/topics/cdh_ig_running_spark_on_yarn.html



그림에서 보이듯이 Yarn client 모드는 spark-submit이 실행되는 장비에서 Spark Driver를 실행하게 됩니다. 

그리고 AM(Application Master)은 Spark driver와 RPC 통신으로 연결되어 있습니다. (Spark driver 위에 있는 YarnScheduler <-> YarnAM)

YarnClientSchedulerBackend(YarnSchedulerBackend의 구현체)는 Spark Application을 제출하고 Application이 종료(성공 또는 실패)될 때 까지 기다립니다.



문제는 여기서부터 발생합니다.

AM과 Driver간의 RPC 통신에서 heartbeat 체크를 하는 로직이 따로 없어서

AM이 Driver가 연결되었는지 확인하는 방법은 AM에 있는 onDisconnected 메소드를 통한 방법 밖에 없습니다.

AM과 Driver간에 TCP 연결이 끊기거나 keep alive 탐색 패킷에 응답이 없을때 호출되며 

이 메소드가 실행되면 결과적으로 (Cluster 모드가 아닐 때) finish 메소드가 호출하게 되고 Application을 SUCCESS 상태로 표기하게 됩니다.

그래서 Driver 모니터 프로세스가 Application의 상태가 SUCCESS로 바뀐 것을 탐지하고 sc를 종료하게 됩니다.

따라서 Spark driver는 네트워크 불안정 등으로 인해 연결이 끊겼을 때 재연결 할 수 있는 방법이 없게 됩니다.



https://github.com/apache/spark/blob/master/resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/ApplicationMaster.scala


그 후에 Zeppelin에서 Spark job을 실행하면 아래와 같이 이미 종료된 sc를 사용할 수 없다는 에러 메시지를 만나게 됩니다.


java.lang.IllegalStateException: Cannot call methods on a stopped SparkContext. This stopped SparkContext was created at: org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:860)



client 모드 일때만 finish 메소드가 호출되므로 로그 확인, 디버깅 등의 이유가 아니라면 client 모드보다는 cluster 모드를 사용하는 것이 좋겠습니다.