メインコンテンツまでスキップ
に最終更新

データのバケット分割

パーティションは、ビジネス要件に応じて複数のデータバケットにさらに分割できます。各バケットは物理的なデータシャード(Tablet)として保存されます。適切なバケット分割戦略により、クエリ時にスキャンするデータ量を効果的に減らし、クエリ性能と同時処理能力を向上できます。

このドキュメントは、テーブル作成時の判断順序に沿って構成されています。まずバケット分割方式を選び、次にバケットキーを選定し、最後にバケット数とその後の管理方法を決めます。

判断の手順​

テーブルを作成する際は、次の順序でバケット分割を設計できます。

手順判断項目主な検討事項
1バケット分割方式を選ぶフィルターに頻繁に使うカラムの有無、データ分布の均等さ、テーブルモデル
2バケットキーを選定する(Hash バケット分割のみ)クエリのフィルター条件、カラムのカーディナリティ、クエリの同時実行数とスループットの特性
3バケット数を決めるTablet ごとのデータサイズ、BE の数、ディスクの数
4バケットの管理方針を立てるデータの増加傾向、動的パーティションの使用有無

1. バケット分割方式を選ぶ​

Doris は Hash バケット分割と Random バケット分割の二つの方式をサポートします。主な違いは次のとおりです。

比較項目Hash バケット分割Random バケット分割
データの分散方法バケットキーの Hash 値に基づいて分割ランダムかつ均等に分散
バケットキーの要否必要不要
バケットのプルーニングのサポートありなし
対応するテーブルモデルDUPLICATE / UNIQUE / AGGREGATEDUPLICATE のみ
データスキューのリスクバケットキーの選択による低い
適した用途特定のカラムで頻繁に絞り込むポイントクエリ任意のディメンションでの分析、スキューが生じやすいデータ

1. Hash バケット分割​

テーブルの作成時または新しいパーティションの追加時には、一つ以上のカラムをバケットキーとして選び、バケット数を明示的に指定する必要があります。同じパーティション内では、システムがバケットキーとバケット数に基づいて Hash 値を計算し、同じ Hash 値を持つ行を同じバケットに割り当てます。

たとえば、次の図では、p250102 パーティションが region カラムによって 3 つのバケットに分割され、同じ Hash 値を持つ行が同じバケットに配置されます。

Hash バケット分割

推奨される用途:

  • 特定のフィールドで頻繁に絞り込む場合、そのフィールドをバケットキーにしてバケットのプルーニングを利用すると、クエリ効率を向上できます。
  • テーブル内のデータが比較的均等に分布し、スキューが生じにくい場合。

例: Hash バケット分割を使用するテーブルを作成します。構文の詳細については、CREATE TABLE を参照してください。

以下の例では、テーブル名に demo データベースを指定します。クラスターにまだ存在しない場合は、先に作成してください。

CREATE DATABASE IF NOT EXISTS demo;
CREATE TABLE demo.hash_bucket_tbl(
oid BIGINT,
dt DATE,
region VARCHAR(10),
amount INT
)
DUPLICATE KEY(oid)
PARTITION BY RANGE(dt) (
PARTITION p250101 VALUES LESS THAN("2025-01-01"),
PARTITION p250102 VALUES LESS THAN("2025-01-02")
)
DISTRIBUTED BY HASH(region) BUCKETS 8;

この例では、DISTRIBUTED BY HASH(region) が Hash バケット分割の使用と region カラムのバケットキーへの指定を表します。BUCKETS 8 は、8 つのバケットを作成する指定です。

2. Random バケット分割​

Random バケット分割は、フィールドの Hash 値に依存せず、各パーティション内のバケットにデータをランダムに分散します。この方式により、データが均等に分散され、不適切なバケットキーの選択によるデータスキューを回避できます。

データのロード時には、単一のロードジョブ内の各バッチがランダムに Tablet に書き込まれ、データの均等な分散が保証されます。たとえば、次の図では、8 つのデータバッチが p250102 パーティション内の 3 つのバケットにランダムに割り当てられます。

Random バケット分割

