데이터엔지니어링/Spark

[3장] 아파치 스파크의 정형화 API [1]

데이터잼니 2023. 7. 20. 16:03

스파크 : RDD 아래에는 무엇이 있나?

RDD는 스파크에서 가장 기본적인 추상적인 부분이다

RDD의 특성은 다음과 같다.

 

의존성(dependency)

 

어떤 입력을 필요로 하고 현재의 RDD가 어떻게 만들어지는지 스파크에게 가르쳐 주는 의존성이 필요한데, 결과를 새로 만들어야 하는 경우 스파크는 이 의존성 정보를 참고하고 연산을 다시 반복해서 RDD를 다시 만들 수 있고, 이 특성이 RDD에 유연성을 부여해준다.

 

파티션(지역성 정보 포함)

 

파티션은 스파크에게 작업을 나눠서 이그제큐터들에 분산해 파티션별로 병렬 연산할 수 있는 능력을 부여한다.

 

연산 함수 : Partition => Iterator[T]

 

RDD는 RDD에 저장되는 데이터를 Iterator[T] 형태로 만들어 주는 연산 함수를 갖고 있다.

 

다만, 연산 함수나 연산식 자체가 스파크에 투명하지 않다. 사용자가 연산 함수에서 뭘 하는지 스파크가 알수없다는 뜻이다. 또, Iterator[T] 데이터 타입이 파이썬 RDD에서 불투명 했다는 점이다. 스파크에서는 단지 파이썬 기본 객체로만 인식한다. 스파크가 함수 연산이나 표현식을 검사하지 못하기 때문에 최적화도 불가능하고, T로 표현한 파입에 대한 정보가 스파크는 전혀 없다.


스파크 구조 확립

 

저수준 RDD API를 이용한다면 아래와 같이 코드가 구성 될 것이다.

 

고수준 DSL 연산자들과 데이터 프레임 API를 쓰면 아래와 같이 코드가 구성 될 것이다.

위 코드의 결과는 아래와 같다.

이런 DSL 연산자와 API는 스파크에게 무엇을 할지 알려주기때문에 표현력이 높으며, 스파크는 이런 쿼리를 파악해서 사용자의 의도를 이해할 수 있기 때문에 효과적인 실행을 위해 연산들을 최적화하거나 적절한 재배열이 가능하다.


데이터 프레임 API

 

스파크는 특정 연산에 있어서 판다스 데이터 프레임에 영향을 받은 스파크 데이터 프레임은 이름 있는 칼럼과 스키마를 가진 분산 인메모리 테이블처럼 동작하며, 각 칼럼은 특정한 데이터 타입을 가질 수 있다(정수, 문자열, 배열, 맵, 실수, 날짜, 타임스탬프 등)

 

스파크의 기본 데이터 타입

 

스파크의 기본 파이썬 데이터 타입

데이터 타입 파이썬에서 할당되는 값 초기 생성 API
ByteType int DataTypes.ByteType
ShortType int DataTypes.ShortType
IntegerType int DataTypes.IntegerType
LongType int DataTypes.LongType
FloatType float DataTypes.FloatType
DoubleType float DataTypes.DoubleType
StringType str DataTypes.StringType
BooleanType bool DataTypes.BooleanType
DecimalType decimal.Decimal DecimalType

 

스파크의 정형화 타입과 복합 타입

스파크의 파이썬 정형화 데이터 타입

데이터 타입 파이썬에서 할당되는 값 초기 생성 API
ByteType bytearray BinaryType()
TimestampType datetime.datetime TimestampType()
DateType datetime.date DateType()
ArrayType list, tuple, array 중 ArrayType(datatype, [nullable])
MapType dict MapType(keyType, valueType, [nullable])
StructType list or tuple StructType([fields])
StructType 해당 필드와 맞는 값의 타입 StructField(name, dataType, [nullable])

 

스키마와 데이터 프레임 만들기

 

읽을 때 스키마를 가져오는 방식과 달리 미리 스키마를 정의하는 것은 세가지 장점이 있다.

- 스파크가 데이터 타입을 추측해야 하는 책임을 덜어 준다

- 스파크가 스키마를 확정하기 위해 파일의 많은 부분을 읽어 들이려고 별도의 잡을 만들지 않으며, 데이터 파일이 클 때, 비용과 시간을 아낄 수 있다.

- 데이터가 스키마와 맞지 않는 경우, 조기 문제 발견 가능하다.

 

데이터 소스가 큰 파일이라면 스키마를 지정해 두는 것이 좋다.

 

스키마를 정의하는 두 방법

 

프로그래밍 스타일로 정의하는 방법과, DDL을 사용하는 방법이다.

 

아래는 프로그래밍 스타일로 정의한 것이다.

# 파이썬 예제

from pyspark.sql.types import *
schema = StructType([StructField("author" , StringType(), False), 
	StructField("title" , StringType(), False), 
	StructField("pages", StringType(), False)])​

DDL을 이용하여 정의한 것이다.

# 파이썬 예제
schema = "author STRING, title STRING, pages INT"

example 코드
example 결과
blogs_df.schema를 사용하면 나오는 결과
example 결과

expr() 이나 col()를 이용하여 새로운 컬럼을 만들수도 있다. 


ROW

 

스파크에서 하나의 행은 일반적으로 하나 이상의 칼럼을 갖고 있는 로우객체로 표현이 된다.

Row는 스파크의 객체이고 순서가 있는 필드 집합 객체이므로 스파크의 지원 언어들에서 각 필드를 0부터 시작하는 인덱스로 접근한다.

 

파이썬 예제

Row 객체들은 빠른 탐색을 위해 데이터 프레임으로 만들어 사용하기도 한다.

 

데이터 프레임화 시킨 것

파일들의 대부분은 규모가 커, 데이터 프레임 작성 하는 것이 효율적이다.