您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關數據湖的最佳調優是怎樣的,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
1.選擇最佳恰當的分區列
對于delta 表建議指定分區列。企業中最常見的分區列就是date,地域這些。遵循以下兩個經驗法則來決定要按哪個列進行分區:
a.如果列的基數很高,請不要使用該列進行分區。例如,如果按userId列進行分區,分區數可能就是用戶總數,這明顯不是一個好的分區策略。
b.每個分區中的數據量:如果希望該分區中的數據至少為1 GB,則可以按滿足這個需求的列進行分區。
2.合并文件
如果是不斷將數據寫入Delta表,隨著時間的推移,會產生大量文件,尤其是如果小數據量的添加數據時。這個可能會大大降低表的查詢速率,也可能影響文件系統的性能。理想情況下,應定期將大量的小文件重寫為少量的較大的文件。
可以通過將表重新分區為較少數量的文件來實現壓縮表功能。另外,可以將dataChange配置指定為false表示該操作不會變更數據,僅重新排列數據布局。這將確保由于此壓縮操作對其他并行操作的影響最小。
例如,可以將一個表壓縮為16個文件:
val path = "..."
val numFiles = 16
spark.read
.format("delta")
.load(path)
.repartition(numFiles)
.write
.option("dataChange", "false")
.format("delta")
.mode("overwrite")
.save(path)
如果對表進行了分區,并且您只想基于謂詞對一個分區進行重新分區,則可以使用where僅讀取分區,并使用replaceWhere寫回該分區:
val path = "..."val partition = "year = '2019'"val numFilesPerPartition = 16spark.read .format("delta") .load(path) .where(partition) .repartition(numFilesPerPartition) .write .option("dataChange", "false") .format("delta") .mode("overwrite") .option("replaceWhere", partition) .save(path)
警告:
在更改數據的操作上配置dataChange = false可能會損壞表中的數據。
3.merge操作的性能調優
下面幾個方法可以有效減少merge的處理時間:
a.減少匹配查找的數據量
默認情況下,merge操作會掃描整個delta lake表找到滿足條件的數據。可以加些謂詞,以減少數據量。比如,數據是以country和date進行分區的,而你只想更新特定國家的昨天的數據。就可以增加一些條件,比如:
events.date = current_date() AND events.country = 'USA'
這樣就只會處理指定分區的數據,大大減少了數據掃描量。也可以避免不同分區之間操作的一些沖突。
b.合并文件
如果數據存儲的時候有很多小文件,就會降低數據的讀取速度。可以合并小文件成一些大文件,來提升讀取的速度。后面會說到這個問題。
c.控制shuffle的分區數
為了計算和更新數據,merge操作會對數據進行多次shuffle。shuffle過程中task數量是由參數spark.sql.shuffle.partitions來設置,默認是200。該參數不僅能控制shuffle的并行度,也能決定輸出的文件數。增加這個值雖然可以增加并行度,但也相應的增加了產生小文件數。
d.寫出數據之間進行重分區
對與分區表,merge操作會產生很多小文件,會比shuffle分區數多很多。原因是每個shuffle任務會為多分區表產生更多的文件,這可能會是一個性能瓶頸。所以,很多場景中使用表的分區列對數據進行寫入前重分區是很有效的。可以通過設置spark.delta.merge.repartitionBeforeWrite為true來生效。
上述就是小編為大家分享的數據湖的最佳調優是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。