Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Spark details의 시간, 동시성과 메모리 읽기

Spark details는 Foundry의 Spark 실행 작업을 단계와 태스크 수준에서 조사하는 화면입니다. 실행 시간이 늘어난 구간, 병렬화되지 않은 계산과 데이터 쏠림을 찾는 데 사용할 수 있습니다.

화면 열기

  1. Dataset Preview 또는 Data Lineage의 History에서 빌드를 선택하고 View build report를 엽니다. All builds 목록에서 빌드를 바로 선택할 수도 있습니다.
  2. 간트 차트 아래의 실행 작업 목록에서 작업을 선택합니다.
  3. Spark details를 선택합니다.

Overview의 주요 지표

지표의미
Total runtime across all tasks모든 스테이지에 속한 모든 태스크의 실행 시간을 합한 값
Job duration첫 스테이지 시작부터 마지막 스테이지 완료까지의 Spark 계산 경과 시간
Disk spillage실행기의 RAM에 유지하지 못해 디스크로 내보낸 데이터량의 합
Shuffle write스테이지 및 파티션 사이에서 재분배한 데이터량의 합

태스크 시간의 합과 실제 경과 시간을 나누면 평균적인 병렬성의 단서를 얻을 수 있습니다.

전체 병렬성 비율 = 모든 태스크 실행 시간의 합 / Job duration

비율이 1에 가까우면 병렬 처리가 적다는 신호입니다. 이 값은 CPU 사용률 자체가 아니라 여러 태스크의 경과 시간을 비교한 값입니다.

디스크 사용과 shuffle

메모리에 맞지 않는 데이터는 디스크로 내보내고 다시 읽으므로 처리가 느려질 수 있습니다. 큰 데이터에서는 디스크 사용이 예상되는 동작이기도 합니다. 연산의 특성에 따라 메모리 부족과 실패로 이어지는지 함께 확인합니다.

브로드캐스트하지 않은 조인, 집계와 재파티셔닝은 shuffle을 만들 수 있습니다. shuffle은 네트워크 및 디스크 I/O를 포함하므로 적합한 작은 테이블을 브로드캐스트하거나, 반복 조인 키에 맞는 버킷 구성을 검토하거나, 불필요한 재파티셔닝을 줄여 비용을 낮출 수 있습니다.

스테이지 타임라인

Spark는 변환을 스테이지와 의존 관계로 나눕니다. 타임라인의 왼쪽은 보통 입력 읽기, 오른쪽은 보통 출력 쓰기를 나타냅니다.

예시에서 28, 30, 31, 33, 35는 병렬로 진행할 수 있고 32는 이들 앞선 작업이 끝난 뒤 시작합니다. 다음 단계가 기다리는 시간은 앞선 단계들의 가장 늦은 완료 시점에 의해 정해집니다. 따라서 35만 빠르게 해도 다른 단계가 더 늦게 끝나면 전체 시간은 거의 줄지 않습니다. 가장 긴 의존 경로와 그 뒤의 32를 함께 조사합니다.

태스크 동시성

스테이지의 평균 동시성도 다음 비율로 해석할 수 있습니다.

스테이지 동시성 비율 = 해당 스테이지의 태스크 시간 합 / 스테이지 경과 시간

동시성 차트는 위쪽 간트 차트와 시간 축을 공유하므로 어느 스테이지에서 자원을 사용하지 못하는지 비교할 수 있습니다.

예시의 32는 긴 시간 동안 거의 한 태스크만 진행하는 형태입니다. 이에 비해 잘 분산된 작업은 여러 태스크가 함께 실행되는 모습을 보입니다.

긴 태스크와 데이터 쏠림

이 화면은 스테이지를 원본 코드의 정확한 위치나 전체 물리 실행 계획에 자동으로 역추적하는 기능을 제공하지 않습니다. 대신 스테이지별 시간과 데이터량을 비교하여 조사 범위를 좁힐 수 있습니다.

예시의 태스크 실행 시간 중앙값은 약 2초지만 최대 태스크는 약 1시간 16분입니다. 모든 태스크의 시간 합은 약 1시간 59분이므로 긴 태스크 하나가 그 합의 약 64%를 차지합니다. 스테이지 자체의 경과 시간도 약 1시간 16분이어서 가장 긴 태스크가 종료 시점을 거의 결정합니다.

Stage details로 들어가면 표본 태스크와 스테이지 지표를 더 자세히 볼 수 있습니다.

태스크 22267-0은 약 1시간 16분 동안 약 8,100만 행을 처리합니다. 다른 태스크는 대체로 1만~70만 행 규모입니다. 해당 태스크의 디스크 사용은 약 190GB이고 다른 태스크는 0이며, 최대 실행 메모리는 약 4.5GB로 다른 태스크의 약 1GB 수준보다 큽니다. 시간뿐 아니라 행 수와 메모리를 함께 보면 데이터 쏠림을 확인할 수 있습니다.

태스크 목록은 표본이므로 이를 모든 태스크의 전체 목록으로 해석하지 않습니다.

Executors의 실행 중 스냅샷

Executors 탭의 Snapshot은 실행 중인 작업에서 Java 스택 추적 또는 드라이버 전용 메모리 히스토그램을 수집합니다. 작업이 종료된 뒤에는 새로 수집할 수 없습니다.

스택 추적은 각 스레드가 그 순간 무엇을 실행하는지 보여 주므로 멈춘 작업의 진행 위치를 조사할 수 있습니다. 메모리 히스토그램은 JVM 힙의 Java 객체 개수와 크기를 바이트 단위로 보여 줍니다. JVM 밖의 Python 또는 네이티브 메모리 전체를 나타내는 값과는 구분합니다.

스냅샷 수집 자체도 JVM의 작업을 늘립니다. 특히 메모리 히스토그램은 가비지 컬렉션을 유발하므로 실행 중인 작업의 성능에 영향을 줄 수 있습니다. 더 큰 표본과 SQL 실행 그래프가 필요하면 Spark UI를 사용합니다.