[스파크] 핵심 개념

맵리듀스보다 좋은 이유

  • 맵리듀스는 데이터 처리마다 중간에 데이터를 디스크에 저장
  • disk io 를 기본적으로 줄이고 메모리 레벨에서 처리
  • 리니지를 활용해서 dag workflow 를 최적화

스파크 장단점

  • 장점: 메모리 기반이라 데이터 처리가 빠름(특히 반복 처리). 내부적으로 최적의 데이터 흐름을 찾음(lazy evaluation). 다양한 API 제공
  • 단점: 데이터 셔플링 발생 시 느림. 메모리 의존성이 강하여 튜닝이 중요.

RDD

  • 스파크에서 사용하는 분산 데이터 모델
  • 읽기 전용으로 연산을 가하면 새로운 RDD가 생김(readonly, immutable)
  • 변화 과정만 기록(리니지)하여 문제 발생 시 해당 RDD를 쉽게 복원 가능
  • 파티션이라는 더 작은 단위로 나뉘어, 파티션 단위로 병렬 수행

transformation, action

  • transformation: 기존 RDD에 연산을 가해 새로운 RDD를 만듦(리턴 타입이 RDD). 바로 실행되지 않음(lazy evaluation)
  • action: 리턴 타입이 RDD가 아님(파일 저장, 숫자 반환 등). 실제 연산이 수행되는 시점. 액션이 수행될때 실행(내부 최적화 로직. 지역성 높이게)

넓은 의존성, 좁은 의존성

  • 기존 RDD 와 새로운 RDD 간 관계를 표현
  • 넓은 의존성은 새로운 RDD 생성시 셔플이 발생(groupby, reduceby 같은..)
  • 좁은 의존성은 셔플없이 단일 파티션에서 새로운 RDD 생성 가능(map, filter, etc.)

job, stage, task

  • RDD 에서 action 이 수행되면 RDD는 JOB으로 바뀜(dag 스케줄러에게 전달)
  • 잡은 액션 수만큼 생성
  • job은 여러개의 stage로 나뉨(새로운 stage 혹은 stage 분기는 action 에서 셔플이 발생할때 생김)
  • stage는 또 여러 개의 task로 나뉨(셔플링 필요 여부에 따라 stage가 생김)
  • task들은 직렬화되어 executor로 분배되어 각 파티션들을 처리

드라이버 프로그램

  • job 을 수행하는 프로그램(main 함수)
  • 드라이버 메인 함수 내에서 sc 를 만들어 잡을 실행하고 종료하는 역할
  • sc를 통해 rdd 연산 정보(리니지)를 dag 스케줄러에게 전달하면 스케줄러는 이 정보를 클러스터 매니저(yarn)에게 전달
  • 스케줄러는 지역성을 최대로 하도록 실행 계획 수립(셔플 최소화)

파티션

RDD 를 구성하는 작은 단위. 실제 병렬로 수행되는 작업 단위

스파크 어플리케이션 실행과정 179

스파크 컨텍스트

  • 드라이버 프로그램 내에서 어플리케이션과 스파크 클러스터 연결 담당(db connection 같은)
  • 하나의 어플리케이션에 단 하나의 sc만 존재. 다른 어플리케이션과 공유 불가능
  • SparkConf 를 통해 설정 정보 인자로 전달
  • RDD 생성 시 사용

디플로이 모드 185

  • 클라이언트: 어플리케이션을 실행한 프로세스 내부에서 드라이버 프로그램 실행. 디버깅 좋음
  • 클러스터: 클러스터 내부에서(워커 노드 중 하나) 드라이버 프로그램이 동작. 드라이버 프로그램과 익스큐터 간 네트워크 비용 낮아짐

클러스터 매니저

  • standalone: 테스트 목적. 별도 설치 X. 마스터##슬레이브 구조. 슬레이브에서 익스큐터 동작
  • mesos: 다수의 어플리케이션(프레임워크)이 동일한 자원을 공유(동적 할당). 비슷한 방식이 스파크에도 있음.
  • yarn: 하둡 클러스터 매니저. 별도 클러스터 필요없음. 리소스 매니저랑, 노드 매니저를 통해 작업 수행

