ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Apache Spark란?
    Data 2021. 6. 1. 22:18
    반응형

    아파치 스파크는 대량의 데이터 처리를 위한 통합 분석 엔진으로 오픈소스입니다. 스파크는 Java, Scala, Python과 R로 이뤄진 하이레벨 API와 최적화 엔진을 제공하여 기본적인 '실행 그래프'를 지원합니다. 또한, 스파크는 SQL과 정형 데이터 처리를 위한 Spark SQL, 머신러닝을 위한 MLlib, 그래프 프로세싱을 위한 GraphX, 그리고 스트림 처리를 위한 Structured Streaming과 같은 다양한 하이레벨 도구들을 지원합니다 [1].

     

    이 글에서는 아래와 같은 부분을 다뤄보려 합니다:

     

    • 스파크는 어떤 목적으로 만들어졌나?
    • 스파크 RDD와 연관된 연구주제들
    • 스파크 디자인의 철학

     


     

    스파크는 어떤 목적으로 만들어졌나?

    스파크는 UC 버클리의 AMPLab에서 2014년 공식적으로 릴리즈되어 이후 Apache 소프트웨어 재단에 기증되었습니다 [3]. Spark 관련 리서치의 연혁을 살펴보면, Shark라는 명칭의 프레임웍에 대한 내용들이 포함된 것을 볼 수 있습니다 [4]. 이후 Shark는 스파크가 2014년 공식적으로 릴리즈되며, 스파크에 포함되게 되었습니다.  

     

    스파크의 최초의 목적은 가장 초기의 자료를 살펴보면 알 수 있습니다 [2]. 여러가지가 존재하나 해당 논문에서는 아래와 같은 점들을 강조하고 있습니다:

     

    • MapReduce와 유사하게 여러 노드에서 실행되어 확장성을 가지며 fault-tolerance한 대용량 데이터 처리 엔진을 제공

     

    • 기존 MapReduce는 acyclic dataflow 모델에 기반하여 효율적으로 특정 애플리케이션에 적용될 수 없는 한계를 가지기에, RDD (Resilient Distributed Dataset)라는 데이터 모델과 그에 기반한 병렬 연산을 통해 (똑같은 데이터에 반복적인 연산을 하는) Iterative Jobs과 인터랙티브 분석이 가능하도록 함

     

    • MapReduce는 데이터 공유를 오직 stable storage를 통해서 진행하기에 느림. 스파크는 in-메모리 처리 지향을 통해 하둡보다 10배(초기 논문 상에서) 빠른 처리가 가능하도록 함

     

    위와 같은 점을 요약하면, MapReduce와 같이 확장성과 fault-tolerant한 데이터 처리 시스템을 더 다양한 처리 방식을 제공하며 인메모리 기반의 더 빠른 분산 처리 엔진을 만드는 것이 주요 목적이었음을 알 수 있습니다. 

     

    첫 Research Paper 이후 [4]에서 연혁을 살펴보면, 2012년 4월 RDD와 관련한 논문이 제출된 것을 볼 수 있습니다 [5]. [5]에서 스파크 데이터 모델의 근간을 이루는 RDD의 인메모리를 통한 저장, 처리, fault-tolerance 부분의 개선을 전달해주고 있습니다. 해당 논문에서 제목에서도 알 수 있듯이, 핵심 데이터 모델인 RDD를 가다듬고 데이터 모델에 기반한 프로그래밍 인터페이스에 집중한 부분을 알 수 있습니다. 

     

    그러한 개선 중 하나는 DryadLINQ에서와 같은 Lazy Evaluation을 통한 프로그래밍 인터페이스와 함께 Transformation, Action, Lineage와 같은 개념이 적용된 부분입니다. 

    Lazy Evaluation of RDDs - Image from 'Big data analytics on Apache Spark'

     

    그러한 핵심 데이터 모델과 프로그래밍 인터페이스가 정립되고 난후의 논문들을 살펴보면, 이전의 코어(데이터 모델 및 프로그래밍 인터페이스)에 기반하여 사용성을 목적으로 하이레벨 인터페이스 관련된 부분인 것을 알 수 있습니다:

     

    • 2012년 5월 Shark의 데이터 분석 관련
    • 2012년 6월 분산 스트림 프로세싱
    • 2013년 6월 Shark SQL
    • 2013년 11월 분산 스트림 프로세싱 관련
    • 2015년 6월 Spark SQL
    • 2016년 MLlib
    • 2016년 6월 SparkR 

     

    이러한 스파크는 현재 아래와 같은 에코시스템을 이루고 있습니다.

     

    먼저, 아래 부분에서 분산 처리 엔진으로 '분산 자원 관리' 도구들인 YARN, Mesos, Kubernetes 레이어와 저장소 레이어에 기반하고 있습니다. 중심에는 코어에 해당되는 Compute Engine과 그 위에 얹은 다양한 언어로 된 API가 존재합니다. 

     

    상위에는 다양한 프로그래밍 언어로 목적에 따라 처리할 때에 마주하게 되는 프레임웍이 존재합니다. SQL과 같은 형태로 정형 데이터 처리를 위한 SQL과 스트림 프로세싱을 위한 Streaming, 머신러닝 관련 MLlib, 그래프 프로세싱의 GraphX 등의 도구를 통해 분산 클러스터 환경에서 다양한 데이터 처리를 가능하도록 도와줍니다. 

     

    Spark Eco System - Image from TowardDataScience

     

    저장소와 관련해서는 스파크는 아래와 같이 다양한 코넥터를 지원해주고 있습니다. 그렇기에 데이터 환경에서 데이터 처리에 중심에 위치하며 다양한 곳에서 다양한 곳으로 다양한 처리를 분산 환경에서 효율적으로 작업하는데 사용될 수 있습니다.

     

    Apache Spark's ecosystem of connectors - Image from 'Learning Spark'

     

    스파크 RDD와 연관된 연구주제들

    이번 장에서는 RDD와 연관된 연구주제들을 [2, 5]의 Related Work 부분에 기반해 자세히 살펴보고자 합니다. 또한, 그러한 연관 주제들을 살펴보며 어떻게 스파크와 유사하고 다른지 비교검토를 통해 보다 더 자세히 스파크를 이해하고자 합니다. 

     

    Cluster Programming Models

    클러스터 프로그래밍 모델과 관련한 사항들은 몇 가지 그룹으로 나뉠 수 있습니다:

     

    • Data Flow Model 시스템

     MapReduce, Dryad, Ciel는 데이터 처리를 위해 다양한 연산자를 제공하지만 데이터를 stable한 저장소 시스템을 통해 공유합니다.  RDDs는 데이터 복제, I/O, 직렬화의 비용을 피하여 저장소 시스템을 통한 데이터 공유보다 더 효율적입니다. 

     

    • Data Flow System을 위한 하이레벨 프로그래밍 인터페이스 시스템

    DryadLINQ, FlumeJava 등과 같은 Data Flow System을 위한 하이레벨 프로그래밍 인터페이스는 언어에 결합된 API를 제공하여 사용자가 map과 reduce와 같은 연산자를 통해 병렬 콜렉션을 다룰 수 있도록 합니다. 그러나 이러한 시스템에서 병렬 콜렉션은 디스크의 파일들이나 쿼리플랜을 표현하기 위한 임시적인 데이터셋만을 나타냅니다. 그러한 시스템들은 같은 쿼리 상의 여러 연산자 간에 데이터를 파이프라이닝하지만, 쿼리 간에는 데이터를 효율적으로 공유하지 못합니다. 

     

    스파크도 유사하게 편의성을 위해 병렬 콜렉션을 사용하나,  RDD라는 스토리지 추상화를 통해 더 넓은 범위의 애플리케이션을 지원합니다.

     

    • 데이터 공유를 필요로 하는 특정 애플리케이션을 위한 하이레벨 인터페이스 시스템

    이러한 예로, Pregel은 반복적인 그래프 애플리케이션을 지원하고 Twister와 HaLoop은 iterative MapReduce 런타임입니다. 

     

    그러나 이러한 프레임웍들은 지원하는 컴퓨팅 패턴을 위해 암시적으로 데이터 공유를 수행하며 사용자가 직접 선택적으로 데이터 공유를 진행할 수는 없습니다. Pregel 또는 Twister에서는 사용자가 데이터셋을 메모리에 올리고 나서 어떤 쿼리를 실행할지 결정할 수 없습니다 (로드와 실행이 한꺼번에만 진행됨).

     

    RDDs는 명시적으로 분산 스토리지 추상화를 제공하여 위와 같은 특정 애플리케이션을 위한 시스템이 지원하지 못하는 인터랙티브 데이터 마이닝과 같은 형태로도 이용될 수 있습니다. 

     

    • 인메모리 컴퓨팅이 가능한 공유된 mutable 상태 제공 시스템 

    몇몇의 시스템은 사용자가 인메모리 컴퓨팅을 실행할 수 있도록 공유 mutable 상태를 제공하여 줍니다. 예로, Piccolo는 사용자가 분산 해쉬 테이블에 있는 셀을 읽고 업데이트하는 분산 함수를 실행할 수 있도록 해줍니다. Distributed shared system (DSM)과 RAMCloud와 같은 키-밸류 저장소는 비슷한 모델을 제공합니다. 

     

    RDDs는 이러한 시스템과 2가지 부분에서 다릅니다.

     

    1. RDDs는 map, sort, join과 같은 연산자에 기반해 하이레벨 프로그래밍 인터페이스를 제공하는 반면, 위 시스템의 인터페이스는 단순히 셀을 읽고 업데이트할 수 있습니다. 

    2. 위 시스템은 체크포인트와 롤백을 통한 리커버리를 구현하여서 RDDs의 리니지 기반보다 리커버리 시에 더욱 많은 비용을 소모하게 됩니다. 

     

    DSM에 비해서  RDDs는 이외에도 여러 장점을 가집니다. 이 부분은 추후 다른 글에서 전달드리겠습니다. 

     

    Caching Systems

    Nectar는 DryadLINQ  jobs 간의 중간 결과물을 프로그램 분석의 일반적인 하위표현(subexpression)을 식별하여 재사용할 수 있습니다. 이러한 부분은 RDD 기반 시스템에 추가를 고려해볼만한 기능이었습니다. 하지만, Nectar에서는 인메모리 캐싱을 지원하지 않으며, 사용자가 데이터를 persist할지 어떻게 파티션할지에 대한 선택권이 전혀 없었습니다. Ciel과 FlumeJava는 마찬가지로 task 결과를 캐싱할 수 있었으나 인메모리 캐싱이나 데이터 캐싱에 대한 명시적 컨트롤을 지원하지 않았습니다. 

    Lineage

    데이터에 대한 리니지나 출처 정보를 기록하는 것은 과학 컴퓨팅이나 데이터베이스에서 오래전부터 연구되던 주제였습니다. 상세하게는 결과에 대한 설명을 하거나, 타자에 의해 재생성되도록 하거나, 데이터셋이 없거나 워크플로우에 오류가 있을 때 데이터를 다시 컴퓨팅 하는 애플리케이션에 많이 사용되어 왔습니다. RDDs는 fine-grained 리니지의 비용이 적은 병렬 프로그래밍 모델을 제공하기에, 실패 리커버리에 사용될 수 있습니다. 

     

    RDDs의 리니지 기반 리커버리 메커니즘은 MapReduce와 Dryad에서 사용되는 형태와 유사합니다. 하지만, 그러한 시스템에서는 리니지 정보가 job이 끝나면 없어져 복제된 스토리지 시스템을 사용해 데이터를 여러 컴퓨팅 노드에 공유해주어야 했습니다. 반면, RDDs는 컴퓨팅 노드 전반에 리니지를 적용해 복제와 디스크 I/O 비용 없이 인메모리 데이터를 효율적으로 persist하게하였습니다.

     

    Relational Database

     RDDs는 개념적으로 데이터베이스의 뷰와 유사하고, persistent RDDs는 materialized view와 닮았습니다. 하지만 DSM 시스템처럼, 데이터베이스는 주로 모든 레코드에 대한 fine-grained read-write 접근을 허용하고, fault-tolerance를 위해 실행기록과 데이터에 대한 로깅 그리고 일관성 유지를 위한 추가적인 오버헤드를 요구하게 됩니다. 

     

    이러한 오버헤드는 coarse-grained transformation 모델을 기반으로한  RDDs에서는 발생하지 않습니다. 

     

     

    스파크 디자인의 철학

     스파크 디자인은 아래와 같은 4가지 부분에 중점을 두고 설계되었습니다 [6]:

     

    • 속도
    • 사용성
    • 모듈성
    • 확장성

     

    속도

    스파크는 몇 가지 방식을 통해 빠른 속도를 가능하게 합니다.

     

    첫 번째로, 스파크의 내부 구현은 CPU와 메모리 같은 하드웨어 가성비가 개선되며 많은 이점을 가지게 되었습니다. 현재의 일반 서버는 저렴한 값에 수백 기가바이트의 메모리와 다수의 코어를 가지며 유닉스 기반 멀티 쓰레딩과 병렬 처리 기능을 제공합니다. 스파크는 이러한 모든 하위 시스템의 장점을 이용하여 최적화하였습니다. 

     

    두 번째로, 스파크는 처리 계획을 Directed acyclic graph (DAG)라는 논리적 객체로 만듭니다. 이 DAG은 스케쥴러와 쿼리 옵티마이저를 통해 tasks로 나눠질 수 있는 효율적인 그래프로 표현되고 여러 워커에서 병렬적으로 실행될 수 있게됩니다. 

     

    세 번째로, 물리적 실행 엔진은 Tungstenwhole-stage code 생성을 통해 실행을 위한 컴팩트한 코드를 생성합니다. 

     

    네 번째로, 모든 중간결과물이 메모리에 저장되어 전달되며 디스크 I/O를 최소화합니다. 

     

    사용성

    스파크는 RDD라고 불리는 근간에 위치한 논리적 데이터 구조를 제공하여 단순함을 이룹니다. 데이터프레임, 데이터셋과 같은 하이레벨 데이터 구조는 모두 이 RDD에 기반하고 있습니다. 

     

     이러한 데이터 모델에 기반해 transformation과 action이라는 2가지 구분되는 분류에 속한 다양한 프로그래밍 인터페이스를 제공하여 데이터 처리를 쉽게 만들어 줍니다.

     

    모듈성

    스파크 연산은 다양한 형태의 작업에 이용될 수 있고 지원되는 다양한 언어(Scala, Java, Python, SQL, R)로 표현할 수 있습니다. 또한, 스파크는 Spark SQL, Spark Structured Streaming, Spark MLlib, GraphX와 같은 다양한 모듈을 제공하기에 다양한 요구사항에 여러 도구를 사용하는 것이 아니라 스파크로 통합된 하나의 도구로 처리할 수 있게 됩니다. 

     

    확장성

    스토리지와 컴퓨팅을 모두 포함한 하둡과 달리, 스파크는 2가지를 분리하여 컴퓨팅만을 담당합니다. 그렇기에 스파크는 수많은 다양한 데이터 저장소에 접근하여 처리를 할 수 있습니다. 또한, DataFrameReaders와 DataFrameWriters를 확장하여 쉽게 새로운 데이터 저장소에 연결될 수 있습니다.

     

    Reference

    [1] https://spark.apache.org/docs/latest/

    [2] Spark: Cluster Computing with Working Sets

    [3] https://en.wikipedia.org/wiki/Apache_Spark

    [4] https://spark.apache.org/research.html

    [5] Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing

    [6] Learning Spark, 2nd Edition

     

     

     

    반응형
Kaden Sungbin Cho