본문 바로가기

프로그래밍(TA, AA)/JVM 언어

[SPARK] 스파크 실행 구조

분산모드에서 스파크는 하나의 중앙 조정자(coordinator)와 여러 개의 분산 작업 노드로 구성되는 마스터/슬레이브 구조를 사용한다. 중앙 조정자는 드라이버라고 부른다. 드라이버는 executor라고 불리는 다수의 분산 작업자들과 통신한다. 드라이버는 자신만의 자바 프로세스에서 돌아가며 각 익스큐터 또는 독립된 자바 프로세스이다. 하나의 드라이버와 익스큐터들을 합쳐서 스파크 애플리케이션이라고 부른다.



하나의 스파크 애플리케이션은 클러스터 매니저라고 불리는 외부 서비스를 써서 여러 개의 머신에서 실행된다. 이야기했듯이 스파크에는 단독 클러스터 매니저라고 불리는 내장 클러스터 매니저가 함께 패키징되어 있다. 스파크는 그 외에도 유명한 오픈소스 클러스터 매니저인 하둡 얀이나 아파치 메소스에서도 동작한다.



[드라이버]

드라이버란 프로그램의 main() 메소드가 실행되는 프로세스를 말한다. 드라이버는 SparkContext를 생성하고 RDD를 만들고 트랜스포메이션과 액션을 실행하는 사용자 코드를 실행하는 프로세스이다. 스파크 셸을 실행할 때 이미 드라이버 프로그램을 만든 것이다(스파크 셸은 미리 로딩된 sc라고 불리는 SparkContext 객체를 갖고 시작한다) 드라이버가 종료되면 애플리케이션도 종료된다.


사용자 프로그램을 태스크로 변환

스파크 드라이버는 사용자 프로그램을 물리적 실행 단위가 되는 태스크(job은 전체적인 '작업'을 의미하며 task는 하나의 노드에서 실행되는 단위 작업을 의미)로 바꿀 책임을 갖는다. 상위 수준에서 모든 스파크 프로그램은 동일한 구조를 갖는다. 입력으로부터 RDD를 만들고, 트랜스포메이션을 사용하여 새로운 RDD를 받아오며, 데이터를 가져오거나 저장하기 위해 액션을 사용한다. 스파크 프로그램은 내부적으로 연산들의 관계에 대해 논리적인 비순환 그래프(DAG: Directed Acyclic Graph)를 생성한다. 드라이버가 실행될 때 드라이버는 이 논리 그래프를 물리적인 실행계획으로 변환한다.

스파크는 맵/트랜스포메이션을 "pipelining"해서 합치는 등의 여러가지 최적화를 통해 실행 그래프를 여러 개의 단계(stage)로 바꾼다. 각 단계는 순서에 따라 여러 개의 태스크로 이루어지며 단위 작업들은 묶여서 클러스터로 전송된다. 태스크는 스파크의 작업 계층에서 가장 작은 단위의 개체이다. 대개 사용자 프로그램은 수백 개에서 수천 개의 개별 태스크를 실행한다.


익스큐터에서 태스크들의 스케줄링

물리적 실행 계획이 주어지면 스파크 드라이버는 익스큐터ㅡㄹ에서의 개별 작업들을 위한 스케줄을 조정한다. 익스큐터들은 시작하면서 드라이버에 등록을 하게 되므로 항상 애플리케이션의 실행에 대해 전체적으로 볼 수 있다. 각 익스큐터는 태스크들을 실행하고 RDD 데이터를 저장하는 프로세스이다.

스파크 드라이버는 항상 실행 중인 익스큐터들을 살펴보고 각 태스크를 데이터 위치에 기반해 적절한 위치에서 실행될 수 있도록 노력한다. 작업들이 실행되면 이미 캐시된 데이터를 또 저장하는 부작용이 있을수도 있다. 드라이버는 또한 이것들을 추적하여 그 데이터를 사용하게될 이후의 작업들이 적절하게 스케줄될 수 있도록 한다.

드라이버는 기본적으로 4040 포트를 사용하는 WebUI를 통해 스파크 애플리케이션의 실행 정보를 보여준다. 



[익스큐터]

