[Spark] 2.4.0 - bucket pruning
spark의 기능을 대략적으로만 파악하고 넘어가면 공부가 덜 되는 것 같아 각 버전별로 추가된 내용을 분석해 보기로 하였다.
현재(2020-03-10) 기준 가장 최신 버전은 2.4.5인데 2.4.x 버전에서 추가된 기능부터 정리해 보고자 한다.
이번 글에서 정리한 내용은 bucket pruning 이다.
Bucket
제목에서 나오는 bucket의 개념부터 살펴보자.
아래 정의는 Hive 문서에서 발췌했다.
Buckets (or Clusters): Data in each partition may in turn be divided into Buckets based on the value of a hash function of some column of the Table. For example the page_views table may be bucketed by userid, which is one of the columns, other than the partitions columns, of the page_view table. These can be used to efficiently sample the data.
Bucket은 파티션의 데이터 중에 특정 컬럼 값을 해시값으로 변환하여 나누어 준다.
아래 그림과 같이 Bucket 별로 별로의 파일로 저장되게 된다.
높은 cardinality (유일한 값의 수)를 가지는 컬럼의 경우 파티션으로 나누는 것이 비효율적인데, 이때 Bucket를 사용하면 이점이 많다.
Bucktet을 파티션 안의 파티션으로 볼 수 있는데 차이점은 Bucket의 숫자가 고정된다는 점이다.
아래 코드를 보면서 spark으로 Bucket을 가진 Table을 생성하고 2.4.0에서의 개선점이 뭔지 살펴보자.
.bucketBy(2, "user_id")로 유추할 수 있듯 user_id 컬럼에 2개의 Bucket를 가지도록 설정했다.
그리고 Bucket으로 지정된 컬럼을 where 조건으로 걸어서 조회했다.
2.4.0에서의 개선점은 Bucket을 가진 테이블을 조회할 때, Bucket이 조건으로 포함된 쿼리의 최적화하는 데 있다.
2.4.0 이후에는 Bucket으로 조회 조건을 걸면 실행 계획에서 필러링 된 파일들만 읽어온다.
spark 2.4.0 이전/ 이후 버전에서 쿼리에 의한 실행계획을 출력해 보면 차이점이 명확하게 보인다.
2.3.4와 2.4.5 버전을 비교했다.
2.4.5 버전의 실행계획에서 SelectedBucketsCount: 1 out of 2가 추가되었다.
의미는 2개의 Bucket 중에서 하나의 Bucket만 선택해서 가져왔다는 것이다.
where user_id = 'user1'로 조회를 했기에 동일 해시값으로 동일 Bucket에 저장된 user1를 구분할 수 있어서 하나의 Bucket만 불러와도 되는 것이다.
Bucket으로 조건을 걸었을 때, 가져오지 않아도 되는 파일들을 필터링할 수 있어 성능상 이점이 생긴다.
참고 문서
-
[SPARK-23803] Support Bucket Pruning