Random バケット分割では、単一 Tablet ロードモードを有効にできます(load_to_single_tablet を true に設定)。この場合、一つのバッチのデータは一つのデータシャードにのみ書き込まれます。これにより、次の効果が得られます。

  • 大規模なデータロードの同時実行数とスループットを向上させます。
  • データロードと Compaction 操作による書き込み増幅を抑えます。
  • クラスターの安定性を高めます。

推奨される用途:

  • 固定のフィルターカラムや結合カラムがなく、任意のディメンションで分析する場合。
  • 頻繁にクエリするカラム、またはカラムの組み合わせのデータ分布が大きく偏っており、データスキューを避ける必要がある場合。

適さない用途:

  • ポイントクエリ:Random バケット分割ではバケットキーに基づくプルーニングができないため、条件に一致するパーティション内のすべてのデータをスキャンします。
  • UNIQUE および AGGREGATE テーブル:Random バケット分割をサポートするのは DUPLICATE テーブルのみです。

例: Random バケット分割を使用するテーブルを作成します。構文の詳細については、CREATE TABLE を参照してください。

CREATE TABLE demo.random_bucket_tbl(
oid BIGINT,
dt DATE,
region VARCHAR(10),
amount INT
)
DUPLICATE KEY(oid)
PARTITION BY RANGE(dt) (
PARTITION p250101 VALUES LESS THAN("2025-01-01"),
PARTITION p250102 VALUES LESS THAN("2025-01-02")
)
DISTRIBUTED BY RANDOM BUCKETS 8;

この例では、DISTRIBUTED BY RANDOM が Random バケット分割の使用を表し、バケットキーの選定は不要です。BUCKETS 8 は、8 つのバケットを作成する指定です。

2. バケットキーを選定する​

ヒント

バケットキーの選定が必要なのは Hash バケット分割のみです。Random バケット分割では不要です。

バケットキーには一つ以上のカラムを指定できます。テーブルモデルごとに、バケットキーには次の制約があります。

テーブルモデルバケットキーに指定できるカラム
DUPLICATE任意の Key カラムまたは Value カラム
AGGREGATE / UNIQUEKey カラムであること(正しいデータ集約を保証するため)

選定の原則​

ビジネス上のクエリの特性に応じて、バケットキーを選ぶ際は次の原則を参考にしてください。

原則説明利点
クエリのフィルター条件を活用するクエリでフィルターとして頻繁に使うカラムをバケットキーに選ぶバケットのプルーニングが可能になり、スキャンするデータ量を削減できる
カーディナリティの高いカラムを活用する異なる値が多いカラムをバケットキーに選ぶデータが均等に分散され、スキューを回避できる
同時実行数が多いポイントクエリ一つのカラムまたは少数のカラムをバケットキーに選ぶ一つのクエリでスキャンするバケットが一つだけになり、クエリ間の IO 干渉を抑えられる
スループットが高いクエリ複数のカラムをバケットキーに選ぶデータがより均等に分散され、クエリ条件が等値条件に完全には一致しない場合に全体のスループットが向上する

3. バケット数を決める​

Doris では、各 Bucket は物理ファイル(Tablet)として保存されます。テーブル内の Tablet の総数は次のとおりです。

Total Tablets = partition_num × bucket_num
注意

パーティションのバケット数は、一度指定すると変更できません。バケット数を決める際は、将来のマシンの増設を見据えて計画してください。

バージョン 2.0 以降、Doris はマシンリソースとクラスター情報に基づいて、パーティションのバケット数を自動設定できます。ビジネス上、見積もりに求められる精度に応じて、手動方式と自動方式を選択できます。

1. バケット数を手動で設定する​

DISTRIBUTED 句でバケット数を指定します。

-- Set hash bucket num to 8
DISTRIBUTED BY HASH(region) BUCKETS 8

-- Set random bucket num to 8
DISTRIBUTED BY RANDOM BUCKETS 8

判断の原則​

バケット数を決める際は、次の二つの原則に従います。両者が競合する場合は、サイズに関する原則を優先します。

  1. サイズに関する原則:各 Tablet の圧縮後のデータサイズ(インデックスを除く)は 1 GB から 20 GB に収めることを推奨します。Unique Key テーブルでは 10 GB 以下にしてください。

    • Tablet が小さすぎる場合:集約の効果が下がり、メタデータ管理のオーバーヘッドが増えます。
    • Tablet が大きすぎる場合:レプリカの移行と復旧が難しくなり、失敗した Schema Change の再試行コストが増えます。
    • SHOW TABLETS FROM your_table で Tablet の実際のサイズを確認できます。
  2. 数量に関する原則:スケールアウトを考慮しない場合、テーブル内の Tablet 数はクラスター内のディスク総数より少し多くすることを推奨します。

