洞察資料約 4 分鐘閱讀

資料湖小檔案如何合併而不影響查詢與更新

小檔案會增加物件儲存請求、查詢規劃與中繼資料負擔,但直接覆寫檔案可能讓讀取與更新互相衝突。穩健的合併流程應把它視為可回滾的資料版本發布,而不是單純的檔案整理。

先確認問題是檔案大小,還是資料布局

資料湖產生小檔案,通常不是單一元件故障,而是寫入模式的結果。串流工作頻繁提交、微批次太短、分區欄位基數過高,以及多個來源同時寫入,都可能讓每次提交只產生少量資料。查詢引擎因此需要列舉更多物件、讀取更多檔案頁尾並建立更多掃描工作;即使實際讀取的資料量不大,規劃階段也可能變慢。

不要只以平均檔案大小決定是否合併。工程上更值得觀察的是檔案大小分布、每個分區的檔案數、查詢規劃時間、實際掃描量,以及更新工作是否集中在相同分區。若查詢只讀取少數欄位或高度選擇性的資料,過度合併反而可能擴大掃描範圍。目標檔案大小也不是固定常數:互動式查詢、批次分析、物件儲存延遲與執行器記憶體,都會影響合理區間。

以新快照發布,不要在原路徑就地替換

Parquet、ORC 等物件通常應視為不可變。安全做法是讀取一組已提交的小檔案,寫出新的合併檔,再透過資料表格式的中繼資料交易發布新快照。Apache Iceberg、Delta Lake 與 Apache Hudi 雖然提交機制不同,但共同原則是:既有查詢繼續使用啟動時取得的版本,新查詢只在提交完成後看到新檔案。合併失敗時,新檔案不應成為可見資料。

如果資料湖仍以裸 Parquet 路徑供查詢,風險會更高。不要先刪除舊檔再寫入新檔,也不要假設重新整理目錄清單等同交易。較穩健的方法是在新的版本目錄產生完整結果、驗證後再切換 catalog、view 或 manifest 指標,並保留上一版以便回滾。

  • 固定輸入集合:記錄合併起始時的快照或檔案清單,避免工作期間新增的檔案被重複納入。
  • 限制重寫範圍:以分區、事件日期或明確檔案群組為單位,避免一次改寫整張表。
  • 原子發布:先完成資料寫入與驗證,再以單一中繼資料提交讓結果可見。
  • 延後清除:舊檔必須跨過查詢最長執行時間、時間旅行需求與串流恢復窗口後才能刪除。

處理與串流、更新及刪除的競爭

合併最容易出問題的地方不是讀取,而是同一批檔案仍可能被更新。若 MERGE、UPDATE、DELETE 或串流 upsert 與合併同時修改重疊範圍,採用樂觀並行控制的資料表可能拒絕其中一個提交。這是保護機制,不應以忽略衝突或強制覆蓋處理。合併工作必須能重新取得最新快照、重新規劃受影響檔案,並以有限次數重試。

實務上可優先合併已越過事件時間 watermark、近期不再變動的冷分區;熱分區則提高觸發門檻、縮小每批範圍,或交由資料表格式原生的 clustering、optimize 或 compaction 功能處理。若業務要求更正歷史資料,不能假設舊分區永遠唯讀,排程仍應偵測更新活動並跳過正在變動的範圍。

刪除檔也要納入設計。部分格式會以 position delete、equality delete 或變更紀錄表示刪除,而不是立即重寫資料檔。合併時必須確認引擎是否會套用並吸收這些刪除;否則可能增加讀取成本,甚至在自製流程中讓已刪除資料重新出現。通常應使用資料表格式提供的維護程序,並把資料檔重寫、刪除檔整理、中繼資料清理與孤兒檔清除視為不同階段。

用可驗證、可停止的維護流程上線

建議先從一個低風險分區執行 canary。提交前比對資料列數、主鍵唯一性、必要欄位的最小值與最大值、分區值,以及檔案層級統計;提交後以代表性查詢驗證結果與延遲。資料列數相同並不足以證明正確,因為重複與遺漏可能互相抵銷。若資料含個資或敏感欄位,驗證也應避免把原始值寫入日誌。

排程條件應由實際壓力驅動,例如某分區的小檔案數、檔案大小分布或查詢規劃成本超過團隊設定的界線,而不是無條件每天重寫。監控至少要涵蓋輸入與輸出檔案數、改寫資料量、提交衝突、失敗重試、孤兒檔案與查詢效能。當衝突或延遲升高時,系統應能停止後續批次,而不是繼續擴大影響範圍。

  • 先小後大:以單一分區或有限檔案群組驗證,再逐步擴大。
  • 保留回滾窗口:確認所有長查詢與串流 checkpoint 已跨過舊快照,再執行過期與清理。
  • 分離維護工作:合併、排序、快照過期與孤兒檔清除應有各自的權限、指標與失敗處理。
  • 定期調整門檻:依查詢型態、寫入頻率與儲存成本重新評估,而非沿用一次設定的參數。

本文由 AI 依聖索科技規劃的主題自動撰寫,內容為一般性說明,導入前請依實際情況評估或與我們討論。

開始

有類似的需求?

告訴我們你的產業、目前系統狀態與預算範圍。我們會在 2 個工作天內回覆,並安排 30 分鐘免費諮詢。