Spark

Spark Memory Structure

server 2023. 9. 1. 13:29

개요

  • Spark를 사용할 때 메모리 구조를 잘 이해하는 것이 중요한데 그 이유는 아래와 같습니다.
1. 성능 최적화 : Spark의 메모리 구조를 이해하면, 데이터 셔플링, 캐싱, 연산에 필요한 메모리를 효율적
으로 할당할 수 있어 성능을 향상 시킬 수 있습니다.

2. 장애 예방 : 메모리 부족이나 시스템 과부하등 다양한 문제를 미리 인식하고 적절한 방법으로 해결할 수 있습
니다. 예를 들어, 'OutOfMemoryError' 같은 문제를 피하기 위해 메모리 설정을 조절할 수 있습니다.

3. 디버깅과 튜닝 : 애플리케이션에 문제가 발생했을 때, 메모리 구조를 잘 이해하고 있으면 문제의 원인을 더
빨리 찾고 해결할 수 있습니다. 예를 들어, 왜 데이터 셔플링이 느린지, 왜 특정 연산이 메모리를 많이 사용하
는지 등을 파악할 수 있습니다.

4. API와 라이브러리 선택 : Spark는 다양한 API와 라이브러리를 제공합니다. (RDD, DataFrame,
DataSet) 메모리 구조를 잘 이해하면 어떤 API나 라이브러리가 특정 작업에 가장 적합한지 판단할 수 있습니다

아래에 설명 될 내용은 Executor 메모리 관리에 중점을 두고 설명할 예정입니다.

Executor Memory 분석

  • Reserved Memory
    • 이 메모리는 시스템에서 예약한 메모리이며 크기가 하드코딩 되어 있습니다. Reserved Memory는 300MB로 고정되어 있으며 이 값을 변경하려면 내가 작성한 애플리케이션에서 제어하는게 아니라 Spark source code에서 이 값을 변경한 후 다시 컴파일 해야합니다. 이러한 방식은 권장되지 않습니다.
    • 이 메모리가 왜 필요하냐면 여유 공간 을 확보하기 위함입니다. 예를 들어 메모리 사용량이 급증할 때 안정성을 보장하기 위해 사용됩니다. (네트워크 통신이나 테스크 스케줄링 같은 작업에서 일시적으로 데이터를 저장)
  • User Memory
    • 사용자 정의 데이터 구조(Local Collection : Spark 애플리케이션 내에서 사용되는 일반적인 자료구조(리스트, 배열, 맵)), 사용자가 생성한 모든 UDF 등을 저장하는 메모리 영역입니다. 이 메모리는 애플리케이션 코드에 제어할 수 있는 영역이며 이 메모리 크기는 아래와 같은 계산으로 할당됩니다.
    • User Memory = (Java Heap - Reserved Momory) * (1.0 - spark.memory.fraction)
    • ex ) 4G 할당 → (4096MB - 300MB) * (1.0 - 0.75) = 949MB
  • Spark Memory
    • Spark에 의해 관리되는 영역이며 조인과 같은 작업 실행을 수행하는 동안 중간 상태를 저장하거나 브로드 캐스트 변수를 저장합니다. 모든 cache, persist 데이터는 이 메모리에 저장됩니다. 이 메모리 크기는 아래와 같은 계산으로 할당됩니다.
    • Spark Memory = (Java Heap - Reserved Memory) * spark.memory.fraction
    • ex ) 4G 할당 → (4096MB - 300MB) * 0.75 = 2847MB
  • Spark Memory - Store Memory
    • 캐시된 모든 데이터를 저장하는데 사용되며, 브로드 캐스트 변수도 여기에 저장됩니다.
    • Spark는 LRU(Least Recent Used) 메커니즘을 기반으로 동작합니다
    • 브로드캐스트 변수는 MEMORY_AND_DIST 지속 수준으로 이 세그먼트에 저장됩니다.
    • Spark Memory - Store Memory = (Java Heap - Reserved Memory) * spark.memory.fraction * spark.memory.storageFraction
    • ex ) 4G 할당 → (4096MB - 300MB) * 0.75 *0.5 = 1423MB
  • Spark Memory - Execution Memory
    • 작업 실행 중에 생성된 개체에 대해 Spark에서 사용되는데 예를 들어, 셔플 중간 버퍼를 저장하는데 사용됩니다.
    • 이 메모리는 다른 작업에 의해 강제로 제거가 될 수 없습니다.
    • Spark Memory - Execution Memory = (Java Heap - Reserved Memory) * spark.memory.fraction * (1.0 - spark.memory.storageFraction)
    • ex ) 4G 할당 → (4096MB - 300MB) * 0.75 * (1.0 - 0.5) = 1423MB

참고 문서