스파크 모니터링과 계측

스파크 모니터링과 계측

스파크 애플리케이션을 모니터링하는 방법은 크게 세 가지 — 웹 UI, 메트릭, 외부 계측 — 이 있어요. 각 SparkContext는 기본적으로 4040 포트에 웹 UI를 띄워서 스테이지·태스크 목록, RDD 크기·메모리 사용 요약, 환경 정보, 실행 중인 익스큐터 정보를 보여줘요. 여기에 히스토리 서버로 사후 분석까지 가능하고, REST API와 메트릭 시스템으로 자체 모니터링 도구를 만들 수도 있어요. 하나씩 살펴볼게요.

출처: Monitoring and Instrumentation - Apache Spark 공식 문서

본문

웹 인터페이스

애플리케이션이 도는 동안에는 브라우저에서 http://<driver-node>:4040을 열면 웹 UI를 볼 수 있어요. 같은 호스트에서 SparkContext가 여러 개 돌면 4040부터 시작해 4041, 4042 식으로 다음 포트에 바인딩돼요. 이 정보는 기본적으로 애플리케이션이 도는 동안에만 볼 수 있어요.

사후에 보기 (히스토리 서버)

애플리케이션이 끝난 뒤에도 UI를 보고 싶으면 시작 전에 spark.eventLog.enabled=true를 설정해요. 그러면 스파크가 UI에 표시되던 정보를 인코딩한 이벤트를 영속 저장소에 기록해요. 이후 스파크 히스토리 서버로 그 이벤트 로그를 재구성해 UI를 만들 수 있어요.

히스토리 서버는 이렇게 시작해요.

./sbin/start-history-server.sh

기본적으로 http://<server-url>:18080에 웹 인터페이스가 생기고, 완료·진행 중인 애플리케이션과 시도(attempt)를 나열해요. 파일시스템 프로바이더 클래스(spark.history.provider)를 쓰면 spark.history.fs.logDirectory 설정에 기본 로깅 디렉터리를 주고, 그 안의 각 하위 디렉터리가 애플리케이션 하나의 이벤트 로그로 취급돼요. 스파크 잡들은 이벤트를 기록하도록, 그리고 같은 공유·쓰기 가능 디렉터리에 기록하도록 설정돼야 해요. 예를 들어 서버 로그 디렉터리가 hdfs://namenode/shared/spark-logs라면 클라이언트 쪽 설정은 이래요.

spark.eventLog.enabled true
spark.eventLog.dir hdfs://namenode/shared/spark-logs

히스토리 서버 관련 환경 변수로는 SPARK_DAEMON_MEMORY(기본 1g), SPARK_DAEMON_JAVA_OPTS, SPARK_DAEMON_CLASSPATH, SPARK_PUBLIC_DNS(공개 주소, 안 잡으면 애플리케이션 히스토리 링크가 내부 주소를 써서 깨질 수 있어요), SPARK_HISTORY_OPTS(spark.history.* 설정)가 있어요.

롤링 이벤트 로그 압축: 스트리밍 같은 장기 실행 애플리케이션은 이벤트 로그 파일이 하나로 커질 수 있어요. spark.eventLog.rolling.enabledspark.eventLog.rolling.maxFileSize를 켜면 하나의 거대 파일 대신 롤링 파일을 갖게 돼요. 스파크 히스토리 서버는 spark.history.fs.eventLog.rolling.maxFilesToRetain 설정으로 롤링 이벤트 로그를 압축해 전체 로그 크기를 줄일 수 있어요. 단 압축은 손실(lossy) 작업이에요 — 일부 이벤트가 버려져 UI에서 더 이상 안 보일 수 있으니 켜기 전에 어떤 이벤트가 버려질지 확인하는 게 좋아요. 압축은 끝난 잡(spark job) 관련 이벤트와 그 stage/태스크, 종료된 익스큐터 이벤트, 끝난 SQL 실행과 관련 이벤트를 버리는 경향이 있어요. 스파크 3.0에서 도입된 비교적 새로운 기능이라 완전히 안정적이진 않으니 주의해서 써요.

