Spark executor 메모리 값 관련 문제에 대해서

저는 EKS에서 Fargate를 사용하여 Spark를 실행하고 있습니다.
하지만 Spark executor의 메모리가 항상 제 예상과 다르게 설정되는 이유를 잘 이해하지 못하겠습니다.

아래와 같이 설정했을 때:

ini

CopyEdit

spark.executor.memory = 6g
executor-cores = 2
spark.executor.memoryOverhead = 0.10
spark.memory.offHeap.size = 0

Spark executor pod의 리소스 제한은 실제로 8601Mi로 설정됩니다.
하지만 계산상 (6144 * 0.10) + 6144 = 6,758.4인데, 추가로 1,842.6Mi가 어디에서 오는지 모르겠습니다.

spark-submit 매개변수를 아래와 같이 바꾸면:

ini

CopyEdit

spark.executor.pyspark.memory = 1g
spark.executor.memory = 6g
spark.executor.memoryOverhead = 0.10
spark.memory.offHeap.size = 0

Spark executor pod의 리소스 제한은 9625Mi로 나타납니다.
계산해 보면: 9625 - ((6144*0.10)+6144+1024) = 1,842.6

즉, Spark executor에 할당하는 메모리가 커질수록 이 차이도 더 커집니다.

왜냐하면, Kubernetes에서 실행되는 Spark의 non-JVM 작업의 경우 spark.executor.memoryOverhead기본값이 0.4이기 때문입니다.

이 값은 JVM 외 메모리(overhead memory) 를 위해 할당되는 비율을 설정하는 것으로, 여기에는 off-heap 메모리 할당, non-JVM 태스크, 시스템 프로세스, 그리고 spark.kubernetes.local.dirs.tmpfstrue일 때 사용하는 tmpfs 기반 로컬 디렉토리 등이 포함됩니다.

  • JVM 기반 작업의 경우 기본값은 0.10이고,
  • non-JVM 작업(예: PySpark)의 경우 기본값은 0.40입니다.

이는 non-JVM 작업이 JVM 외부 힙 메모리를 더 많이 필요로 하기 때문이며,
이런 작업들은 종종 "Memory Overhead Exceeded" 오류로 실패하곤 합니다.
이를 방지하기 위해 기본값을 더 높게 설정한 것입니다.

단, spark.driver.memoryOverheadFactorspark.executor.memoryOverheadFactor 값을 명시적으로 설정하면 해당 기본값은 무시됩니다.

1 Like

빠른 답변주셔서 감사합니다. :slight_smile: