メインコンテンツまでスキップ

Data distribution

データディストリビューション

適切な分割とバケッティングの設定は、均等なデータディストリビューションを実現するのに役立ちます。均等なデータディストリビューションとは、データを特定のルールに従い、異なるノードに均等に分割することを意味します。これにより、スキャンするデータ量が減少し、クラスタの並列処理能力を最大限に活用して問い合わせのパフォーマンスを向上させることができます。

注意

  • v3.1以降は、テーブルの作成やパーティションの追加時にDISTRIBUTED BY句でバケッティングキーを指定する必要はありません。StarRocksはランダムバケッティングをサポートしており、データをランダムにすべてのバケットに分散することができます。詳細については、ランダムバケッティングを参照してください。
  • v2.5.7以降、テーブルやパーティションの作成時にバケット数を手動で設定する必要はありません。StarRocksは自動的にバケット数(BUCKETS)を設定することができます。ただし、StarRocksによる自動的なバケット数の設定後にパフォーマンスが期待通りでない場合や、バケッティングメカニズムに詳しい場合は、バケット数の手動設定を参照して手動でバケット数を設定することもできます。

ディストリビューションの方法

一般的なディストリビューションの方法

現代の分散データベースシステムでは、一般的に次の基本的なディストリビューション方法が使用されます。ラウンドロビン、範囲、リスト、ハッシュです。

データディストリビューション方法
  • ラウンドロビン:データを循環的に異なるノードに分散します。
  • 範囲:パーティショニングの列の値の範囲に基づいてデータをさまざまなノードに分散します。図に示すように、範囲[1-3]と[4-6]は異なるノードに対応しています。
  • リスト:パーティショニングの列の離散値(性別、都道府県など)に基づいてデータをさまざまなノードに分散します。各離散値はノードにマップされ、複数の異なる値が同じノードにマップされることがあります。
  • ハッシュ:ハッシュ関数に基づいてデータをさまざまなノードに分散します。

より柔軟なデータパーティショニングを実現するために、これらのデータディストリビューション方法のうちの1つを使用するだけでなく、特定のビジネス要件に基づいてこれらの方法を組み合わせることもできます。一般的な組み合わせには、Hash+Hash、Range+Hash、Hash+Listなどがあります。

StarRocksでのディストリビューション方法

StarRocksは、データディストリビューション方法の個別および複合の使用をサポートしています。

注意

ジェネラルなディストリビューション方法に加えて、StarRocksはランダムディストリビューションもサポートしており、バケッティングの設定を簡素化します。

また、StarRocksは2レベルのパーティショニング+バケッティングメソッドを実装してデータを分散させます。

  • 第1レベルはパーティショニングです:テーブル内のデータをパーティションに分割することができます。サポートされているパーティショニングメソッドは、式パーティショニング、範囲パーティショニング、リストパーティショニングです。または、パーティションを使用しないことも選択できます(テーブル全体を1つのパーティションと見なします)。
  • 第2レベルはバケッティングです:パーティション内のデータをさらに小さなバケットに分散する必要があります。サポートされているバケッティングメソッドは、ハッシュバケッティングとランダムバケッティングです。

ディストリビューション方法

パーティショニングとバケッティングの方法

説明

ランダムディストリビューション

ランダムバケッティング

テーブル全体が1つのパーティションと見なされます。テーブルのデータはランダムに異なるバケットに分散されます。これはデフォルトのデータディストリビューション方法です。

ハッシュディストリビューション

ハッシュバケッティング

テーブル全体が1つのパーティションと見なされます。テーブルのデータは、ハッシュ関数を使用してバケット化キーコラムのハッシュ値に基づいて対応するバケットに分散されます。

範囲+ランダムディストリビューション

  1. 式パーティショニングまたは範囲パーティショニング
  2. ランダムバケッティング
  1. テーブルのデータは、パーティショニング列の値が含まれる範囲に基づいて対応するパーティションに分散されます。
  2. パーティション内のデータはランダムに異なるバケットに分散されます。

範囲+ハッシュディストリビューション

  1. 式パーティショニングまたは範囲パーティショニング
  2. ハッシュバケッティング
  1. テーブルのデータは、パーティショニング列の値が含まれる範囲に基づいて対応するパーティションに分散されます。
  2. パーティション内のデータは、ハッシュ関数を使用してバケット化キーのハッシュ値に基づいて対応するバケットに分散されます。

リスト+ランダムディストリビューション

  1. 式パーティショニングまたは範囲パーティショニング
  2. ランダムバケッティング
  1. テーブルのデータは、パーティショニング列の値が含まれる範囲に基づいて対応するパーティションに分散されます。
  2. パーティション内のデータはランダムに異なるバケットに分散されます。

リスト+ハッシュディストリビューション

  1. 式パーティショニングまたはリストパーティショニング
  2. ハッシュバケッティング
  1. テーブルのデータは、パーティショニング列の値が所属する値リストに基づいてパーティションに分割されます。
  2. パーティション内のデータは、ハッシュ関数を使用してバケット化キーのハッシュ値に基づいて対応するバケットに分散されます。
  • ランダムディストリビューションテーブルの作成時やパーティションの追加時にパーティショニングメソッドとバケッティングメソッドを設定しない場合、デフォルトでランダムディストリビューションが使用されます。このディストリビューション方法は、Duplicate Keyテーブルを作成する場合に使用されます。

    CREATE TABLE site_access1 (
    event_day DATE,
    site_id INT DEFAULT '10',
    pv BIGINT DEFAULT '0' ,
    city_code VARCHAR(100),
    user_name VARCHAR(32) DEFAULT ''
    )
    DUPLICATE KEY (event_day,site_id,pv); -- パーティショニングメソッドとバケッティングメソッドが設定されていないため、デフォルトでランダムディストリビューションが使用されます。
  • ハッシュディストリビューション

    CREATE TABLE site_access2 (
    event_day DATE,
    site_id INT DEFAULT '10',
    city_code SMALLINT,
    user_name VARCHAR(32) DEFAULT '',
    pv BIGINT SUM DEFAULT '0'
    )
    AGGREGATE KEY (event_day, site_id, city_code, user_name)
    -- バケッティングメソッドとバケッティングキーを指定する必要があります。
    DISTRIBUTED BY HASH(event_day,site_id);
  • 範囲+ランダムディストリビューション(このディストリビューション方法は、現在、Duplicate Keyテーブルを作成する場合にのみ使用できます。)

    CREATE TABLE site_access3 (
    event_day DATE,
    site_id INT DEFAULT '10',
    pv BIGINT DEFAULT '0' ,
    city_code VARCHAR(100),
    user_name VARCHAR(32) DEFAULT ''
    )
    DUPLICATE KEY(event_day,site_id,pv)
    -- パーティショニングメソッドとバケッティングメソッドを指定しない場合、デフォルトでランダムバケッティングが使用されます。
  • 範囲+ハッシュディストリビューション

    CREATE TABLE site_access4 (
    event_day DATE,
    site_id INT DEFAULT '10',
    city_code VARCHAR(100),
    user_name VARCHAR(32) DEFAULT '',
    pv BIGINT SUM DEFAULT '0'
    )
    AGGREGATE KEY(event_day, site_id, city_code, user_name)
    PARTITION BY date_trunc('day', event_day)
    -- バケッティングメソッドとバケッティングキーを指定する必要があります。
    DISTRIBUTED BY HASH(event_day, site_id);

パーティショニング

パーティショニングメソッドは、テーブルを複数のパーティションに分割します。パーティショニングは主に、パーティションキーに基づいてテーブルを異なる管理ユニット(パーティション)に分割するために使用されます。各パーティションに対してストレージ戦略を設定できます。ストレージ戦略には、バケットの数、ホットなデータとコールドなデータの保存戦略、ストレージメディアの種類、レプリカの数などが含まれます。StarRocksでは、クラスタ内でさまざまな種類のストレージメディアを使用できます。たとえば、クエリのパフォーマンスを向上させるために最新のデータをSSDに保存し、ストレージコストを削減するために過去のデータをSATAハードディスクに保存することができます。

パーティショニングメソッド

シナリオ

パーティションの作成方法

式パーティショニング(推奨)

前のバージョンでは自動パーティショニングとして知られていました。このパーティショニングメソッドはより柔軟で使いやすく、連続した日付範囲またはenum値に基づいてデータをクエリおよび管理する場合など、ほとんどのシナリオに適しています。

データの読み込み時に自動的に作成されます

範囲パーティショニング

シンプルで順序付けられたデータを保存し、連続した日付/数値の範囲に基づいて頻繁にクエリおよび管理されるデータ。たとえば、特定のケースでは、過去のデータを月で分割する必要があるが、最近のデータを日ごとに分割する必要がある場合があります。

手動で、動的にまたは一括で作成できます

リストパーティショニング

列挙値に基づいてデータのクエリと管理を行う一般的なシナリオで、パーティショニング列の値毎に異なる値を含める必要がある場合に使用します。たとえば、国や都市に基づいて頻繁にデータのクエリと管理を行う場合、この方法を使用し、をパーティショニング列として選択します。そのため、1つのパーティションには同じ国に所属する複数の都市のデータが格納されます。

手動で作成します

パーティショニング列と粒度の選択方法
  • 適切なパーティショニング列を選択することで、クエリ時のスキャンするデータ量を効果的に減らすことができます。ほとんどのビジネスシステムでは、期限切れのデータの削除やホットデータとコールドデータの階層化データの管理など、時間に基づいたパーティショニングが一般的に採用されます。この場合、式パーティショニングまたは範囲パーティショニングを使用し、時間列をパーティショニング列として指定することができます。また、データのクエリと管理が頻繁にenum値に基づいて行われる場合、式パーティショニングまたはリストパーティショニングを使用し、これらの値を含む列をパーティショニング列として指定することができます。
  • パーティショニングの粒度を選択する際には、データ容量、クエリパターン、およびデータ管理の粒度という要素を考慮する必要があります。
    • 例1:テーブルの月のデータ容量が小さい場合、メタデータの量が日のパーティショニングと比べて少なくなり、メタデータ管理とスケジューリングのリソース消費を削減することができます。
    • 例2:テーブルの月のデータ容量が大きく、クエリが主に特定の日のデータをリクエストする場合、日ごとのパーティショニングを使用することで、クエリ時のスキャンするデータ量を効果的に減らすことができます。
    • 例3:データが日単位で期限切れになる場合は、日ごとのパーティショニングをお勧めします。

バケッティング

バケッティングメソッドは、パーティションを複数のバケットに分割します。バケット内のデータはタブレットとして参照されます。

サポートされているバケッティングメソッドは、ランダムバケッティング(v3.1以降)とハッシュバケッティングです。

  • ランダムバケッティング:テーブルやパーティションの作成時にバケッティングキーを設定する必要はありません。パーティション内のデータはランダムに異なるバケットに分散されます。
  • ハッシュバケッティング:テーブルやパーティションの作成時にバケッティングキーを指定する必要があります。同じパーティション内のデータは、バケッティングキーの値に基づいてバケットに分割され、バケッティングキーの値が同じ行は対応するユニークなバケットに分散されます。

バケット数:デフォルトでは、StarRocksはバケット数を自動的に設定します(v2.5.7以降)。また、手動でバケット数を設定することもできます。詳細については、「バケット数の決定」を参照してください。

パーティションの作成と管理

パーティションの作成

式パーティショニング(推奨)

注意

v3.1以降、StarRocksの共有データモードは時間関数式をサポートしており、列式はサポートしていません。

v3.0以降、StarRocksは式パーティショニング(以前は自動パーティショニングとして知られていました)をサポートし、より柔軟で使いやすくなりました。このパーティショニングメソッドは、連続した日付範囲またはenum値に基づいてデータをクエリおよび管理する一般的なシナリオに適しています。

テーブル作成時にパーティション式(時間関数式または列式)を設定するだけで、StarRocksはデータの読み込み時に自動的にパーティションを作成します。事前に多くのパーティションを手動で作成する必要はなく、動的なパーティションプロパティを設定する必要もありません。

範囲パーティショニング

範囲パーティショニングは、時系列データ(日付またはタイムスタンプ)または連続する数値データなどのシンプルな連続データを保存するのに適しています。頻繁に日付/数値の連続範囲に基づいてクエリと管理が行われるデータのシナリオで使用されます。また、過去のデータを月ごとにパーティション分割し、最新のデータを日本ごとにパーティション分割するなど、いくつかの特殊なケースでも使用できます。

StarRocksは、明示的に定義された各パーティションに対する明示的に定義された範囲のマッピングに基づいてデータを対応するパーティションに格納します。

動的パーティショニング

動的パーティショニングに関連するプロパティは、テーブル作成時に設定されます。StarRocksは、データの新しいパーティションを事前に自動的に作成し、期限切れのパーティションを削除してデータの更新を保証し、パーティションのタイムトゥライブ(TTL)管理を実装します。

式パーティショニングによる自動的なパーティション作成機能とは異なり、動的パーティショニングではプロパティに基づいて定期的に新しいパーティションが作成されます。新しいデータがこれらのパーティションに属さない場合、ロードジョブはエラーが返されます。 ただし、ロードされたデータに基づいて常に対応する新しいパーティションを作成できる式パーティショニングによる自動的なパーティション作成能力があります。

手動でパーティションを作成

スキャンされるデータ量を効果的に削減するために適切なパーティションキーを使用できます。現在、パーティショニングの列のデータタイプは、DATE、DATETIME、もしくは含まれる数字や文字列(CHAR、VARCHAR、STRING)のいずれかを使用する必要があります。ビジネスシナリオでは、主にデータ管理の観点からパーティショニングキーを選択します。一般的なパーティショニング列には、日付または位置を表す列が含まれます。

CREATE TABLE site_access (
event_day DATE,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT SUM DEFAULT '0'

AGGREGATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY RANGE(event_day) (
PARTITION p1 VALUES LESS THAN ("2020-01-31"),
PARTITION p2 VALUES LESS THAN ("2020-02-29"),
PARTITION p3 VALUES LESS THAN ("2020-03-31")
)
DISTRIBUTED BY HASH(site_id);

想定されるテーブルsite_accessの各パーティションには10つのバケットがあります。次のクエリでは、10個のバケットのうち9個がプルーニングされ、StarRocksはsite_accessテーブル内のデータの1/10のみをスキャンする必要があります。

select sum(pv)
from site_access
where site_id = 54321;

ただし、もし site_idが不均衡状態である場合、たとえばある数のサイトのデータのみがリクエストされる場合、1つのバケット列でデータスキューが発生し、システムのパフォーマンスのボトルネックとなる可能性があります。この場合、複数のディストリビューション列を選択することができます。例えば、次のステートメントではsite_idcity_codeをバケットング列として使用しています。

CREATE TABLE site_access

site_id INT DEFAULT '10',
city_code SMALLINT,
user_name VARCHAR(32) DEFAULT '',
pv BIGINT SUM DEFAULT '0'

AGGREGATE KEY(site_id, city_code, user_name)
DISTRIBUTED BY HASH(site_id,city_code);

実際の設定では、ビジネスの特性に応じて1つまたは2つのバケットング列を選択することができます。データのスキャン量が少ない短いクエリには1つのバケットング列 site_id を使用する方が効果的です。これにより、ノード間のデータのやりとりを減らすことができ、クラスタ全体のパフォーマンスを向上させることができます。一方、2つのバケットング列 site_idcity_code を使用することで、長時間のクエリでは分散クラスタの全体的な同時性を活用してパフォーマンスを大幅に向上させることができます。

注意

  • 短いクエリでは、少量のデータをスキャンして単一のノードで完了できます。
  • 長時間のクエリでは、大量のデータをスキャンし、分散クラスタの複数のノードで並列スキャンすることでパフォーマンスを大幅に向上させることができます。

パーティションの管理

パーティションの追加

範囲パーティショニングとリストパーティショニングでは、新しいデータを格納するために新しいパーティションを手動で追加することができます。ただし、式パーティショニングでは、データの読み込み時にパーティションが自動的に作成されるため、手動で追加する必要はありません。

次のステートメントは、テーブルsite_accessに新しい月のデータを格納するための新しいパーティションを追加します。

ALTER TABLE site_access
ADD PARTITION p4 VALUES LESS THAN ("2020-04-30")
DISTRIBUTED BY HASH(site_id);

パーティションの削除

次のステートメントは、テーブルsite_accessからパーティションp1を削除します。

注意

この操作はパーティション内のデータを即座に削除しません。データはトラッシュに一定期間(デフォルトでは1日)保持されます。パーティションが誤って削除された場合、RECOVER コマンドを使用してパーティションとそのデータを復元することができます。

ALTER TABLE site_access
DROP PARTITION p1;

パーティションの復元

次のステートメントは、テーブルsite_accessにパーティションp1とそのデータを復元します。

RECOVER PARTITION p1 FROM site_access;

パーティションの表示

次のステートメントは、テーブルsite_accessのすべてのパーティションの詳細を返します。

SHOW PARTITIONS FROM site_access;

バケッティングの設定

ランダムバケッティング(v3.1以降)

StarRocksは、パーティション内のデータをランダムにすべてのバケットに分散します。データサイズが小さく、クエリのパフォーマンス要件が比較的低いシナリオに適しています。バケッティング方式を設定しない場合、StarRocksはデフォルトでランダムバケッティングを使用し、自動的にバケット数を設定します。

ただし、大量のデータをクエリする場合や、特定の列をフィルタ条件として頻繁に使用する場合など、ランダムバケッティングによって提供されるクエリパフォーマンスが最適でない場合があります。そのような場合は、ハッシュバケッティングを使用することをお勧めします。これらの列をクエリのフィルタ条件として使用する場合、クエリが命中した一部のバケットのデータのみ