全部產品
Search
文件中心

MaxCompute:合并小檔案

更新時間:Sep 02, 2026

Distributed File System按塊(Block)存放資料,檔案大小比塊大小(64MB)小的檔案稱為小檔案。分布式系統不可避免會產生小檔案,比如SQL或其他分布式引擎的計算結果、Tunnel資料擷取。合并小檔案可以達到最佳化系統效能的目的。本文為您介紹如何在MaxCompute中合并小檔案。

背景資訊

小檔案過多,會帶來以下問題:

  • MaxCompute處理單個大檔案比處理多個小檔案更有效率,小檔案過多會影響整體的執行效能。

  • 小檔案過多會給Pangu檔案系統帶來一定的壓力,影響儲存空間的有效利用。

因此從儲存和效能兩方面考慮,都需要將計算過程中產生的小檔案合并。MaxCompute在小檔案處理方面的功能日趨完善,主要體現在以下方面:

  • 預設情況下,當作業完成之後,如果滿足一定的條件,系統會自動分配一個Fuxi Task進行小檔案合并,即使用過程中經常看到的MergeTask。

  • 預設情況下,一個Fuxi Instance不再只能處理一個小檔案,而是最多可以處理100個小檔案,同時可以通過odps.sql.mapper.merge.limit.size參數來控制讀取檔案總大小。

  • MaxCompute後台會定期掃描中繼資料庫,對小檔案較多的表或分區進行小檔案合并,這個合并過程對您透明。

但是通過中繼資料發現仍然存在大量的小檔案未被合并掉,例如有的表一直在寫入,無法自動執行合併作業,需要您先將寫入作業停止,然後再手工進行小檔案合併作業。

注意事項

  • 使用合并小檔案功能需要用到計算資源,如果您購買的執行個體是隨用隨付,會產生相關費用,具體計費規則與SQL隨用隨付保持一致,詳情請參見計算費用(隨用隨付)

  • 合并小檔案命令不支援Transactional表,如果需要對Transactional表進行小檔案合并,請參見COMPACTION

查看錶的檔案數

  • 命令文法

    您可以通過如下命令查看錶的檔案數:

    desc extended <table_name> [partition (<pt_spec>)];
  • 參數說明

    • table_name:必填。待查看錶的名稱。

    • pt_spec:可選。待查看分區表的指定分區。格式為(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)

  • 結果樣本

    如下所示,odl_bpm_wfc_task_log表的樣本分區有3607個檔案, 分區大小274MB (287869658Byte),平均檔案大小約為0.07MB,需要進行小檔案合并。

    odps@ admin_task_project>desc extended jxbwarehouse.odl_bpm_wfc_task_log partition(new_dts_sync_modifytime_year='2022',new_dts_sync_modifytime_month='11',new_dts_sync_modifytime_day='27');
    +--------------------------------------------------------------------------------------------+
    | PartitionSize: 287869658                                                                   |
    +--------------------------------------------------------------------------------------------+
    | CreateTime:               2022-11-27 00:00:46                                              |
    | LastDDLTime:              2022-11-27 00:00:46                                              |
    | LastModifiedTime:         2022-11-27 23:59:47                                              |
    +--------------------------------------------------------------------------------------------+
    | IsExstore:                false                                                            |
    | IsArchived:               false                                                            |
    | PhysicalSize:             863608974                                                        |
    | FileNum:                  3607                                                             |
    +--------------------------------------------------------------------------------------------+

解決方案

通過中繼資料檢測,分區中含有100個以上的檔案且平均檔案大小小於64MB的都可以進行小檔案合并,合并的方案有如下兩種。

  • 即時合并

    使用如下命令進行小檔案即時合并。

    ALTER TABLE <table_name> [partition (<pt_spec>)] MERGE SMALLFILES;

    odl_bpm_wfc_task_log表執行即時合併作業,完成後如下所示檔案數減少為19個,儲存大小也減少到37MB,在合并小檔案的同時,儲存效率也有了明顯提升。

    odps@ adxxx>alter table  jxbwarehouse.odl_bpm_wfc_task_log partition(new_dts_sync_modifytime_year='2022',new_dts_sync_modifytime_month='11',new_dts_sync_modifytime_day='27') merge smallfiles;
    ID = xxx
    Log view:
    http:
    E2NzA
    aW9uIjoiMSJ9
    Job Queueing..
    
             STAGES        STATUS   TOTAL  COMPLETED   RUNNING   PENDING   BACKUP
    MergeFinalizeTask_0_admin..  TERMINATED    1        1          0         0        0
    MergeTask_0_admin_task_pr..  TERMINATED   19       19          0         0        0
    
    STAGES: 02/02  [==============================>>] 100%  ELAPSED TIME: 75.88 s
    
    Summary:
    project name: , xxx  schema name: jxbwarehouse table name: odl_bpm_wfc_task_log /new_dts_sync_modifytime_year=2022/new_dts_sync_modifytime_month=11/new_dts_sync_modifytime_day=27  instance count: 20
        before merge, file count:     3607  file size: 281122K  file physical size: 843368K
        after merge, file count:       19  file size: 37495K  file physical size: 112486K

    一般情況下,使用預設參數可以達到合并小檔案的效果。但MaxCompute同時提供一些參數完成定製需求,常用的一些參數如下:

    • set odps.merge.cross.paths=true|false

      設定是否跨路徑合并,對於表下面有多個分區的情況,合并過程會將多個分區產生獨立的MergeAction進行合并,所以對於odps.merge.cross.paths設定為true,並不會改變路徑個數,只是分別去合并每個路徑下的小檔案。

    • set odps.merge.smallfile.filesize.threshold = 64

      設定合并檔案的小檔案大小閾值,檔案大小超過該閾值,則不進行合并,單位為MB。此參數可以不進行設定,不設定時,則使用全域變數odps_g_merge_filesize_threshold,該參數值預設為32MB,設定時必須大於32MB。

    • set odps.merge.maxmerged.filesize.threshold = 500

      設定合并輸出檔案量的大小,輸出檔案大於該閾值,則建立新的輸出檔案,單位為MB。此參數可以不進行設定,不設定時,則使用全域變odps_g_max_merged_filesize_threshold,該參數值預設為500MB,設定時必須大於500MB。

  • PyODPS指令碼合并

    通過PyODPS非同步提交任務,合并前一天任務產出的小檔案,指令碼樣本如下:

    import os
    from odps import ODPS
    
    # 確保 ALIBABA_CLOUD_ACCESS_KEY_ID 環境變數設定為使用者 Access Key ID,
    # ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境變數設定為使用者 Access Key Secret,
    # 不建議直接使用 Access Key ID / Access Key Secret 字串
    o = ODPS(
        os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
        os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
        project='your-default-project',
        endpoint='your-end-point',
    )
    
    #注意需要替換$table_name為所需的表名
    table_name = $table_name
    t = odps.get_table(table_name)
    
    #設定merge選項
    hints = {'odps.merge.maxmerged.filesize.threshold': 256}
    
    #examples for multi partition
    insts = []
    #iterate_partitions list列舉ds=$datetime下所有分區,分區格式也可能是其他格式
    for partition in t.iterate_partitions(spec="ds=%s" % $datetime):
        instance=odps.run_merge_files(table_name, str(partition), hints=hints)
    		#從這個logview的Waiting Queue點進去,才可以找到真正執行的logview
        print(instance.get_logview_address())
        insts.append(instance)
    
    #等待分區結果
    for inst in insts:
        inst.wait_for_completion()

    運行上述指令碼需要提前安裝PyODPS,安裝方法請參見PyODPS

使用案例

tbcdm.dwd_tb_log_pv_di是資料穩定性體系識別出來的需要合并小檔案的物理表,通過中繼資料tbcdm.dws_rmd_merge_task_1d提供的資訊,可以看出此表相關分區的檔案個數大部分都在1000以上,多的甚至達到7000以上,但平均檔案大小有些還不到1MB。

查詢表 dwd_tb_log_pv_di 在分區 ds=20151114 下各子分區(按 visitor_typeurl_type 組合)的檔案統計資訊,結果顯示 pangu_file_num(檔案數量)普遍較高(如 7384、7018、6818、5384 等),而 avg_pangu_file_size(平均檔案大小)較小,存在明顯的小檔案問題。

使用如下命令採用即時合并方案對其進行小檔案合并。

set odps.merge.cross.paths=true;
set odps.merge.smallfile.filesize.threshold=128;
set odps.merge.max.filenumber.per.instance = 2000;
alter table tbcdm.dwd_tb_log_pv_di partition (ds='20151116') merge smallfiles;

執行合并命令後,各分區的合并結果如下,file count 從數千個大幅減少到與 instance count 一致的數十個。

Summary:
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=uid/url_type=other/company=c  instance count: 442  run time: 182
  before merge, file count:     8285  file size: 226272202K  file physical size: 678816607K
   after merge, file count:      442  file size: 226193505K  file physical size: 678580517K
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=mid/url_type=other/company=c  instance count: 50  run time: 136
  before merge, file count:     8285  file size: 25174441K  file physical size: 75523325K
   after merge, file count:       50  file size: 24979902K  file physical size: 74939708K
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=mid/url_type=ipv/company=c  instance count: 48  run time: 183
  before merge, file count:     7888  file size: 24452025K  file physical size: 73356075K
   after merge, file count:       48  file size: 24328967K  file physical size: 72986902K
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=uid/url_type=ipv/company=c  instance count: 131  run time: 125
  before merge, file count:     7620  file size: 66788449K  file physical size: 200365347K
   after merge, file count:      131  file size: 66660873K  file physical size: 199982619K
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=uid/url_type=search/company=c  instance count: 45  run time: 115
  before merge, file count:     6285  file size: 22863879K  file physical size: 68591639K
   after merge, file count:       45  file size: 22732543K  file physical size: 68197630K
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=uid/url_type=shop/company=c  instance count: 50  run time: 104
  before merge, file count:     6285  file size: 25156741K  file physical size: 75470224K
   after merge, file count:       50  file size: 25029475K  file physical size: 75088426K
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=mid/url_type=search/company=c  instance count: 15  run time: 130
  before merge, file count:     6285  file size: 7265051K  file physical size: 21795153K
   after merge, file count:       15  file size: 7148859K  file physical size: 21446577K
table name: dwd_tb_log_pv_di /ds=20151116/visitor_type=mid/url_type=shop/company=c  instance count: 12  run time: 140
  before merge, file count:     6285  file size: 5861160K  file physical size: 17583481K
   after merge, file count:       12  file size: 5734710K  file physical size: 17204132K