클러스터 (Cluster Overview)

클러스터 (Cluster Overview)

이 문서는 Spark가 클러스터에서 어떻게 동작하는지 짧게 훑어보면서, 관련된 구성 요소를 이해하기 쉽도록 설명합니다. 클러스터에 애플리케이션을 실행하는 방법이 궁금하다면 애플리케이션 제출 가이드를 읽어보세요.

구성 요소 (Components)

Spark 애플리케이션은 클러스터 위에서 독립된 프로세스 묶음으로 실행됩니다. 이들을 조율하는 건 여러분의 메인 프로그램 안에 있는 SparkContext 객체인데, 이 메인 프로그램을 드라이버 프로그램(driver program) 이라고 부릅니다.

좀 더 구체적으로 보면, 클러스터에서 실행되기 위해 SparkContext는 여러 종류의 클러스터 매니저(cluster manager) 와 연결할 수 있습니다. Spark 자체의 스탠드얼론(standalone) 클러스터 매니저, YARN, Kubernetes가 그 후보죠. 이 매니저들은 애플리케이션 간에 리소스를 할당해 줍니다. 연결이 끝나면 Spark는 클러스터의 노드들 위에 executor 를 확보합니다. executor는 여러분의 애플리케이션을 위해 계산을 실행하고 데이터를 저장하는 프로세스입니다. 그다음에는 애플리케이션 코드(SparkContext에 넘긴 JAR 또는 Python 파일로 정의된 코드)를 executor로 보내고, 마지막으로 SparkContext가 실행할 task 를 executor에게 보냅니다.

Spark 클러스터 구성 요소

이 구조에서 짚고 넘어갈 유용한 점이 몇 가지 있습니다.

  1. 각 애플리케이션은 자기만의 executor 프로세스를 가집니다. 이 프로세스는 애플리케이션 전체 실행 동안 유지되며, 여러 스레드에서 task를 실행합니다. 덕분에 애플리케이션끼리 서로 격리되는데, 스케줄링 측면(각 드라이버가 자기 task를 직접 스케줄링)과 executor 측면(서로 다른 애플리케이션의 task가 서로 다른 JVM에서 실행) 모두에서 그렇습니다. 다만 그만큼, 서로 다른 Spark 애플리케이션(각각 별도의 SparkContext 인스턴스)끼리는 데이터를 외부 저장 시스템에 쓰지 않고는 공유할 수 없다는 뜻이기도 합니다.
  2. Spark는 클러스터 매니저에 대해 중립적입니다. (cluster-agnostic) executor 프로세스를 확보할 수 있고, 그 프로세스들이 서로 통신할 수만 있다면 다른 애플리케이션도 지원하는 클러스터 매니저(YARN/Kubernetes 같은) 위에서도 비교적 쉽게 실행할 수 있습니다.
  3. 드라이버 프로그램은 살아 있는 내내 executor로부터 들어오는 연결을 받아들여야 합니다. 예를 들어 네트워크 설정의 spark.driver.port를 참고하세요. 그러니까 드라이버 프로그램은 워커 노드에서 네트워크로 접근 가능한 위치에 있어야 합니다.
  4. 드라이버는 클러스터에서 task를 스케줄링하기 때문에 워커 노드와 가깝게, 되도록 같은 로컬 네트워크(LAN)에서 실행하는 게 좋습니다. 클러스터에 원격으로 요청을 보내고 싶다면, 워커 노드에서 멀리 떨어진 곳에 드라이버를 두기보다 드라이버에 RPC를 열어 그 근처에서 작업을 제출하도록 만드는 편이 낫습니다.

클러스터 매니저 종류 (Cluster Manager Types)

현재 시스템은 여러 클러스터 매니저를 지원합니다.

  • Standalone — Spark에 포함된 단순한 클러스터 매니저로, 손쉽게 클러스터를 구성할 수 있게 해 줍니다.
  • Hadoop YARN — Hadoop 3의 리소스 매니저입니다.
  • Kubernetes — 컨테이너화된 애플리케이션의 배포·확장·관리를 자동화하는 오픈소스 시스템입니다.

애플리케이션 제출 (Submitting Applications)

어떤 종류의 클러스터든 spark-submit 스크립트를 이용해 애플리케이션을 제출할 수 있습니다. 구체적인 방법은 애플리케이션 제출 가이드에 설명되어 있습니다.

모니터링 (Monitoring)

각 드라이버 프로그램은 웹 UI를 가지며, 보통 4040 포트에서 실행 중인 task, executor, 스토리지 사용량 정보를 보여줍니다. 웹 브라우저에서 http://<driver-node>:4040에 접속하기만 하면 이 UI를 볼 수 있습니다. 그 외 모니터링 방법은 모니터링 가이드에서도 설명하고 있습니다.

작업 스케줄링 (Job Scheduling)

Spark는 리소스 할당을 제어할 수 있게 해 주는데, 애플리케이션 간 (클러스터 매니저 수준) 그리고 애플리케이션 내부 (같은 SparkContext에서 여러 계산이 일어날 때) 두 가지 수준이 있습니다. 더 자세한 내용은 작업 스케줄링 개요에서 설명합니다.

용어 정리 (Glossary)

다음 표는 클러스터 개념을 다룰 때 자주 보게 될 용어들을 정리한 것입니다.

용어
Application Spark 위에 구축된 사용자 프로그램. 클러스터의 드라이버 프로그램executor 로 구성됩니다.
Application jar 사용자의 Spark 애플리케이션을 담고 있는 jar. 경우에 따라 애플리케이션과 그 의존성을 함께 담은 "uber jar"를 만들고 싶을 수도 있습니다. 사용자 jar에는 Hadoop이나 Spark 라이브러리를 절대 포함하면 안 됩니다. 이들은 런타임에 추가되기 때문입니다.
Driver program 애플리케이션의 main() 함수를 실행하고 SparkContext를 만드는 프로세스.
Cluster manager 클러스터에서 리소스를 확보하기 위한 외부 서비스 (예: standalone 매니저, YARN, Kubernetes).
Deploy mode 드라이버 프로세스가 어디서 실행되는지를 구분하는 방식. "cluster" 모드에서는 프레임워크가 클러스터 안에서 드라이버를 실행하고, "client" 모드에서는 제출자가 클러스터 밖에서 드라이버를 실행합니다.
Worker node 클러스터에서 애플리케이션 코드를 실행할 수 있는 모든 노드.
Executor 워커 노드에서 애플리케이션을 위해 실행되는 프로세스로, task를 실행하고 그 사이에 데이터를 메모리나 디스크 저장소에 유지합니다. 각 애플리케이션은 자기만의 executor를 가집니다.
Task 하나의 executor로 보내질 작업 단위.
Job 여러 task로 구성된 병렬 계산으로, Spark 액션(예: save, collect)에 응답하여 생겨납니다. 드라이버의 로그에서 이 용어를 보게 될 겁니다.
Stage 각 job은 서로 의존하는 더 작은 task 묶음인 stage 로 나뉩니다(MapReduce의 map/reduce 스테이지와 비슷합니다). 드라이버 로그에서 이 용어를 보게 될 겁니다.