また、次の点にも注意してください。

  • データを均等に分散させるため、バケット数は BE 数の整数倍にする必要があります。
  • 単一パーティションのバケット数は、通常 128 を超えないようにします。それ以上必要な場合は、まずテーブルをパーティション分割してください。

クラスターに 10 台の BE マシンがあり、それぞれにディスクが一台あるとします。バケット数の設定には次の表を参考にしてください。

パーティションの圧縮後のデータサイズ推奨バケット数
< 1 GB1 バケット
1 - 10 GB10 バケット
10 - 200 GB10 - 20 バケット
> 200 GBまずテーブルをパーティション分割する
ヒント

SHOW DATA コマンドでテーブルのデータサイズを確認できます。結果をレプリカ数で割ると、テーブルの実際のデータサイズが得られます。

2. バケット数を自動で設定する​

バケット数の自動推定機能は、直近のパーティションサイズから将来のパーティションサイズを予測し、それに応じてバケット数を決定します。

-- Set hash bucket auto
DISTRIBUTED BY HASH(region) BUCKETS AUTO
properties("estimate_partition_size" = "20G")

-- Set random bucket auto
DISTRIBUTED BY RANDOM BUCKETS AUTO
properties("estimate_partition_size" = "20G")

estimate_partition_size プロパティは、パーティションサイズの初期推定値を調整するために使用します。

  • このパラメータは省略可能です。指定しない場合のデフォルト値は 10GB です。
  • このパラメータは初期推定値にのみ影響し、後でシステムが過去のパーティションデータから推定する将来のパーティションサイズには影響しません。

計算されたバケット数は、FE 設定の autobucket_min_buckets と autobucket_max_buckets の範囲に収められます。

FE 設定デフォルト値説明
autobucket_min_buckets3自動バケット分割の結果の下限。デフォルト値は 1 から 3 に変更されました。4.0.8(4.0 系)および 4.1.4(4.1 系)で適用されます
autobucket_max_buckets128自動バケット分割の結果の上限
動作変更(4.0.8 / 4.1.4)

autobucket_min_buckets のデフォルト値は、1 から 3 に変更されました。4.0.8(4.0 系)および 4.1.4(4.1 系)で適用されます。以前は小さなパーティションでバケット数が一つまで減ることがあり、並列処理とデータ分散が不十分になる場合がありました。変更後は、自動バケット分割で生成されるバケット数が 3 未満になることはありません。

この変更が影響するのは、アップグレード後に作成されたパーティションのみです。既存のパーティションのバケット数は変わりません。以前の動作を維持するには、autobucket_min_buckets を明示的に 1 に設定してください。

4. データのバケット分割を管理する​

ヒント

現在、Doris では新しく追加するパーティションのバケット数のみ変更できます。次の操作はサポートされていません。

  1. バケット分割方式の変更。
  2. バケットキーの変更。
  3. 作成済みのバケットのバケット数の変更。

テーブル作成時には、各パーティションのバケット数を DISTRIBUTED 句で一律に指定します。データの増加や減少に対応するため、パーティションを動的に追加する際には、新しいパーティションのバケット数を個別に指定できます。

次の例は、ALTER TABLE コマンドを使用して、新しく追加するパーティションのバケット数を変更する方法を示します。

-- Modify hash bucket table
ALTER TABLE demo.hash_bucket_tbl
ADD PARTITION p250103 VALUES LESS THAN("2025-01-03")
DISTRIBUTED BY HASH(region) BUCKETS 16;

-- Modify random bucket table
ALTER TABLE demo.random_bucket_tbl
ADD PARTITION p250103 VALUES LESS THAN("2025-01-03")
DISTRIBUTED BY RANDOM BUCKETS 16;

-- Modify dynamic partition table
ALTER TABLE demo.dynamic_partition_tbl
SET ("dynamic_partition.buckets"="16");

バケット数を変更した後は、SHOW PARTITION コマンドで結果を確認できます。