實踐場景:解決Spark流處理產生的小檔案
來源:大資料左右手
背景
做流批一體,湖倉一體的大資料架構,常見的做法就是:
資料來源->spark Streaming->ODS(資料湖)->spark streaming->DWD(資料湖)->...
那麼資料來源->spark Streaming->ODS,以這段為例,在資料來源透過spark structured streaming寫入ODS在資料湖(Delta Lake)落盤時候必然會產生很多小檔案。
目的
為了在批處理spark-sql執行更快,也避免因為小檔案而導致報錯。
影響
WARNING: Failed to connect to /172.16.xx.xx:9866 for block, add to deadNodes and continue. java.net.SocketException:
Too many open files
小檔案在批處理資料IO消耗巨大,程式可能卡死。
小檔案塊都有對應的後設資料,後設資料放在NameNode,導致需要的記憶體大大增大,增加NameNode壓力,這樣會限制了叢集的擴充套件。
在HDFS或者物件儲存中,小檔案的讀寫處理速度要遠遠小於大檔案,(定址耗時)。
解決思路
事前
(1)避免寫入時候產生過多小檔案 做好分割槽partitionBy(年,月,日), 避免小檔案過於分散 Trigger觸發時間可以設定為1分鐘,這樣會攢一批一寫入,避免秒級別寫入而產生大量小檔案(但是使用spark structured 想要做real-time不能這樣,只適合做準實時)
(2)開啟自適應框架的開關
spark.sql.adaptive.enabled true
(3)透過spark的coalesce()方法和repartition()方法
val rdd2 = rdd1.coalesce(8, true) //(true表示是否shuffle)
val rdd3 = rdd1.repartition(8)
coalesce:coalesce()方法的作用是返回指定一個新的指定分割槽的Rdd,如果是生成一個窄依賴的結果,那麼可以不發生shuffle,分割槽的數量發生激烈的變化,計算節點不足,不設定true可能會出錯。
repartition:coalesce()方法shuffle為true的情況。
事後(小檔案引起已經產生)
(1)最佳化 Delta 表的寫入,避免小檔案產生 在開源版 Spark 中,每個 executor 向 partition 中寫入資料時,都會建立一個表檔案進行寫入,最終會導致一個 partition 中產生很多的小檔案。
Databricks 對 Delta 表的寫入過程進行了最佳化,對每個 partition,使用一個專門的 executor 合併其他 executor 對該 partition 的寫入,從而避免了小檔案的產生。
該特性由表屬性 delta.autoOptimize.optimizeWrite 來控制:可以在建立表時指定
CREATE TABLE student (id INT, name STRING)
TBLPROPERTIES (delta.autoOptimize.optimizeWrite = true);
也可以修改表屬性
ALTER TABLE table_name
SET TBLPROPERTIES (delta.autoOptimize.optimizeWrite = true);
該特性有兩個優點:
(1)透過減少被寫入的表檔案數量,提高寫資料的吞吐量;
(2)避免小檔案的產生,提升查詢效能。
缺點:
其缺點也是顯而易見的,由於使用了一個 executor 來合併表檔案的寫入,從而降低了表檔案寫入的並行度,此外,多引入的一層 executor 需要對寫入的資料進行 shuffle,帶來額外的開銷。因此,在使用該特性時,需要對場景進行評估。
場景:
該特性適用的場景:頻繁使用 MERGE,UPDATE,DELETE,INSERT INTO,CREATE TABLE AS SELECT 等 SQL 語句的場景;
該特性不適用的場景:寫入 TB 級以上資料。
(2)自動合併小檔案
在流處理場景中,比如流式資料入湖場景下,需要持續的將到達的資料插入到 Delta 表中,每次插入都會建立一個新的表檔案用於儲存新到達的資料,假設每10s觸發一次,那麼這樣的流處理作業一天產生的表檔案數量將達到8640個,且由於流處理作業通常是 long-running 的,執行該流處理作業100天將產生上百萬個表檔案。這樣的 Delta 表,僅後設資料的維護就是一個很大的挑戰,查詢效能更是急劇惡化。
為了解決上述問題,Databricks 提供了小檔案自動合併功能,在每次向 Delta 表中寫入資料之後,會檢查 Delta 表中的表檔案數量,如果 Delta 表中的小檔案(size < 128MB 的視為小檔案)數量達到閾值,則會執行一次小檔案合併,將 Delta 表中的小檔案合併為一個新的大檔案。
該特性由表屬性 delta.autoOptimize.autoCompact 控制,和特性 delta.autoOptimize.optimizeWrite 相同,可以在建立表時指定,也可以對已建立的表進行修改。自動合併的閾值由 spark.databricks.delta.autoCompact.minNumFiles 控制,預設為50,即小檔案數量達到50會執行表檔案合併;
合併後產生的檔案最大為128MB,如果需要調整合並後的目標檔案大小,可以透過調整配置 spark.databricks.delta.autoCompact.maxFileSize 實現。
(3)手動合併小檔案(我常用,每天定時執行合併分割槽內小檔案,再去處理批任務)
自動小檔案合併會在對 Delta 表進行寫入,且寫入後表中小檔案達到閾值時被觸發。除了自動合併之外,Databricks 還提供了 Optimize 命令使使用者可以手動合併小檔案,最佳化表結構,使得表檔案的結構更加緊湊。
在實現上 Optimize 使用 bin-packing 演算法,該演算法不但會合並表中的小檔案,且合併後生成的表檔案也更均衡(表檔案大小相近)。例如,我們要對 Delta 表 student 的表檔案進行最佳化,僅需執行如下命令即可實現:(Optimize 命令不但支援全表小檔案的合併,還支援特定的分割槽的表檔案的合併)。
OPTIMIZE student WHERE date >= '2024-01-01'
附加
面試官可能會問,我執行optimize合併小檔案,但是小檔案太多了,直接卡死執行不了程式(某網際網路面試題)
(1)首先停掉程式,這裡注意deltalake因為有歷史版本這個概念,所以不存在執行一半覆蓋原來版本情況,可以基於上一個版本重新執行(考點)。
(2)第二點,大資料思想分而治之,“分”,即把複雜的任務分解為若干個“簡單的任務”來處理。
OPTIMIZE student WHERE date > '2024-01-01' and date < '2024-01-02'
因為前面做了partitionby(年月日),那麼縮小optimize範圍,在遍歷這個月的每一天日期,分治處理。
(3)第三點,大資料思想,自己不行找兄弟,加節點,加計算資源。
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027827/viewspace-3007647/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Hadoop小檔案的處理方式Hadoop
- 複雜場景資料處理的 OLTP 與 OLAP 融合實踐
- 大資料開發-Flume-頻繁產生小檔案原因和處理大資料
- 使用資料流的思想處理檔案
- SparkSQL中產生笛卡爾積的幾種典型場景以及處理策略SparkSQL
- 面試官:哪些場景會產生OOM?怎麼解決?面試OOM
- 前後端處理流檔案請求後端
- 處理生產bug
- TDengine的實踐場景
- 場景實踐:使用函式計算打包下載OSS檔案函式
- linux Typora修改Windows檔案產生亂碼(未解決)LinuxWindows
- 【精益生產】如何處理決策延遲?
- 實時流處理與分散式儲存過程中對檔案的操作分散式儲存過程
- 檔案輸入輸出處理(二)-位元組流
- 社交場景下iOS訊息流互動層實踐iOS
- 揭秘政企安全加速解決方案的架構與應用場景實踐架構
- rsync+inotify實現實時同步(小業務場景解決方案)
- 【PWA學習與實踐】(9)生產環境中PWA實踐的問題與解決方案
- 分享一個生產者-消費者的真實場景
- Python如何處理檔案的?Python
- 【Oracle】死鎖的產生與處理Oracle
- python 檔案處理Python
- python處理檔案Python
- python檔案處理Python
- 使用無伺服器實現檔案處理的批處理 - DZone Cloud伺服器Cloud
- Flink 流處理在中信建投證券的實踐與應用
- 使用 IDA 處理 U-Boot 二進位制流檔案boot
- 遊戲場景渲染中的PostProcessing(後處理)遊戲
- Docker生產實踐(六)Docker
- ORACLE分散式事務鎖各種場景下的處理詳解Oracle分散式
- python處理txt檔案Python
- window 批處理檔案
- Python之檔案處理Python
- Go xml檔案處理GoXML
- 解鎖「SOAR」在不同場景下的應用與實踐
- Spring MVC檔案請求處理詳解:MultipartResolverSpringMVC
- Spark Streaming 流式處理Spark
- OceanBase 在證券行業基金資管場景落地實踐與解決方案行業