[Apache Spark] Partition Pruning과 Predicate Pushdown
Spark에서 file scan을 효율적으로 할 수 있게 해주는 주요한 기능들인 Partition Pruning과 Predicate Pushdown에 대해서 간단히 정리해보자.
Partition Pruning
Partition Pruning은 스파크가 HDFS나 S3에서 디렉토리와 파일을 읽을 때 지정된 파티션의 파일만 읽을 수 있도록 성능 최적화를 가능케 해준다. RDBMS의 Parition Pruning과 개념적으로 동일하다.
물론 활용을 위해서는 파일을 쌓을 때 파티션 구조로 쌓는 것이 선행되어야 한다.
Predicate Pushdown
대부분의 쿼리 엔진은 필터링을 최대한 소스에 가깝게 적용하고자 한다. 소스에 가깝게 필터를 적용한다는 것의 의미는, 파일시스템에서 데이터를 읽어온 이후에 메모리에서 필터링 하는 것이 아니라, 파일을 읽을 때부터 꼭 필요한 데이터만 효율적으로 읽겠다는 것이다.
Parquet와 ORC 포맷의 파일은 각 컬럼별로 다양한 stats 데이터를 보관하고 있다.(min, max 등) 이러한 stats 정보가 불필요한 데이터를 건너뛰고 필요한 데이터만 읽을 수 있도록 Filter Push Down을 가능하게 해준다.
DPP(Dynamic Partition Pruning)
Spark 3.0의 주요 feature중 하나인 Dynamic Partition Pruning은 JOIN 단계에서 파티션된 테이블의 필요한 파티션만 활용할 수 있도록 최적화 하는 것이다.
Star schema구조에서 Broadcast Hash Join이 가능한 사이즈의 작은 dimension테이블과 fact 테이블의 JOIN 연산일 때 가장 효과적으로 적용될 수 있다.
Spark Configuration
기본적으로 Partition Pruning과 Predicate Pushdown에 관련된 설정 값들은 default가 활성화이다. 따라서 별도로 비활성화 해야하는 이유가 없다면 설정된 상태를 유지하면 된다.
관련된 spark configuration들은 아래와 같다.
spark.sql.hive.manageFilesourcePartitions
파일 소스 테이블에 대한 파티션 메타 데이터를 Hive metastore에 저장하고 이 metastore의 파티션 정보를 partition pruning에 활용한다.spark.sql.hive.metastorePartitionPruning
Hive metastore의 파티션 정보를 활용해 unmatching partiton을 일찍 제거하고 파일을 read할 수 있다.spark.sql.parquet.filterPushdown
Parquet file type 필터 푸시다운 활성화spark.sql.orc.filterPushdown
ORC file type필터 푸시다운 활성화spark.sql.optimizer.dynamicPartitionPruning.enabled
다이나믹 파티션 프루닝 활성화
Query Plan
Spark UI의 Query Plan을 한번 참고해보자.
아래와 같이 간단한 쿼리를 수행시켰다.
해당 테이블의 partition column은 dt
이고, dt = ‘2020–08–08’이고, category 가 web인 데이터만 읽고자 한다.
spark.sql(“select * from log.clicksteam where dt = ‘2020–08–08’ and category = ‘WEB’ limit 100”).show()
해당 쿼리로부터 실제 수행된 Query Plan 중 Physical Plan의 일부를 보면,
하단의 빨간 네모 상자에 각각 파티션의 Location 정보, Partition Filter 정보, Pushed 된 Filter 정보가 보인다.
- 파티션의 Location 정보/Partition Filter는 Hive Metastore에서 가져온 파티션 정보를 통해서 어디에 어떤 Partition 데이터가 들어있는지 일일이 모든 디렉토리나 파일을 읽는 수고 없이 바로 지정된 파티션만 읽을 수 있었다.
- Pushed Filter는 Parquet file의 footer 정보를 통해 필요한 데이터를 Filtering해서 read 하였다.
References
https://dzone.com/articles/dynamic-partition-pruning-in-spark-30