[spark] Spark - RDD vs Dataframes vs Datasets 

RDD와 Dataframes, Datasets를 비교하는 글이 있어서 보려고 한다.

중간중간 의역 및 생략이 있을 수 있다. 때문에 보다 자세한 글은 아래 원문을 참조

https://databricks.com/blog/2016/07/14/a-tale-of-three-apache-spark-apis-rdds-dataframes-and-datasets.html

 

우리는 언제, 왜 RDD, Dataframes, Datasets를 사용해야 할까? 

Resilient Distributed Dataset (RDD)

RDD는 Spark 등장 이래로 주로 사용된 API 이다. Spark Core에서는 RDD는 변경할 수 없는(Immutable) 데이터의 집합으로 클러스터 내의 여러 노드에 분산되어 있다.

(Transformation, Action과 같은 low-level API를 지원한다.)

 

그럼 언제 RDD를 사용해야 할까? 일반적으로 사용되는 경우를 살펴보자.

- low-level API인 Transformation, Action을 사용할 때

- 데이터가 미디어와 같이 비구조화 형태로 되어 있을 때

- 데이터를 함수형 프로그래밍으로 조작하고 싶을 때

- 데이터를 처리할 때, 칼럼 형식과 같은 스키마를 굳이 따지고 싶지 않을 때

- 최적화를 굳이 신경쓰지 않을 때

 

그럼 RDD는 Spark 2.0에서는 어떻게 되었을까? deprecated 되었을까?

이후에도 알아 보겠지만 Dataframe, Dataset 와 함께 존재한다. (해당 타입이 RDD의 상위 개념에 속하기 때문)

 

Dataframes

RDD와 같이 Dataframe도 변경 할 수 없는 데이터 집합이다. 다만, 데이터가 RDB의 관계형 테이블처럼 칼럼이 존재한다. 따라서 대용량 데이터를 좀 더 쉽게 처리 할 수 있다.

또한 구조화 되어 있기 때문에 여러 데이터 엔지니어들이 쉽게 Spark에 접근 할 수 있다. (RDB와 같은 형태를 많은 사람들에게 익숙하기 때문에)

그러나 Spark 2.0에서 Dataframe API는 Datasets API와 통합되었다.

 

 

Datasets

Spark 2.0이 대두되면서, Dataset은 2가지 특징(strongly-typed API, uptyped API)을 가지게 되었다. 개념적으로 Dataframe은 제네릭(generic) 객체인 Dataset[Row]의 집합이며 Alias이다. (DataFrame = Dataset[Row])

Dataset API의 장점에 대해 알아보자.

Spark 2.0 이후로 Dataframe과 Dataset이 통합되면서 여러 가지 장점을 갖는다.

 

1. Static-typing & runtime type-safety

예를 들어 Spark SQL을 사용하면 실행 할 때까지 문법 에러를 알 수 없다. 반면에 Dataframe과 Dataset은 컴파일 시점에 에러를 잡을 수 있다. (물론 실행 할 때까지 존재하지도 않는 칼럼은 찾을 수 없다.) 또한 Dataset API는 람다 함수 및 JVM 타입 객체로 표현되기 때문에, 컴파일 시점에 타입을 검사할 수 있다. 

 

 

2. High-level abstraction and custom view into structured and semi-structured data

예를 들어 JSON으로 표현된 거대한 IoT 디바이스 데이터가 있다고 가정해보자. JSON은 반구조화 형태이지만 Dataset[DeviceIoTData]와 같은 strongly typed의 집합으로 구성된다. 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

{
  "device_id": 198164, "device_name": "sensor-pad-198164owomcJZ",
  "ip": "80.55.20.25", "cca2": "PL", "cca3": "POL",
  "cn": "Poland", "latitude": 53.080000, "longitude": 18.620000,
  "scale": "Celsius", "temp": 21, "humidity": 65,
  "battery_level": 8, "c02_level": 1408, "lcd": "red", "timestamp": 1458081226051
}
case class DeviceIoTData (battery_level: Long, c02_level: Long, cca2: String, cca3: String, cn: String, 
                          device_id: Long, device_name: String, humidity: Long, ip: String, latitude: Double, lcd: String, 
                          longitude: Double, scale:String, temp: Long, timestamp: Long)
// read the json file and create the dataset from the 
// case class DeviceIoTData
// ds is now a collection of JVM Scala objects DeviceIoTData
val ds = spark.read.json(“/databricks-public-datasets/data/iot/iot_devices.json”).as[DeviceIoTData]

위의 코드를 보면,

1) JSON 데이터

2) 추출하기 위한 클래스

3) JSON 데이터를 읽어서 클래스 형태로 구성

이 중, 3)에서 데이터를 Dataset으로 구성하면서 타입을 DevcieIoTData 으로 명시한다. 

 

대부분의 사람들은 구조화된 데이터를 처리하는데 익숙하다. 이렇듯 타입이 명시된 데이터 집합인 Dataset으로 컴파일 시점에 데이터 뷰를 볼 수 있다. 게다가 Dataset[T] 형태는High-level 메소드로 쉽게 작업 할 수 있다.

 

 

