[Spark] DataFrame, Cluster by SQL, Application, Structured API : 데이터프레임, SQL이 사용된 클러스터, 애플리케이션, 구조적 API

KingU·2023년 1월 4일

Spark

목록 보기
2/3

DataFrame, Cluster by SQL, Application, Structured API : 데이터프레임, SQL이 사용된 클러스터, 애플리케이션, 구조적 API



1. 스파크의 기본 아키텍처


컴퓨터 클러스터는 여러 컴퓨터의 자원을 모아 하나의 컴퓨터처럼 사용
컴퓨터 클러스터를 구성하는 것만으로는 부족하여 조율할 수 있는 프레임워크가 필요
스파크가 바로 그런 역할을 하는 프레임워크
스파크는 클러스터의 데이터 처리 작업을 관리하고 조율

스파크가 연산에 사용할 클러스터를 관리하는 클러스터 매니저

  • 스파크 Standalone 클러스터 매니저
  • 하둡 YARN
  • Mesos

클러스터 매니저는 애플리케이션 실행에 필요한 자원을 할당

1. 스파크 애플리케이션

1) 스파크 애플리케이션

  • Driver 프로세스
  • 다수의 Executor 프로세스

드라이버 프로세스는 클러스터 노드 중 하나에서 실행되며 main() 함수를 실행

2) 스파크 애플리케이션 정보에서의 역할

  • 유지 관리
  • 사용자 프로그램이나 입력에 대한 응답
  • 전반적인 익스큐터 프로세스의 작업과 관련된 분석
  • 배포
  • 스케줄링

드라이버 프로세스는 애플리케이션의 수명 주기 동안 관련 정보를 모두 유지

3) 익스큐터의 역할

  • 드라이버가 할당한 코드를 실행
  • 진행 상황을 다시 드라이버 노드에 보고






2. 스파크의 다양한 언어 API


스파크의 언어 API를 이용하면 다양한 프로그래밍 언어로 스파크 코드르 실행 가능
스파크는 모든 언어에 맞는 몇몇 핵심 개념을 제공합
핵심 개념은 클러스터 머신에서 실행되는 스파크 코드로 변환

  • Scala : 스파크는 스칼라로 개발되어 있으므로 스칼라가 스파크의 기본언어
  • Java : 스파크 창시자들은 자바를 이용해 스파크 코드를 작성할 수 있도록 심혈을
  • Python : 파이썬은 스칼라가 지원하는 거의 모든 구조를 지원
  • SQL : 스파크는 ANSL SQL:2003 표준 중 일부를 지원
  • R : 스파크는 일반적으로 사용하는 두개의 R 라이브러리 존재
    • SparkR
    • sparklyr

위 그림은 SparkSession과 스파크의 언어 API 간의 관계
사용자는 스파크 코드를 실행하기 위해 sparksession 객체를 진입점으로 사용






3. 스파크 API

기본적으로 두 가지 API를 제공

  • 저수준의 비구조적 API
  • 고수준의 구조적 API






4. SparkSession


사용자 명령어와 데이터를 스파크 애플리케이션에 전송하는 방법
대화형 모드로 스파크를 시작하면 애플리케이션을 관리하는 SparkSession이 자동으로 생성

스탠드얼론 애플리케이션으로 스파크를 시작하면
사용자 애플리케이션 코드에서 SparkSession 객체를 직접 생성

스파크 애플리케이션은 SparkSession이라 불리는 드라이버 프로세스로 제어
SparkSession 인스턴스는 사용자가 정의한 처리 명령을 클러스터에서 실행
하나의 SparkSession은 하나의 스파크 애플리케이션에 대응






5. DataFrame


DataFrame은 가장 대표적인 구조적 API
DataFrame은 테이블의 데이터를 로우와 칼럼으로 단순하게 표현
스파크 DataFrame은 수천 대의 컴퓨터에 분산
여러 컴퓨터에 데이터를 분산하는 이유
=> 단일 컴퓨터에 저장하기에는 데이터가 너무 크거나 계산에 너무 오랜 시간이 걸릴 수 있기 때문

1) 파티션

모든 익스큐터가 병렬로 작업을 수행할 수 있도록 파티션이라 불리는 청크 단위로 데이터를 분할
파티션은 클러스터의 물리적 머신에 존재하는 로우의 집합을 의미
DataFrame의 파티션은 실행 중에 데이터가 컴퓨터 클러스터에서 물리적으로 분산되는 방식
만약 파티션이 하나라면 스파크에 수천 개의 익스큐터가 있더라도 병렬성은 1
수백 개의 파티션이 있더라도 익스큐터가 하나밖에 없다면 병렬성은 1

DataFrame을 사용하면 파티션을 수동 혹은 개별적으로 처리할 필요가 없음
물리적 파티션에 데이터 변환용 함수를 지정하면 스파크가 실제 처리 방법을 결정
RDD 인터페이스를 이용하는 저수준 API 역시 제공됩니다.






6. 트랜스포메이션


스파크의 핵심 데이터 구조는 불변성을 가짐
DataFrame을 변경하려면 원하는 변경 방법을 스파크에 알려야함
이때 사용하는 명령을 트랜스포메이션이라 부름
다음 코드는 DataFrame에서 짝수를 찾는 간단한 트랜스포메이션 예제입니다.

Scala

val divisBy2 = myRange.where("number % 2 = 0")

추상적인 트랜스포메이션이지만 지정한 상태이기 때문에
Action을 호출하지 않으면 스파크는 실제 트렌스포메이션을 수행하지 않음
트랜스포메이션은 스파크에서 비즈니스 로직을 표현하는 핵심 개념

트랜스포메이션에는 두 가지 유형

  • 좁은 의존성(narrow dependency)
  • 넓은 의존성(wide dependency)

1) 좁은 의존성(narrow dependency)

좁은 의존성을 가진 트랜스포메이션은 각 입력 파티션이 하나의 출력 파티션에만 영향을 미침

이전 코드 예제에서 where 구문은 좁은 의존성을 가짐
따라서 하나의 파티션이 하나의 출력 파티션에만 영향을 미침

2) 넓은 의존성(wide dependency)

넓은 의존성을 가진 트랜스포메이션은 하나의 입력 파티션이 여러 출력 파티션에 영향을 미침

스파크가 클러스터에서 파티션을 교환하는 셔플(Shuffle)이라는 단어
스파크는 셔플의 결과를 디스크에 저장

3) 지연 연산 (lazy evaluation)

스파크가 연산 그래프를 처리하기 직전까지 기다리는 동작 방식을 의미
스파크는 이 과정을 거치며 전체 데이터 흐름을 최적화하는 엄청난 강점






7. 액션 (Action)

사용자는 트랜스포메이션을 사용해 논리적 실행 계획을 세움
하지만 실제 연산을 수행하려면 액션 명령을 내려야 함
액션은 일련의 트랜스포메이션으로부터 결과를 계산하도록 지시하는 명령
가장 단순한 액션인 count 메서드는 DataFrame의 전체 레코드수를 반환

divisBy2.count()
count 외에도 다음 세 가지 유형의 액션이 있습니다.

  • 콘솔에서 데이터를 보는 액션
  • 각 언어로 된 네이티브 객체에 데이터를 모으는 액션
  • 출력 데이터소스에 저장하는 액션

액션을 지정하면 스파크 잡이 시작
스파크 잡은 필터(좁은 트랜스포메이션)를 수행한 후
파티션 별로 레코드 수를 카운트(넓은 트랜스포메이션)
그리고 각 언어에 적합한 네이티브 객체에 결과를 모음
이때 스파크가 제공하는 스파크 UI로 클러스터에서 실행 중인 스파크 잡을 모니터링 가능






8. 스파크 UI

스파크 UI는 스파크 잡의 진행 상황을 모니터링할 때 사용
스파크 UI는 드라이버 노드의 4040 포트로 접속
로컬 모드에서 실행했다면 스파크 UI의 주소는 http:/localhost:4040

스파크 UI에서 확인 가능한 것

  • 스파크 잡의 상태
  • 환경 설정
  • 클러스터 상태
    etc...
    스파크 UI는 스파크 잡을 튜닝하고 디버깅할 때 매우 유용






There is rather joy in life in hardship. A voyage without wind waves, how monotonous! The more hardships I suffer, the more my heart beats.
Friedrich Wilhelm Nietzsche
차라리 고난 속에 인생의 기쁨이 있다. 풍파 없는 항해, 얼마나 단조로운가! 고난이 심할수록 내 가슴은 뛴다.
니체

profile
원하는 것을 창조하고 창조한 것을 의미있게 사용하자

0개의 댓글