データ分散
テーブル作成時に適切なパーティション化とバケッティングを設定することで、均等なデータ分散を実現できます。均等なデータ分散とは、特定のルールに従ってデータをサブセットに分割し、異なるノードに均等に分配することを意味します。これにより、スキャンするデータ量を減らし、クラスターの並列処理能力を最大限に活用することで、クエリパフォーマンスを向上させることができます。
注意
- テーブル作成時にデータ分散が指定され、ビジネスシナリオでクエリパターンやデータ特性が進化した場合、v3.2以降のStarRocksでは、最新のビジネスシナリオにおけるクエリパフォーマンスの要件を満たすために、テーブル作成後に特定のデータ分散関連プロパティを変更することがサポートされています。
- v3.1以降、テーブル作成時やパーティション追加時にDISTRIBUTED BY句でバケッティングキーを 指定する必要はありません。StarRocksはランダムバケット法をサポートしており、データをすべてのバケットにランダムに分配します。詳細はランダムバケット法を参照してください。
- v2.5.7以降、テーブル作成時やパーティション追加時にバケット数を手動で設定しないことを選択できます。StarRocksは自動的にバケット数(BUCKETS)を設定します。ただし、StarRocksが自動的にバケット数を設定した後にパフォーマンスが期待に応えない場合で、バケッティングメカニズムに精通している場合は、バケット数を手動で設定することもできます。
はじめに
一般的な分散手法
現代の分散データベースシステムは、一般的に以下の基本的な分散手法を使用します: ラウンドロビン、レンジ、リスト、ハッシュ。
- ラウンドロビン: データを異なるノードに循環的に分配します。
- レンジ: パーティション列の値の範囲に基づいてデータを異なるノードに分配します。図に示されているように、範囲[1-3]と[4-6]は異な るノードに対応しています。
- リスト: パーティション列の離散値に基づいてデータを異なるノードに分配します。例えば、性別や州などの値です。各離散値がノードにマッピングされ、複数の異なる値が同じノードにマッピングされることがあります。
- ハッシュ: ハッシュ関数に基づいてデータを異なるノードに分配します。
より柔軟なデータパーティション化を実現するために、上記のデータ分散手法のいずれかを使用するだけでなく、特定のビジネス要件に基づいてこれらの手法を組み合わせることもできます。一般的な組み合わせには、ハッシュ+ハッシュ、レンジ+ハッシュ、ハッシュ+リストがあります。
StarRocksにおける分散手法
StarRocksは、データ分散手法の個別使用と複合使用の両方をサポートしています。
注意
一般的な分散手法に加えて、StarRocksはバケッティング設定を簡素化するためにランダム分散もサポートしています。
また、StarRocksは2レベルのパーティション化+バケッティング手法を実装してデータを分散します。
- 第一レベルはパーティション化です: テーブル内のデータはパーティション化できます。サポートされているパーティション化の手法は、式に基づくパーティション化、レンジパーティション化、リストパーティション化です。また、パーティション 化を使用しないことも選択できます(テーブル全体が1つのパーティションと見なされます)。
- 第二レベルはバケッティングです: パーティション内のデータはさらに小さなバケットに分配される必要があります。サポートされているバケッティング手法は、ハッシュとランダムバケット法です。
分散手法 | パーティション化とバケッティング手法 | 説明 |
---|---|---|
ランダム分散 | ランダムバケット法 | テーブル全体が1つのパーティションと見なされます。テーブル内のデータはランダムに異なるバケットに分配されます。これはデフォルトのデータ分散手法です。 |
ハッシュ分散 | ハッシュバケット法 | テーブル全体が1つのパーティションと見なされます。テーブル内のデータは、ハッシュ関数を使用してデータのバケッティングキーのハッシュ値に基づいて対応するバケットに分配されます。 |
レンジ+ランダム分散 |
|
|
レンジ+ハッシュ分散 |
|
|
リスト+ランダム分散 |
|
|
リスト+ハッシュ分散 |
|
|
-
ランダム分散
テーブル作成時にパーティション化とバケッティング手法を設定しない場合、デフォルトでランダム分散が使用されます。この分散手法は現在、重複キーテーブルの作成にのみ使用できます。
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); -
レンジ+ランダム分散(この分散手法は現在、重複キーテーブルの作成にのみ使用できます。)
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)
-- パーティション化手法として式に基づくパーティション化を使用し、時間関数の式を設定します。
-- レンジパーティション化を使用することもできます。
PARTITION BY date_trunc('day', event_day);
-- バケッティング手法が設定されていないため、デフォルトでランダムバケット法が使用されます。 -
レンジ+ハッシュ分散
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); -
リスト+ランダム分散(この分散手法は現在、重複キーテーブルの作成にのみ使用できます。)
CREATE TABLE t_recharge_detail1 (
id bigint,
user_id bigint,
recharge_money decimal(32,2),
city varchar(20) not null,
dt date not null
)
DUPLICATE KEY(id)
-- パーティション化手法として式に基づくパーティション化を使用し、パーティション列を指定します。
-- リストパーティション化を使用することもできます。
PARTITION BY (city);
-- バケッティング手法が設定されていないため、デフォルトでランダムバケット法が使用されます。 -
リスト+ハッシュ分散
CREATE TABLE t_recharge_detail2 (
id bigint,
user_id bigint,
recharge_money decimal(32,2),
city varchar(20) not null,
dt date not null
)
DUPLICATE KEY(id)
-- パーティション化手法として式に基づくパーティション化を使用し、パーティション列を指定します。
-- リストパーティション化を使用することもできます。
PARTITION BY (city)
-- バケッティング手法としてハッシュバケット法を使用し、バケッティングキーを指定する必要があります。
DISTRIBUTED BY HASH(city,id);
パーティション化
パーティション化手法は、テーブルを複数のパーティションに分割します。パーティション化は主に、パーティションキーに基づいてテーブルを異なる管理単位(パーティション)に分割するために使用されます。各パーティションに対して、バケット数、ホットデータとコールドデータの保存戦略、記憶媒体の種類、レプリカの数などのストレージ戦略を設定できます。StarRocksは、クラスター内で異なる種類の記憶媒体を使用することを許可しています。例えば、最新のデータをSSDに保存してクエリパフォーマンスを向上させ、履歴データをSATAハードドライブに保存してストレージコストを削減することができます。
パーティション化手法 | シナリオ | パーティションを作成する方法 |
---|---|---|
式に基づくパーティション化(推奨) | 以前は自動パーティション化として知られていました。このパーティション化手法はより柔軟で使いやすく、連続した日付範囲や列挙値に基づいてデータをクエリおよび管理するほとんどのシナリオに適しています。 | データロード中に自動的に作成されます |
レンジパーティション化 | 典型的なシナリオは、連続した日付/数値範囲に基づいて頻繁にクエリおよび管理されるシンプルで順序付けられたデータを保存することです。例えば、特定のケースでは、履歴データを月単位でパーティション化し、最近のデータを日単位でパーティション化する必要があります。 | 手動 で、動的に、またはバッチで作成されます |
リストパーティション化 | 典型的なシナリオは、列挙値に基づいてデータをクエリおよび管理し、各パーティション列の異なる値を含むデータを含むパーティションが必要な場合です。例えば、国や都市に基づいて頻繁にデータをクエリおよび管理する場合、この手法を使用し、city をパーティション列として選択できます。これにより、同じ国に属する複数の都市のデータを1つのパーティションに保存できます。 | 手動で作成されます |
パーティション列と粒度の選び方
- パーティションキーは1つ以上のパーティション列で構成されます。適切なパーティション列を選択することで、クエリ時にスキャンするデータ量を効果的に減らすことができます。ほとんどのビジネスシステムでは、期限切れデータの削除によって引き起こされる特定の問題を解決し、ホットデータとコールドデータの階層型ストレージの管理を容易にするために、時間に基づいたパーティション化が一般的に採用されています。この場合、式に基づくパーティション化またはレンジパーティション化を使用し、時間列をパーティション列として指定できます。さらに、データが頻繁にENUM値に基づいてクエリおよび管理される場合、式に基づくパーティション化またはリストパーティション化を使用し、これらの値を含む列をパーティション列として指定できます。
- パーティションの粒度を選択する際には、データ量、クエリパターン、データ管理の粒度を考慮する必要があります。
- 例1: テーブルの月間データ量が少ない場合、日単位でパーティション化するよりも月単位でパーティション化することで、メタデータの量を減らし、メタデータ管理とスケジューリングのリソース消費を削減できます。
- 例2: テーブルの月間データ量が多く、クエリが特定の日のデータを主に要求する場合、日単位でパーティション化することで、クエリ時にスキャンするデータ量を効果的に減らすことができます。
- 例3: データが日単位で期限切れになる必要がある場合、日単位でパーティション化することをお勧めします。
バケッティング
バケッティング手法は、パーティションを複数のバケットに分割します。バケット内のデータはタブレットと呼ばれます。
サポートされているバケッティング手法は、ランダムバケット法(v3.1以降)とハッシュバケット法です。
-
ランダムバケット法: テーブル作成時やパーティション追加時にバケッティングキーを設定する必要はありません。パーティション内のデータはランダムに異なるバケットに分配されます。
-
ハッシュバケット法: テーブル作成 時やパーティション追加時にバケッティングキーを指定する必要があります。同じパーティション内のデータは、バケッティングキーの値に基づいてバケットに分割され、バケッティングキーの同じ値を持つ行は対応する一意のバケットに分配されます。
バケット数: デフォルトでは、StarRocksは自動的にバケット数を設定します(v2.5.7以降)。バケット数を手動で設定することもできます。詳細については、バケット数の決定を参照してください。
パーティションの作成と管理
パーティションの作成
式に基づくパーティション化(推奨)
注意
v3.1以降、StarRocksの共有データモードは時間関数式をサポートし、列式をサポートしません。
v3.0以降、StarRocksは式 に基づくパーティション化(以前は自動パーティション化として知られていました)をサポートしており、より柔軟で使いやすくなっています。このパーティション化手法は、連続した日付範囲やENUM値に基づいてデータをクエリおよび管理するほとんどのシナリオに適しています。
テーブル作成時にパーティション式(時間関数式または列式)を設定するだけで、StarRocksはデータロード中に自動的にパーティションを作成します。事前に多数のパーティションを手動で作成する必要はなく、動的パーティションプロパティを設定する必要もありません。
レンジパーティション化
レンジパーティション化は、シンプルで連続したデータ、例えば時系列データや連続した数値データを保存するのに適しています。レンジパーティション化は、連続した日付/数値範囲に基づいて頻繁にクエリされるデータに適しています。さらに、特定のケースでは、履歴データを月単位でパーティション化し、最近のデータを日単位でパーティション化する必要があります。
データパーティション列を明示的に定義し、パーティションとパーティション列値の範囲とのマッピング関係を確立する必要があります。データロード中に、StarRocksはデータパーティション列値が属する範囲に基づいてデータを対応するパーティションに割り当てます。
パーティション列のデータ型については、v3.3.0以 前は、レンジパーティション化は日付型と整数型のパーティション列のみをサポートしていました。v3.3.0以降、3つの特定の時間関数をパーティション列として使用できます。パーティションとパーティション列値の範囲とのマッピング関係を明示的に定義する際には、まず特定の時間関数を使用してタイムスタンプや文字列のパーティション列値を日付値に変換し、変換された日付値に基づいてパーティションを分割する必要があります。
- パーティション列の値がタイムスタンプの場合、パーティションを分割する際には、from_unixtimeまたはfrom_unixtime_ms関数を使用してタイムスタンプを日付値に変換する必要があります。from_unixtime関数を使用する場合、パーティション列はINTおよびBIGINT型のみをサポートします。from_unixtime_ms関数を使用する場合、パーティション列はBIGINT型のみをサポートします。
- パーティション列の値が文字列(STRING、VARCHAR、またはCHAR型)の場合、パーティションを分割する際には、str2date関数を使用して文字列を日付値に変換する必要があります。