apache-spark - jdk - spark run local




새로운 데이터가없는 파티션을 삭제하지 않고 Spark에서 DataFrame을 파티션 나누고 쓰는 방법? (2)

DataFrame 을 세 가지 열 값으로 분할 된 DataFrameWriter 사용하여 Parquet 형식의 HDFS에 저장하려고합니다.

dataFrame.write.mode(SaveMode.Overwrite).partitionBy("eventdate", "hour", "processtime").parquet(path)

이 질문 에서 언급했듯이, partitionBypath 에서 파티션의 기존 계층 구조 전체를 삭제하고 dataFrame 의 파티션으로 대체합니다. 특정 날짜에 대한 새로운 증분 데이터가 주기적으로 올 것이므로 원하는 것은 데이터 dataFrame 에 데이터가있는 계층 구조의 파티션 만 바꾸고 나머지는 그대로 둡니다.

이렇게하려면 다음과 같이 전체 경로를 사용하여 각 파티션을 개별적으로 저장해야합니다.

singlePartition.write.mode(SaveMode.Overwrite).parquet(path + "/eventdate=2017-01-01/hour=0/processtime=1234567890")

그러나 전체 경로를 사용하여 데이터를 쓸 수 있도록 단일 파티션 DataFrame 으로 데이터를 구성하는 가장 좋은 방법을 이해하는 데 어려움을 겪고 있습니다. 하나의 아이디어는 다음과 같습니다.

dataFrame.repartition("eventdate", "hour", "processtime").foreachPartition ...

그러나 foreachPartition 은 Parquet 형식으로 쓰는 데 이상적이지 않은 Iterator[Row] 에서 작동합니다.

또한 select...distinct eventdate, hour, processtime 을 사용하여 파티션 목록을 얻은 다음 원본 데이터 프레임을 각 파티션별로 필터링하고 전체 파티션 경로에 결과를 저장하는 방법을 고려했습니다. 그러나 개별적인 쿼리와 각 파티션에 대한 필터는 많은 필터 / 쓰기 작업이 될 것이므로 매우 효율적으로 보이지 않습니다.

dataFrame 에 데이터가없는 기존 파티션을 보존하는 더 깨끗한 방법이 dataFramedataFrame .

읽어 주셔서 감사합니다.

스파크 버전 : 2.1


나는 이것이 아주 오래되었다는 것을 안다. 게시 된 솔루션을 볼 수 없으므로 앞으로 가서 게시 할 것입니다. 이 접근법은 쓰기를 원하는 디렉토리 위에 하이브 테이블이 있다고 가정합니다. 이 문제를 해결하는 한 가지 방법은 테이블에 추가해야하는 dataFrame 에서 임시 뷰를 dataFrame 다음 일반 하이브와 같은 insert overwrite table ... 명령을 사용하는 것입니다.

dataFrame.createOrReplaceTempView("temp_view")
spark.sql("insert overwrite table table_name partition ('eventdate', 'hour', 'processtime')select * from temp_view")

새로운 파티션에만 쓰는 동안 오래된 파티션을 보존합니다.


모드 옵션 Append 에 catch가 있습니다!

df.write.partitionBy("y","m","d")
.mode(SaveMode.Append)
.parquet("/data/hive/warehouse/mydbname.db/" + tableName)

나는 테스트하여 기존 파티션 파일을 유지한다는 것을 알았습니다. 그러나 이번에는 다음과 같은 문제가 있습니다. 같은 코드를 두 번 (동일한 데이터로) 실행하면 동일한 데이터 (기존 1.6)에 대해 기존의 파일을 바꾸는 대신 새 마루 파일을 만듭니다. 따라서 Append 를 사용하는 대신 Overwrite 하여이 문제를 해결할 수 있습니다. 테이블 레벨에서 겹쳐 쓰는 대신 파티션 레벨에서 겹쳐 써야합니다.

df.write.mode(SaveMode.Overwrite)
.parquet("/data/hive/warehouse/mydbname.db/" + tableName + "/y=" + year + "/m=" + month + "/d=" + day)

자세한 내용은 다음 링크를 참조하십시오.

스파크 데이터 프레임 쓰기 메소드에서 특정 파티션을 덮어 씁니다.

(나는 suriyanto의 코멘트 후에 나의 대답을 갱신했다. Thnx.)







parquet