すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:小さなファイルをマージする

最終更新日:Sep 16, 2025

分散ファイルシステムは、ブロック単位でデータを格納する。 サイズがブロックサイズ64 MB未満のファイルは、小ファイルと呼ばれる。 ほとんどの場合、小さなファイルは分散ファイルシステムで生成されます。 たとえば、SQL文の計算結果、分散エンジンの計算結果、およびTunnelコマンドを使用して収集されたデータを保存するために、小さなファイルが生成されます。 小さなファイルをマージしてシステムパフォーマンスを最適化できます。 このトピックでは、MaxComputeで小さなファイルをマージする方法について説明します。

背景情報

過度に小さなファイルが存在する場合、次の問題が発生する可能性があります。

  • 単一の大きなファイルに対するMaxComputeの処理効率は、複数の小さなファイルに対する処理効率よりも高いため、全体的な処理パフォーマンスが影響を受けます。

  • 過度に小さなファイルは、Apsara分散ファイルシステムの作業負荷を増加させます。 これはストレージ使用量に影響します。

したがって、上記の問題を解決するために、データ計算中に小さなファイルをマージする必要があります。 小さなファイルに対するMaxComputeの処理機能は、次の点で改善されています。

  • ジョブが完了すると、特定の条件が満たされると、MaxComputeは自動的にFuxiタスクを割り当てて小さなファイルをマージします。 この場合、MaxComputeが小さなファイルをマージするときにMergeTaskが表示されます。

  • デフォルトでは、Fuxiインスタンスは最大100個の小さなファイルを処理できます。 odps.sql.mapper.merge.limit.sizeパラメーターを設定して、読み取ることができるファイルの合計サイズを管理することもできます。

  • MaxComputeは定期的にメタデータベースをスキャンします。 スキャンプロセス中、MaxComputeは、多数の小さなファイルを含むテーブルまたはパーティション内の小さなファイルをマージします。 このプロセスはユーザーに表示されます。

多数の小さなファイルがマージされていないことをメタデータが示す場合は、これらのファイルを手動でマージする必要があります。 たとえば、多数の小さなファイルを含むテーブルにデータが継続的に書き込まれ、小さなファイルを自動的にマージできない場合は、書き込みジョブを停止して、小さなファイルを手動でマージする必要があります。

注意事項

  • コンピューティングリソースは、小さなファイルをマージするために消費されます。 従量課金インスタンスを使用する場合、料金が発生します。 課金ルールは、SQL文の従量課金ルールと一致しています。 詳細については、次をご参照ください: コンピューティング価格

  • 小さなファイルをマージするために使用されるコマンドは、トランザクションテーブルをサポートしません。 小さなファイルをトランザクションテーブルにマージする方法の詳細については、「COMPACTION」をご参照ください。

テーブル内のファイル数の表示

  • 構文

    次のコマンドを実行して、テーブル内のファイル数を表示できます。

    desc extended <table_name> [パーティション (<pt_spec>)];
  • パラメーター

    • table_name: 必須です。 ファイルを表示するテーブルの名前。

    • pt_spec: オプション。 表示するパーティション分割テーブル内のパーティション。 このパラメーターの値は、(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...) 形式です。

  • サンプル結果

    サンプルの結果を次の図に示します。 odl_bpm_wfc_task_logテーブルのサンプルパーティションには3,607ファイルが含まれています。 パーティションサイズは274 MB (287,869,658バイト) です。 平均ファイルサイズは約0.07 MBです。 この場合、小さなファイルをマージする必要があります。

    结果示例

解決策

パーティションに100を超えるファイルが含まれ、平均ファイルサイズが64 MB未満であることがメタデータによって示されている場合、次のいずれかの方法を使用して小さなファイルをマージできます。

  • コマンドを使用して小さなファイルをマージする

    次のコマンドを実行して、小さなファイルをマージします。

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

    odl_bpm_wfc_task_logテーブル内の小さなファイルがマージされると、ファイル数は19に減り、保存されるデータのサイズは37 MBに減ります。 これにより、ストレージ効率が大幅に向上します。 詳細は以下の図をご参照ください。即时合并

    ほとんどの場合、デフォルトのパラメータを使用して小さなファイルをマージできます。 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を使用できます。 この変数のデフォルト値は32で、単位はMBです。 この変数を設定する場合は、32より大きい値を指定します。

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

      マージ後の出力ファイルのサイズのしきい値を指定します。 出力ファイルのサイズがこのしきい値より大きい場合、新しい出力ファイルが作成されます。 単位:MB。 このパラメーターはオプションです。 このパラメーターを設定しない場合、グローバル変数odps_g_max_merged_filesize_thresholdを設定できます。 この変数のデフォルト値は500で、単位はMBです。 この変数を設定する場合は、500より大きい値を指定します。

  • PyODPSスクリプトを使用して小さなファイルをマージする

    PyODPSを使用してタスクを非同期に送信し、前日にタスクによって生成された小さなファイルをマージできます。 スクリプト例:

    osのインポート
    odpsからODPSをインポート
    
    # 環境変数ALIBABA_CLOUD_ACCESS_KEY_IDをAccessKey IDに設定します。 
    # 環境変数ALIBABA_CLOUD_ACCESS_KEY_SECRETをAccessKeyシークレットに設定します。 
    # AccessKey IDまたはAccessKeyシークレットを直接使用しないことを推奨します。
    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)
    
    # マージオプションを設定します。
    hints = {'odps.merge.maxmerged.filesize.threshold': 256}
    
    # マルチパーティションの例
    insts = []
    # iterate_partitionsは、ds=$datetimeの下のすべてのパーティションをリストするために使用されます。 パーティションフォーマットは、パーティションごとに異なる場合があります。
    t.iterate_partitionsのパーティション (spec="ds=% s" % $datetime):
        instance=odps.ru n_merge_files(table_name、str(partition) 、hints=hints)
    # このLogviewで待機キューをクリックして、コマンドが実行されているLogviewを見つけます。
        print(instance.get_logview_address())
        insts.append (インスタンス)
    
    # パーティション分割結果を待ちます。
    instsのinstのため:
        inst.wait_for_completion() 

    上記のスクリプトを実行する前に、PyODPSをインストールする必要があります。 PyODPSのインストール方法の詳細については、「PyODPS」をご参照ください。

例:

データ安定性システムは、物理テーブルtbcdm.dwd_tb_log_pv_diに多数の小さなファイルが含まれており、その小さなファイルをマージする必要があると判断します。 メタデータテーブルtbcdm.dws_rmd_merge_task_1dは、テーブル内のほとんどのパーティションに1,000を超えるファイル、さらには7,000を超えるファイルが含まれていることを示します。 ただし、一部のパーティションの平均ファイルサイズは1 MB未満です。 次の図は、tbcdm.dws_rmd_merge_task_1dというメタデータテーブルの情報を示しています。 使用示例次のコマンドを実行して、小さなファイルをマージします。

odps.merge.cross.paths=true;
odps.merge.smallfile.filesize.threshold=128;
set odps.merge.max.filenumber.per.instance = 2000;
テーブルtbcdm.dwd_tb_log_pv_diパーティション (ds='20151116') マージsmallfiles; 

次の図は、小さなファイルがマージされた後の結果を示しています。优化结果