Apache Spark: 데이터 병렬-분산 처리 (1)
참고
공식문서
목차
들어가는 말1. 아파치 스파크
1) Key Feature
2) 장점
3) 등장 배경
4) 역사
5) 기본 아키텍처
6) 기본 기능 (PySpark)2. 구조적 API: DataFrame, Spark SQL, Dataset3. 저수준 API: RDD4. 성능 튜닝
들어가는 말
‘프로그래밍 언어'라는 글에도 썼듯이, 소프트웨어로 문제를 해결하기 위해서는, 프로그램 작성을 위한 제약 조건들에 대해 이해해야 하는데, 그 중 중요한 것이 프로그래밍 언어의 특성을 이해하는 것이다.
Spark 는 “빅데이터 처리”와 관련된 소프트웨어 문제를 해결하기 위한 라이브러리 집합이다. “빅데이터 처리” 문제를 해결하는 프로그래밍 언어 중 하나라고 생각해도 좋을 것이다. 이 글에서 Spark 는 빅데이터를 어떤 자료구조에 담는지, 어떤 API 를 이용해 어떻게 데이터를 처리하는지 알아보도록 하자! 😄
개인적으로 좋은 엔지니어가 되기 위해서는 자기만의 관점을 갖는 것이 중요하다고 생각한다. 이번 시리즈가 데이터 엔지니어를 준비하는, 그리고 데이터 엔지니어로 성장하고 있는 사람들이 자기만의 엔지니어링 관점을 갖고, 그 관점들을 공유하는 공간이 되었으면 좋겠다.
참고) 새로운 정보 처리 기술을 볼 때 나의 관점
→ 왜, 무엇을, 어떻게
→ 컴퓨터는 상태(데이터)를 변경하는 기계
→ 이 상태의 변화 과정은 Input, Processing, Output, 이렇게 세 단계로 나뉨
1. 아파치 스파크
Apache Spark™ is a multi-language engine for executing data engineering, data science, and machine learning on single-node machines or clusters.
1–1) Key Features (공식 홈페이지)
- Batch/Streaming Data
원하는 언어 (Python, SQL, Scala, Java, R) 를 사용해 데이터 프로세싱을 통합할 수 있다. - SQL Analytics
빠르고, 분산화된 ANSI SQL 쿼리를 사용해 ad-hoc 한 레포트와 대시보드를 생성할 수 있다. Data Warehouse 보다 빠르다. - Data Science at scale
downsampling(데이터의 크기를 줄이는 것) 없이도, peta(10¹⁵)byte 크기의 데이터에 대한 Exploratory Data Analysis 를 수행할 수 있다. - Machine Learning
랩탑이든, 클러스터링에서든, 같은 코드로 머신러닝 알고리즘을 훈련시킬 수 있다.
1–2) 자랑거리 (공식 홈페이지)
- The most widely-used engine for scalable computing
- Ecosystem
다양한 프레임워크와 통합되고, 클러스터 환경에서 작동 가능하다. - Spark SQL Engine: advanced distributed SQL 엔진이 탑재되어 있다.
→ Adaptive Query Execution: 런타임에 실행 계획을 자동 조정
→ Support for ANSI SQL: 익숙한 SQL 쿼리 문법 사용
→ Structure and unstructured data: 반구조화 데이터 쿼리도 가능
1–3) 등장 배경
- 무어의 법칙의 한계
하드웨어의 성능 향상이 2005년 경에 멈추게 되면서(물리적인 방열 한계), 성능 향상을 위한 병렬 처리를 하게 됨. - 데이터 양 급증
데이터 저장과 수집 기술이 발전하면서 비용이 저렴해지게 됨. 그만큼 수집되는 데이터의 양도 단일 컴퓨터에서 처리하지 못할 정도로 거대해짐. 클러스터에서 처리해야할 필요성이 생김.
1–4) 역사
- UC 버클리 AMPLab 소속원들의 2009년 스파크 연구 프로젝트로 시작
→ [ Spark: Cluster Computing With Working Sets ] 논문을 통해 시작
→ 클러스터 컴퓨팅의 잠재력 & 맵리듀스 엔진을 사용하는 대규모 애플리케이션의 난이도와 효율성 문제 (연산 단계마다 데이터를 처음부터 읽어야 함)
=> 간결하게 개발할 수 있는 함수형 API
=> 연산 단계에서 메모리에 저장된 데이터를 효율적으로 공유할 수 있는 새로운 엔진 기반의 API 를 구현 - 스파크 1.0 이전 버전: 함수형 연산(자바 객체로 이루어진 컬렉션에 맵이나 리듀스 같은 연산을 수행하는 방식) 관점에서 API 정의
- 스파크 1.0 버전 이후: 구조화된 데이터를 기반으로 동작하는 신규 API인 스파크 SQL 이 추가(고정형 데이터 포맷을 사용하는 스파크 테이블은 자바의 인메모리 데이터 표현 방식에 종속되지 않음)
→ 스파크 SQL 은 데이터 포맷과 코드를 잘 이해하는 라이브러리와 API를 이용해 새롭고 강력한 최적화 기능을 제공 - 이후 DataFrame, 머신러닝 파이프라인 그리고 자동 최적화를 수행하는 구조적 스트리밍 등 강력한 구조체 기반의 신규 API 추가
1–5) 기본 아키텍처
- 컴퓨터 클러스터: 여러 컴퓨터의 자원을 모아 하나의 컴퓨터처럼 사용하는 것
- 클러스터 관리자: 사용가능한 자원을 파악
클러스터의 데이터 처리 작업을 관리하고 조율함
→ 연산에 사용할 클러스터 관리자: 스파크 Standalone 클러스터 매니저, 하둡 Yarn, 메소스(Mesos)
→ 사용자는 클러스터 관리자에 스파크 애플리케이션을 제출(submit)
→ 클러스터 관리자는 애플리케이션 실행에 필요한 자원을 할당 - Driver 프로세스: 주어진 작업을 완료하기 위해 드라이버 프로그램의 명령을 Executor에서 실행할 책임이 있음
클러스터 노드 중 하나에서 실행되며 main( ) 함수를 실행. 스파크 애플리케이션 정보의 유지 관리, 사용자 프로그램이나 입력에 대한 응답, 전반적인 Executor 프로세스의 작업과 관련된 분석, 배포 그리고 스케줄링 역할을 수행하기 때문에 필수적
→ 애플리케이션 수명주기 동안 관련 정보를 모두 유지
(Driver 프로세스, Executor 프로세스 모두 단순한 프로세스이므로 같은 머신이나 다른 머신에서 실행할 수 있지만, 로컬 모드로 실행하면 Driver 와 Executor를 단일 머신에서 스레드 형태로 실행함) - Executor 프로세스: 드라이버 프로세스가 할당한 작업을 수행 & 드라이버가 할당한 코드를 실행하고 진행 상황을 다시 드라이버 노드에 보고하는 역할
- Spark API
1) 저수준의 비구조적(Unstructured) API
2) 고수준의 구조적(Structured) API - Spark Session
대화형 모드:spark-shell
혹은pyspark
명령어로 spark 콘솔에 접속 → Spark Session 이 자동으로 생성
standalone application:spark-submit
을 통해 사용자 명령과 데이터를 스파크 애플리케이션에 전송 → SparkSession 객체를 직접 생성해야함
Spark Application 은 Spark Session 이라고 불리는 드라이버 프로세스로 제어한다. SparkSession 인스턴스와 Spark Application 은 1대 1 대응이며, Spark Session 인스턴스는 사용자가 정의한 처리 명령을 클러스터에서 실행한다. - DataFrame: 테이블의 데이터 Row, Column 으로 단순하게 표현
(스키마: 컬럼과 컬럼의 타입을 정의한 목록을 스키마라고 부름)
(스키마 추론)
=> 단일 컴퓨터에 저장하기에는 데이터가 너무 크거나 계산이 오래 걸리므로 데이터를 클러스터에 분산시켜놓음 - Partition: Spark 는 모든 Executor 가 병렬로 작업을 수행할 수 있도록 ‘파티션'이라고 불리는 청크 단위로 데이터를 분할한다. 파티션은 클러스터의 물리적 머신에 존재하는 Row 의 집합.
Dataframe의 Partition 은 실행중에 데이터가 컴퓨터 클러스터에서 물리적으로 분산되는 방식을 나타냄.
→ Spark 의 병렬성은 파티션과 익스큐터의 갯수로 결정됨 - Transformation: Spark 의 핵심 데이터 구조는 불변성을 가지므로, 변경을 원할 때 변경 방법을 Spark 에게 알려주는 것.
→ 데이터 처리의 비즈니스 로직을 표현하는 핵심 개념
→ 트랜스포메이션을 사용해 논리적 실행 계획을 세울 수 있다
1) 좁은 의존성 (1:1) — 파이프라이닝을 자동으로 수행
2) 넓은 의존성(1:N) — 클러스터에서 파티션을 교환하는 셔플이 일어남 - Lazy Evaluation
스파크가 연산 그래프를 처리하기 직전까지 기다리는 동작 방식
특정 연산 명령이 내려진 즉시 데이터를 수정하지 않고, 원시 데이터에 적용할 트랜스포메이션의 실행 계획을 생성 => 전체 데이터 흐름을 최적화하는 강점을 지님
→ Dataframe 조건절 푸시다운(Predicate Pushdown): 데이터 소스로 위임(처리에 필요한 자원을 최소화하기 위해)하는 최적화 작업을 자동으로 수행 - Action: 실제연산을 수행하기 위한 사용자 명령. 트랜스포메이션으로부터 결과를 계산하도록 지시하는 명령
1) 카운트
2) 콘솔에서 데이터를 보는 액션
3) 각 언어로 된 네이티브 객체에 데이터를 모으는 액션
3) 출력 데이터 소스에 저장하는 액션
액션을 지정하면 스파크 잡이 시작된다. 스파크 잡은 필터(좁은 트랜스포메이션)을 수행한 후 파티션별로 레코드 수를 카운트(넓은 트랜스포메이션) 한다. 그리고 각 언어에 적합한 네이티브 객체에 결과를 모은다. - Spark UI: 스파크 잡의 상태, 환경 설정, 클러스터 상태 등의 정보를 확인할 수 있다. 스파크 잡을 튜닝하고 디버깅할 때 유용하다.
- DAG: 실행 계획은 트랜스포메이션의 지향성 비순환 그래프이며 액션이 호출되면 결과를 만들어낸다.
1–6) 기본 기능 (PySpark)
- Spark SQL and Data Frame
Spark SQL 은 구조적 데이터 프로세싱을 위한 스파크 모듈이다. Spark SQL 은 DataFrame 이라는 추상 객체를 제공하고, 분산환경에서 동작 가능하다. - Streaming
Apache Spark의 Streaming 기능은 Spark 의 내구성과 쉬운 사용성의 장점을 유지하면서도, 상호작용이 가능하고, 분석 어플리케이션을 가능하게 한다. - MLlib: 머신러닝 파이프라인 가능
- Spark Core
Spark Core 는 다른 모든 기능의 기반이 되는 Spark 플랫폼의 기본적인 실행엔진입니다. RDD(Resilient Distributed Dataset) 및 인메모리 컴퓨팅 기능을 제공합니다.