2016-07-22 26 views
1

我正在使用spark 1.6.1,並試圖將數據幀保存爲orc格式。Spark數據幀saveAsTable vs保存

我面臨的問題是保存方法非常慢,每個執行程序需要大約6分鐘50M的獸人文件。 這是我現在的儲蓄數據幀

dt.write.format("orc").mode("append").partitionBy("dt").save(path) 

我試着用saveAsTable到還使用獸人格式的蜂巢表,這似乎是快了大約20%至50%的速度,但這種方法有其自己的問題 - 似乎任務失敗時,由於文件已存在,重試將始終失敗。 這是我現在的儲蓄數據幀

dt.write.format("orc").mode("append").partitionBy("dt").saveAsTable(tableName) 

是否有一個原因Save方法是如此之慢? 我做錯了什麼?

+0

6分鐘寫入50M文件並不那麼慢。聽起來像很多文件!每個人有多大?有多少執行者?如果它是每行一個文件,那就太多了。如果它們適用於您的存儲系統,以及在典型查詢中使用的節點/執行程序的數量,那麼可能有50M是好的,但我對此表示懷疑。如果每個50M文件都是1G,那麼〜47PB,所以我懷疑這一點。如果每個都是1MB,那麼它就是47TB,我建議文件大小太小而無法有效地查詢表格。總數據量是多少? – Davos

+0

它實際上是50兆文件。 – user1960555

+1

像,它只是一個50MB文件?如果它只是一個小文件,那麼沒有太多的點分區。有可能您的dt字段太多,最終會爲每行創建分區。例如。如果是像「2017-01-01 14:52:22」那樣的時間戳/日期時間,那麼每隔一秒鐘就會發生分區,然後爲每個分區寫入一個orc文件。 50MB可能是一個小文件,但它可能是很多具有不同時間戳的行。例如如果每一行是〜8K,那麼~6400行,這是很多文件I/O。 – Davos

回答

1

問題是由於partitionBy方法。 PartitionBy讀取指定列的值,然後爲分區列的每個值分隔數據。 儘量保存它沒有分區,會有顯着的性能差異。

+0

我需要對數據進行分區,所以這不是一個選項。 – user1960555

+0

我認爲這是一個有效的觀點。什麼是dt?這是一個合適的分區列嗎?如果基數非常高,則可能不合適。例如,如果您對數據框的每一行使用的值不同,那麼這會導致分區太多。所有文件I/O的開銷都不值得。 – Davos

1

查看我之前關於基數和分區的評論。

如果你真的想對它進行分區,它只是一個50MB的文件,然後使用類似

dt.write.format("orc").mode("append").repartition(4).saveAsTable(tableName)

再分配將創建4個大致相抵分區,而不是你在做在一個分區是什麼dt列,最終可能會寫很多orc文件。

4個分區的選擇有點任意。你不會從分割這樣的小文件中獲得很多性能/並行化的好處。閱讀更多文件的開銷不值得。