히스토리 서버 구성 옵션: 주요 설정으로 spark.history.provider(기본 org.apache.spark.deploy.history.FsHistoryProvider), spark.history.fs.logDirectory(기본 file:/tmp/spark-events), spark.history.fs.numReplayThreads, spark.history.store.maxDiskUsage(기본 10g), spark.history.store.path(디스크 캐시 경로), spark.history.store.serializer(JSON 또는 PROTOBUF, PROTOBUF가 빠르고 컴팩트해요) 등이 있어요.

이 모든 UI에서 표는 헤더를 클릭해 정렬할 수 있어서 느린 태스크, 데이터 스큐 등을 찾기 쉬워요. 히스토리 서버는 완료·미완료 스파크 잡을 모두 보여주고, 실패 후 여러 번 시도하면 실패한 시도와 진행 중이거나 성공한 시도가 함께 표시돼요. 미완료 애플리케이션은 간헐적으로만 갱신돼요(spark.history.fs.update.interval). 실행 중 애플리케이션을 보려면 사실 그 애플리케이션의 자체 웹 UI를 보는 게 맞아요. 크래시로 완료 등록 없이 종료된 애플리케이션은 실제로는 안 돌아도 미완료로 나열될 수 있어요. 스파크 잡 완료를 알리는 방법 중 하나는 SparkContext를 명시적으로 멈추는 거예요(sc.stop()), Python에선 with SparkContext() as sc: 구문으로 생성·정리를 처리해요.

REST API

UI에서 메트릭을 보는 것 외에도 JSON으로도 볼 수 있어요. 개발자가 스파크용 새 시각화·모니터링 도구를 쉽게 만들 수 있죠. JSON은 실행 중인 애플리케이션과 히스토리 서버 모두에서 제공되고, 엔드포인트는 /api/v1에 마운트돼요. 예를 들어 히스토리 서버는 http://<server-url>:18080/api/v1, 실행 중 애플리케이션은 http://localhost:4040/api/v1로 접근할 수 있어요.

API에서 애플리케이션은 [app-id]로 참조돼요. YARN에서 각 애플리케이션은 여러 시도를 가질 수 있는데, 시도 ID는 cluster 모드 애플리케이션에만 있어요(client 모드엔 없음). YARN cluster 모드에선 [app-id]가 사실상 [base-app-id]/[attempt-id]가 돼요.

주요 엔드포인트는 이래요.

  • /applications — 모든 애플리케이션 목록. ?status=[completed|running], ?minDate=, ?maxDate=, ?limit= 등으로 필터.
  • /applications/[app-id]/jobs — 주어진 애플리케이션의 모든 잡. ?status=[running|succeeded|failed|unknown].
  • /applications/[app-id]/jobs/[job-id] — 해당 잡의 상세.
  • /applications/[app-id]/stages — 모든 스테이지. ?status=[active|complete|pending|failed], ?details=true, ?withSummaries=true, ?quantiles=0.0,0.25,0.5,0.75,1.0.
  • /applications/[app-id]/stages/[stage-id] — 해당 스테이지의 모든 시도.
  • /applications/[app-id]/stages/[stage-id]/[stage-attempt-id] — 해당 스테이지 시도의 상세.
  • /applications/[app-id]/stages/[stage-id]/[stage-attempt-id]/taskSummary — 해당 스테이지 시도의 모든 태스크 요약 메트릭.
  • /applications/[app-id]/stages/[stage-id]/[stage-attempt-id]/taskList — 해당 스테이지 시도의 모든 태스크 목록. ?offset=10&length=50&sortBy=runtime&status=running.

메트릭(Metrics)

스파크 메트릭은 여러 타입으로 나뉘는데 gauge, counter, histogram, meter, timer가 있어요(Dropwizard 라이브러리 문서 참고). 메트릭 프로바이더로는 스파크 자체 외에 여러 sink를 쓸 수 있어요. 컴포넌트 인스턴스별로 Driver, Executor, applicationMaster, master, ApplicationSource, worker, shuffleService 등이 있고, JVM 소스도 포함돼요. 외부 계측(advanced instrumentation)으로는 모니터링을 더 깊게 할 수 있는 방법들이 제공돼요.

더 알아보기