스파크 세션

  • 데이터프레임/데이터셋을 생성하거나 사용자 정의 함수(UDF) 를 등록하기 위한 목적
  • spark session의 builder 메소드를 이용하여 인스턴스 생성

익스큐터

  • 각 워커노드에서 실제 작업을 처리하는 프로세스(스레드가 아님)
  • 실제 cpu 와 메모리를 할당받아 수행
  • yarn 에서는 컨테이너 내에 익스큐터가 생성

스파크 sql

  • 정형 데이터 처리를 위한 스파크 모듈
  • 주로 데이터프레임 처리에 사용

데이터프레임

  • 스파크 sql 에서 사용하는 분산 데이터 모델
  • Row 타입 요소로 구성된 데이터셋
  • 스키마가 있음. SQL 이나 데이터프레임 API 로 데이터 처리
  • 카탈리스트 옵티마이저가 최적화 해줌
  • 장점: 스키마를 기반으로 한 데이터 처리와 내부적인 성능 최적화가 가능
  • 단점: RDD 로는 가능했던 복잡한 처리나 컴파일 타임 오류 체크 기능이 안됨. 이를 개선한 것이 데이터셋
  • RDD 는 내부 데이터 타입을 명확하게 강제. 데이터 프레임은 Row 집합이라는 것만 보장돼있고 실제 데이터 타입 정보는 외부로 노출 안됨
  • 이는 실수로 인해 타입을 잘못 적더라도 IDE 에서 잡아낼 수 없어 또 다른 오류의 원인이 될수 있음

데이터셋

  • 데이터셋이 나오면서 RDD와 데이터프레임 기능이 통합
  • transformation 에는 비타입 연산(row, column 타입 객체로 감싸서 처리), 타입 연산이 존재
  • 파이썬은 지원 안됨

브로드캐스트 변수, 어큐뮬레이터

  • 브로드캐스트 변수: 클러스터 내 모든 서버에서 공유할 수 있는 읽기 전용 자원. 공유하고 싶을때마다 사용하는게 아니라 여러 스테이지에서 반복해서 사용하고자 할때
  • 어큐뮬레이터: 쓰기 동작을 위한 것. 모든 서버가 공유하는 쓰기 공간. 각 서버에서 발생하는 특정 이벤트의 수를 세거나 로그 등을 모아두는 용도로 사용. 드라이버만 읽기 가능

브로드캐스트 조인

  • 두 rdd 중 작은 쪽을 큰 rdd 쪽 파티션으로 복사해서 처리
  • 어떤 게 좋을지는 테스트해봐야….sql optimizer 가 내부적으로 결정하기도 함

cache() 와 persist()

  • 복잡하게 생성되는 경우 RDD를 메모리에 저장하고 싶은 경우에 사용. action 시 노드 메모리에 저장
  • persist 는 디스크와 메모리 모두에 저장하고 싶을 때

coalesce 와 repartition

  • 다양한 연산을 하다보면 최초 설정된 파티션 갯수가 적합하지 않을 수 있음
  • coalesce 나 repartition 을 이용해 RDD 파티션의 개수를 조정할 수 있음
  • coalesce는 줄이는 것만 가능 (셔플 안발생)
  • repartition은 늘리거나 줄이는 거 다 가능 (셔플 발생)

스파크 튜닝

  • 익스큐터 수: 많은 양의 HDFS IO 연산 가능.
  • 익스큐터: 코어가 너무 적으면, 여러 개의 task 를 돌리지 못함. 코어가 너무 많으면 하나의 JVM 에서 너무 많은 일을 해서 HDFS IO 성능이 떨어짐. 보통 5코어 사용.
  • 파티션: 너무 적으면 능률 떨어짐. wide 가 일어나게 되면 파티션이 비균등해질 확률이 높아짐. 리파티션을 통해 균등하게 배분되도록
  • 보통은 trans. 위주니까 익스큐터 많이 하는게 좋음. 셔플이 너무 많다 싶으면 익스큐터 수를 좀 줄이자.
  • map + reducebykey 보단 aggregatebykey
  • join 전에 데이터를 최소화 시키고 하자
  • join 보단 cogroup
  • join 전에 hash partitioner 로 partition 을 명시적으로 지정하고 join 을 수행하는 것이 좋음

© 2021. All rights reserved.

Powered by Hydejack v9.1.4