이 포스팅에서는 Parquet 파일을 읽는 동안 Dataframe의 메타데이터가 수정 되었을 경우 "REFRESH TABLE tableName"에러가 뜨는 문제를 어떻게 해결할 수 있는지 알아보겠습니다.
기존의 모든 배치에서는 동일 파티션에 대해 .mode("overwrite")를 사용하기 때문에, 프로세스가 실행되는 동안 수정/삭제된 파일을 읽으려고 시도하게 되면 메타데이터가 변경되었다는 "REFRESH TABLE tableName" 에러가 발생합니다. 이로 인해 해당 파티션이 저장 중 상태인 temporary 에서는 테이블을 사용할 수 없게 됩니다.
따라서 아래와 같이 메타데이터를 메모리 위에 올려주거나 다른 dump와 같은 경로에 저장을 하는 방법 등으로 해결할 수 있습니다.
저는 그 중 DataFrame.createOrReplaceTempView() 메서드를 통해 DataFrame 을 View 로 등록해 SQL 내에서 테이블처럼 사용하여 CACHE TABLE 구문을 이용해 캐싱하는 방식으로 문제를 해결하였습니다.
df.createOrReplaceTempView("table")
df_cache = spark.sql("""
CACHE TABLE testCache AS(
SELECT *
FROM testData
WHERE ~
)
""")
CreateOrReplaceTempView 란?
- 새로 테이블을 생성하는 것이 아닌, 임시뷰를 만드는 것인데 Spark는 Lazy evaluation이기 때문에 호출할때마다 연산이 이루어집니다. 따라서 메모리에 올리고 싶다면 캐싱을 해야합니다.
- 일시적인 뷰는 Spark 세션이 유지되는 동안에만 존재하므로, 새로운 Spark 세션을 시작하면 뷰가 사라집니다.
- 세션을 종료시키지 않을거라면 , dropTempView로 뷰를 드랍해주고 캐싱까지 했다면 unpersist를 통해 할당 된 메모리를 해제 시켜줘야 합니다.
Global Temporary View 란?
temp view를 GlobalTempViewGlobal 로 만들면 뷰를 등록한 Spark 세션이 종료되더라도, 다른 Spark 세션에서 접근하여 사용할 수 있습니다. 이는 여러 사용자가 하나의 뷰를 공유하거나, 다른 세션에서 임시 결과를 재사용해야하는 경우 유용합니다.
# Global Temporary View 생성
df.createGlobalTempView("temp_df")
# 다른 Spark 세션에서 접근 가능한 Global Temporary View
global_temp_df = spark.table("global_temp.temp_df")
하지만 메타스토어 부하 및 워커 노드의 메모리 부족 문제가 발생할 수 있기 때문에 Global Temporary View 사용은 지양하는 것이 좋습니다.
'개발 > Spark' 카테고리의 다른 글
[Spark] Spark deploy mode 설정(Cluster/Client) (0) | 2023.03.26 |
---|---|
[Spark DEBUG] partiton path load 오류 (0) | 2023.02.26 |
[Spark DEBUG] Refresh for Dataframe while reading file 오류 (0) | 2022.11.16 |
[spark] Build step 'Execute shell' marked build as failure 권한 오류 (Permission denied) (0) | 2022.10.05 |
Spark 이해하기(RDD, DAG, Lazy Evaluation) (0) | 2022.02.07 |