[Apache Spark] RDD 고급 개념

연수·2021년 11월 30일
0

spark

목록 보기
13/26

🗝️ 키-값 형태의 RDD

  • RDD에는 데이터를 키-값 형태로 다룰 수 있는 다양한 메서드가 있다
  • <연산명>ByKey 형태 → PairRDD 타입만 사용 가능
  • PairRDD 타입은 RDD에 맵 연산을 수행해 키-값 구조로 만들 수 있다. 즉, 레코드에 두 개의 값이 존재한다.
  • KeyBy: 키를 생성하는 함수
  • mapValues, flatMapValues: 값 매핑
  • keys, values: 키와 값 추출
  • lookup: 특정 키에 관한 결과 찾기
  • sampleByKey: 근사치나 정확도를 이용해 키를 기반으로 RDD 샘플을 생성

 

🥦 집계

  • 사용하는 메서드에 따라 일반 RDD나 PairRDD를 사용해 집계를 수행할 수 있다.
  • countByKey
    • 각 키의 아이템 수를 구하고 로컬 맵으로 결과를 수집
  • groupByKey
    • 모든 익스큐터에서 함수를 적용하기 전에 해당 키와 관련된 값을 메모리로 읽어 들여야 한다는 문제점 존재 → OutOfMemoryError
  • reduceByKey
    • 각 파티션에서 리듀스 작업을 수행하기 때문에 훨씬 안정적이며 모든 값을 메모리에 유지하지 않아도 된다.
    • 최종 리듀스 작업을 제외한 모든 작업은 개별 워커에서 처리하기 때문에 연산 중에 셔플이 발생하지 않는다.
    • 안정성 및 연산 수행 속도 향상
  • aggregate
    • 드라이버에서 최종 집계를 수행하기 때문에 성능에 약간의 영향이 있다.
  • treeAggregate
    • 드라이버에서 최종 집계를 수행하기 전에 익스큐터끼리 트리를 형성해 집계 처리의 일부 하위 과정을 '푸시 다운' 방식으로 먼저 수행한다.
  • aggregateByKey
    • 파티션 대신 키를 기준으로 연산을 수행한다.
  • combineByKey
    • 집계 함수 대신 컴바이너를 사용한다.
    • 컴바이너(combiner)는 키를 기준으로 연산을 수행하며 파라미터로 사용된 함수에 따라 결과값을 병합한 뒤 여러 컴바이너의 결과값을 병합해 결과를 반환한다.
  • foldByKey
    • 결합 함수와 항등원인 '제로값'을 이용해 키의 값을 병합한다.

 

🥶 cogroup

  • 스칼라의 경우 최대 3개, 파이선의 경우 최대 2개의 키-값 형태의 RDD를 그룹화할 수 있으며 각 키를 기준으로 값을 결합한다.
  • 즉, RDD에 대한 그룹 기반의 조인을 수행한다.
  • 출력 파티션 수나 클러스터에 데이터 분산 방식을 정확하게 제어하기 위해 사용자 정의 파티션 함수를 파라미터로 사용할 수 있다.
  • 키-값 형태의 배열을 결과로 반환한다.

 

🥐 조인

  • 구조적 API와 거의 동일한 조인 방식을 가지고 있지만, RDD를 사용하면 사용자가 많은 부분에 관여해야 한다.
  • 조인하려는 두 개의 RDD가 기본적으로 필요하며, 때에 따라 출력 파티션 수나 사용자 정의 파티션 함수를 파라미터로 사용한다.

     🤐 zip

  • 동일한 길이의 두 개의 RDD를 지퍼를 잠그듯이 연결할 수 있으며, PairRDD를 생성한다.
  • 두 개의 RDD는 동일한 수의 요소와 동일한 수의 파티션을 가져야 한다.

 

👯‍♀️ 파티션 제어하기

  • RDD를 사용하면 데이터가 클러스터 전체에 물리적으로 정확히 분산되는 방식을 정의할 수 있다.
  • 파티션 함수를 파라미터로 사용할 수 있다.
  • coalesce: 파티션을 재분배할 때 발생하는 데이터 셔플을 방지하기 위해 동일한 워커에 존재하는 파티션을 합치는 메서드
  • repartition: 파티션 수를 늘리거나 줄일 수 있지만, 처리 시 노드 간의 셔플이 발생할 수 있다.
  • repartitionAndSortWithinPartitions: 파티션을 재분부핼 수 있고, 재분배된 결과 파티션의 정렬 방식을 지정할 수 있다.

     👾 사용자 정의 파티셔닝

  • RDD를 사용하는 가장 큰 이유 중 하나
  • 사용자 정의 파티셔너는 저수준 API의 세부적인 구현 방식이며, 잡이 성공적으로 동작되는지 여부에 상당한 영향을 미친다.
  • 예) 페이지랭크 → 사용자 정의 파티셔닝을 이용해 클러스터의 데이터 배치 구조를 제어하고 셔플을 회피한다.
  • 데이터 치우침(skew) 같은 문제를 피하고자 클러스터 전체에 걸쳐 데이터를 균등하게 분배하는 목표를 갖는다.
  • 사용자 정의 파티셔너를 사용하려면 구조적 API로 RDD를 얻고 사용자 정의 파티셔너를 적용한 다음 다시 DataFrame이나 Dataset으로 변환해야 한다.
  • 사용자 정의 파티셔닝을 사용하려면 Partitioner를 확장한 클래스를 구현해야 한다.
  • HashPartitioner, RangePartitioner
  • 사용자 정의 키 분배 로직: RDD 수준에서만 사용할 수 있으며, 임의의 로직을 사용해 물리적인 방식으로 클러스터에 데이터를 분배하는 강력한 방법이다.

 

🔗 사용자 정의 직렬화

  • Kryo 직렬화
  • 자바 직렬화보다 약 10배 이상 성능이 좋으며 간결하다.
  • 최상의 성능을 얻기 위해 프로그램에서 사용할 클래스를 사전에 등록해야 한다.
  • 모든 직렬화 유형을 지원하진 않는다.

 


[출처] 스파크 완벽 가이드 (빌 체임버스, 마테이 자하리아 지음)

profile
DCDI

0개의 댓글