스파크의 익스큐터는 주어진 스파크 작업의 개별 태스크들을 실행하는 작업 실행 프로세스이다. 익스큐터는 스파크 애플리케이션 실행시 최초 한번 실행되며 대개 애플리케이션이 끝날 때까지 계속 동작하지만, 익스큐터가 오류로 죽더라도 스파크 애플리케이션은 계속 실행된다. 익스큐터는 두가지 역할을 한다. 첫번째로 애플리케이션을 구성하는 작업들을 실행하여 드라이버에 그 결과를 되돌려 준다. 두번째로 각 익스큐터 안에 존재하는 블록 매니저라는 서비스를 통해 사용자 프로그램에서 캐시하는 RDD를 저장하기 위한 메모리 저장소를 제공한다. RDD가 익스큐터 내부에 직접 캐시되므로 단위 작업들 또한 같이 실행되기에 용이하다.



[클러스터 매니저]

드라이버와 익스큐터는 어떻게 초기 실행될까? 스파크는 익스큐터를 실행하거나 때때로 드라이버 실행을 위해서도 클러스터 매니저에 의존한다. 클러스터 매니저는 스파크와 붙이거나 뗄수있는(pluggable) 컴포넌트이다. 이는 스파크가 얀, 메소스, 내장 매니저 등 다양한 외부 매니저들 위에서도 돌아갈 수 있게 한다.


스파크 문서들은 지속적으로 각 스파크 애플리케이션을 실행하는 프로세스들을 묘사하면서 드라이버와 익스큐터라는 단어를 사용한다. 마스터(master)와 작업자(worker)는 클러스터 매니저의 중앙 집중화 부분과 분산된 부분을 표시하기 위한 단어로 쓴다. 이 단어들은 헷갈리기 쉬우므로 주의를 요한다. 예를 들어, 하둡 얀은 리소스 매니저라고 불리는 master daemon과 노드 매니저라고 불리는 여러 개의 worker daemon을 띄운다. 하지만 스파크는 드라이버와 익스큐터 모두를 얀 작업 노드들 위에서 실행할 수 있다.



[프로그램 실행하기]

어떤 클러스터 매니저를 쓰든지 간에 스파크는 사용자 프로그램을 스파크에 제출(submit)할 수 있는 단일 스크립트인 spark-submit을 제공한다. 다양한 옵션들에도 불구하고 spark-submit은 다른 클러스터 매니저들에 접속할 수 있으며 사용자의 애플리케이션이 얼마나 많은 자원을 쓸지 조정할 수 있다. 어떤 클러스터 매니저는 spark-submit으로 드라이버를 클러스터 위에서 돌릴 수 있으며, 반면 다른 것들은 오직 로컬 머신에서만 실행할 수 있다. 


클러스터에서 스파크 애플리케이션을 실행할 때 발생하는 단계들은 다음과 같다.


1. 사용자는 spark-submit을 사용하여 애플리케이션을 제출한다.

2. spark-submit은 드라이버 프로그램을 실행하고 사용자가 정의한 main() 메소드를 호출한다.

3. 드라이버 프로그램은 클러스터 매니저에게 익스큐터 실행을 위한 리소스를 요청한다.

4. 클러스터 매니저는 드라이버 프로그램을 대신해 익스큐터들을 실행한다.

5. 드라이버 프로세스가 사용자 애플리케이션을 통해 실행된다. 프로그램에 작성된 RDD의 transformation과 action에 기반하여 드라이버는 작업 내역을 단위 작업 형태로 나눠 익스큐터들에게 보낸다.

6. 단위 작업들은 결과를 계산하고 저장히기 위해 익스큐터에 의해 실행된다.

7. 드라이버의 main()이 끈나거나 SparkContext.stop()이 호출된다면 익스큐터들은 중지되고 클러스터 매니저에 사용했던 자원을 반환한다.





'프로그래밍(TA, AA) > JVM 언어' 카테고리의 다른 글

[SPARK] 스파크 UI  (0) 2018.10.27
[SPARK] 스파크 SQL  (0) 2018.10.21
[SPARK] 스파크의 직렬화  (0) 2018.10.19
[SPARK] 스파크 환경관련 메모  (0) 2018.10.17
[SPARK] 스파크의 처리 모델 RDD  (0) 2018.10.09