3. Ease-of-use of APIs with structure

구조적 형태는 Spark에서 데이터를 다루는데 한계가 있을 수 도 있다. 그러나 Dataset은 쉽게 이해 할 수 있고, 데이터를 다양하게 표현 할 수 있다.

예시로 agg, select, sum, avg, map, filter, groupby를 사용하여 데이터를 다루는 것은 RDD의 각 row 필드를 사용하는 것보다 쉽다. 

// Use filter(), map(), groupBy() country, and compute avg() 
// for temperatures and humidity. This operation results in 
// another immutable Dataset. The query is simpler to read, 
// and expressive

val dsAvgTmp = ds.filter(d => {d.temp > 25}).map(d => (d.temp, d.humidity, d.cca3)).groupBy($"_3").avg()

//display the resulting dataset
display(dsAvgTmp)

 

4. Performance & Optimization

Dataframe와 Dataset은 Spark SQL 엔진 위에 탑재되어 있다. (Spark Stack 참조)

즉, 최적화된 논리적 및 물리적 쿼리 계획을 생성 할 수 있는 Catalyst를 사용 할 수 있다. 그러므로 R, Java, Scala, Python과 같은 언어도 같은 장점을 취할 수 있다.

 

다음으로 컴파일러가 데이터 타입 JVM 객체를 알고 있으므로, Encoders를 사용하여 명시화된 JVM 객체를 Tungsten 내부 메모리에 매핑한다. 때문에 효율적으로 JVM 객체를 직별화/반직렬화 시킬 수 있고 바이크도 또한 생성 할 수 있다.

 

그렇다면 언제 Dataframe, Dataset를 사용해야 할까?

- 도메인 API, 추상화 등등이 필요할 때

- filters, maps, aggergagion, 반구조화 데이터에서 람다 함수 등등이 필요할 때

- Catalyst 최적화 및 Tungsten 코드를 사용하고 싶을 때

- API를 단순화하여 사용하고 싶을때

- R, Python 사용자

 

(추가로 Dataframe, Dataset에서 RDD로 간단히 변환이 가능하다.)

 

Bringing It All Together

요약하자면 RDD, Dataframe 및 Dataset의 선택은 명확하다. (RDD는 저수준 기능 및 제어, Dataframe과 Dataset는 고수준 및 도메인 작접 그리고 최적화)



출처: https://timewizhan.tistory.com/entry/Spark-RDD-vs-Dataframes-vs-Datasets [Small talks with something]

 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
공지 오라클 기본 샘플 데이터베이스 졸리운_곰 2014.01.02 86301
공지 [SQL컨셉] 서적 "SQL컨셉"의 샘플 데이타 베이스 SAMPLE DATABASE of ORACLE 가을의 곰을... 2013.02.10 78753
공지 [G_SQL] Sample Database 가을의 곰을... 2012.05.20 95499
15 [표준SQL] 퀴즈로 배우는 SQL : 전기 요금 계산 file 졸리운_곰 2024.08.10 1576
14 [표준SQL] 퀴즈로 배우는 SQL : 파이프 연결하기 file 졸리운_곰 2024.08.10 1320
13 [표준SQL] 퀴즈로 배우는 SQL : 공통점이 가장 많은 친구 찾기 file 졸리운_곰 2024.08.10 2117
12 [표준 SQL] 퀴즈로 배우는 SQL : 일별 누적 접속자 통계 구하기 file 졸리운_곰 2024.08.10 1684
11 [표준 SQL] 퀴즈로 배우는 SQL : 구분자로 나누어 행,열 바꾸기 file 졸리운_곰 2024.08.10 1884
10 [표준 SQL] 퀴즈로 배우는 SQL : 신입사원 부서 배치에 따른 급여 랭킹 시뮬레이션 file 졸리운_곰 2024.08.10 1340
9 [표준 SQL] 퀴즈로 배우는 SQL : 시작일, 종료일 사이의 휴일을 제외한 일수 구하기 file 졸리운_곰 2024.08.10 1479
8 [표준 SQL] 권순용의 DB 이야기 : 함수 기반 인덱스의 개념과 생성 이해 file 졸리운_곰 2024.08.10 1373
7 [표준 SQL] 퀴즈로 배우는 SQL : 계층 쿼리를 이용해 조직도 만들기 file 졸리운_곰 2024.08.10 2068
6 [표준 SQL] SQL을 잘한다는 기준은 무엇일까 file 졸리운_곰 2024.08.10 1340
5 [SQL] CRUD 기본 사용법 file 졸리운_곰 2023.01.23 1393
4 [기본 SQL] SELECT, INSERT, UPDATE, DELETE file 졸리운_곰 2022.04.26 1209
3 Mysql Join 해부(Left, Right, Outer, Inner Join) file 졸리운_곰 2019.01.30 1578
2 Join의 모든것.(LEFT OUTER, RIGHT OUTER, INNER, FULL OUTER, CROSS) 졸리운_곰 2019.01.30 1518
1 SELECT 문법 file 졸리운_곰 2017.11.22 2314
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED