러닝 스파크 chapter 3장까지 읽은 내용을 정리해 보고자 한다.
HDFS와 맵리듀스 프레임워크를 사용하여 빅데이터를 처리하는 것에는 단점이 존재한다. 가장 큰 단점은 배치 작업을 수행하면서 MR 태스크의 중간 단계들을 로컬 디스크에 써야했단 점이다. 이것은 잦은 디스크 I/O 수행을 일으키며 데이터 처리 속도가 매우 느려진다.
그래서 아파치 스파크가 탄생하였다. 아파치 스파크는 대규모 분산 데이터 연산 처리를 위해서 설계된 통합형 엔진이다.
스파크는 하둡 맵리듀스의 단점을 보완하며 업그레이드 되었고 4가지 특징이 있다.
첫번째, 속도
스파크는 질의 연산을 방향성 비순환 그래프(DAG)로 구성하고 클러스터의 워크 노드 위에서 병렬 수행된다. 스파크 SQL 엔진 의 주요 기능 중 하나인 텅스텐(Tungsten)은 전체 쿼리를 하나의 함수로 합쳐 가상 함수 호출이나 중간 데이터를 위한 CPU 사용을 없앤다. 이 방법을 포괄 코드 생성이라고 한다. 이러한 방법은 CPU 사용량을 줄이고 효율을 높인다. 하둡 맵리듀스와 다르게 모든 중간 결과는 메모리에 저장되며 디스크 I/O 사용을 줄인다.
두번째, 사용편리성
데이터 프레임, 데이터세트, RDD API로 인해 사용자가 간결하고 단순한 코드 작성이 가능하다.
세번째, 모듈성
4가지 컴포넌트(스파크SQL, 스파크 정형화 스트리밍, MLlib, GraphX)가 존재하며 하나의 엔진 안에서 사용 가능하며 별도의 엔진을 돌릴 필요도 없고 별도의 API를 배울 필요도 없다.
네번째, 확장성
스파크는 빠른 병렬 연산에 초점이 맞춰져 있기에 저장을 담당하는 여러 데이터 소스와의 확장성이 뛰어나다. 하둡은 저장과 연산을 모두 포함하고 있다.
코드가 어떻게 스파크 애플리케이션에서 동작하는지 살펴보자.
애플리케이션
- API를 써서 스파크 위에서 돌아가는 사용자 프로그램. 드라이버와 클러스터 실행기로 이루어진다.
SparkSession
- 스파크 코어 기능들과 상호 작용할 수 있는 진입점을 제공하는 객체이며, 사용자가 SparkSession 객체를 생성해야 한다.
Job
- 스파크 액션에 대한 응답으로 생성되는 여러 태스크로 이루어진 병렬 연산
Stage
- Job은 스테이지라 불리는 서로 의존성을 가지는 다수의 태스크 모음으로 나뉜다.
Task- 스파크 이그제큐터로 보내지는 작업 실행의 가장 기본적인 단위
스파크 연산은 Transformation과 Action으로 나뉘며, Action이 호출되지 않으면 스파크는 아예 실행되지 않는다.
Transformation은 원본 데이터를 수정하지 않고 하나의 스파크 데이터 프레임을 새로 만들어서 결과값을 리턴한다.
모든 Transformation은 결과값이 즉시 계산되지 않는다. 이를 lineage라 하며, 기록된 리니지는 스파크가 트렌스포메이션들끼리 합치거나 재배열하거나 해서 효율적으로 실행할 수 있도록 최적화 한다. 트랜스포메이션을 리니지에 기록만 해두고 실행하지 않는 것을 지연 평가라고 한다. 코드에서 액션을 만났을 때 모든 트랜스포메이션의 지연 연산이 발동되며 새로운 데이터 프레임을 생성하여 작업한다.
=> 지연 평가는 쿼리 최적화를 가능하게 하고 리니지와 데이터 불변성은 장애에 대한 데이터 내구성을 제공한다.
좁은/넓은 트랜스포메이션
하나의 파티션 내에서 처리 할 수 있으면 좁은 트랜스포메이션으로 filter()나 contains()가 포함된다. 반면에 파티션끼리 데이터 교환이 발생하고 디스크 작업 등이 발생하면 넓은 트랜스포메이션으로 groupby()나 orderby()가 포함된다.