本記事では、OBKV-HBaseデータベースのオブジェクトの作成と管理について説明します。
注意
データベースオブジェクトを操作する前に、MySQLテナントが作成されていることを確認してください。
データベース
OBKVクラスタは、実際にはMySQLテナントを使用するOceanBaseクラスタです。データベース(Database)とは、データベースオブジェクトの集合であり、権限管理と名前空間の分離に使用されます。
データテーブルを作成する前に、まずMySQLテナント内にデータベースを作成する必要があります。データベースの作成と管理の詳細な操作については、以下を参照してください:
テーブルグループ
テーブルグループ(Table Group)は、一連のテーブルの集合を表す論理的な概念です。デフォルトでは、異なるテーブル間のデータはランダムに分散しており、直接的な関係はありません。テーブルグループを定義することで、一連のテーブルの物理的な配置上の近接性を制御できます。 OBKV-HBaseはHBaseモデルを実装する際、HBaseのテーブルをOceanBaseデータベース内のテーブルグループにマッピングします。例えば、HBaseにhtable1というテーブルがある場合、OceanBaseデータベースでは、htable1のテーブルグループを作成する必要があります。
注意
テーブルグループ内のすべてのテーブルのパーティションルールは一致している必要があります。
データテーブルを作成する前に、対応するテーブルグループを作成する必要があります。
CREATE TABLEGROUP htable1;
テーブルグループの詳細と操作方法については、以下を参照してください:
- テーブルグループについて
- テーブルグループの作成
- テーブルグループ情報の確認
- テーブルのテーブルグループへの追加
- テーブルグループのSHARDINGプロパティの変更
- テーブルグループ内のテーブルの管理
- テーブルグループの削除
- CREATE TABLEGROUP
テーブル
OBKV-HBaseは、HBaseのColumn FamilyをOceanBaseのリレーショナルテーブルにマッピングします。HBaseを使用する前に、データベース内にテーブルグループおよびテーブルを作成しておく必要があります。
テーブル識別フラグ
OBKV-HBaseテーブルにおいて、この機能は主に以下の2つの役割を果たします:
- OBKV-HBaseテーブルタイプを識別する。OBKV-HBaseテーブルである場合、そのテーブルがパーティション分割機能をサポートしているかどうかを識別できます。
- カラムファミリー(Column Family)レベルのTTL機能を有効にする。
注意
テーブル作成時に kv_attributes 設定を追加することを強く推奨します。これにより、システムがOBKVテーブルタイプを正確に識別できます。
OBKV-HBaseタイプの kv_attributes は現在、TimeToLive と MaxVersions の2つの設定パラメータのみをサポートしています。2つのパラメータは任意の順序で設定可能であり、どちらか一方または両方とも設定しないことも可能です。
例:
-- TimeToLiveとMaxVersionsを設定します。これら2つのパラメータは正の整数値のみをサポートします
CREATE TABLE t1$cf1 (
K VARBINARY(1024),
Q VARBINARY(256),
T BIGINT,
V VARBINARY(1048576) NOT NULL,
PRIMARY KEY(K, Q, T))
-- '{"HBase": {xxx}}' この形式は変更できません。HBase/TimeToLive/MaxVersionsは大文字小文字を区別しません
kv_attributes ='{"HBase": {"TimeToLive": 3600, "MaxVersions": 3}}'
PARTITION BY KEY(K) PARTITIONS 97;
-- MaxVersionsのみを設定します
CREATE TABLE t1$cf1 (
K VARBINARY(1024),
Q VARBINARY(256),
T BIGINT,
V VARBINARY(1048576) NOT NULL,
PRIMARY KEY(K, Q, T))
kv_attributes ='{"HBase": {"MaxVersions": 3}}'
PARTITION BY KEY(K) PARTITIONS 97;
-- kv_attributesが空の場合
CREATE TABLE t1$cf1 (
K VARBINARY(1024),
Q VARBINARY(256),
T BIGINT,
V VARBINARY(1048576) NOT NULL,
PRIMARY KEY(K, Q, T))
kv_attributes ='{"HBase": {}}'
PARTITION BY KEY(K) PARTITIONS 97;
通常テーブル
通常テーブルはOBKV-HBaseの最も基本的なデータモデルです。HBaseにhtable1というテーブルがあり、family1というカラムファミリーがあると仮定します。OceanBaseデータベースでは、htable1のテーブルグループと通常テーブルhtable1$family1を作成する必要があります。通常テーブルの命名規則はTableGroupName$FamilyNameであり、htable1のテーブルグループにバインドされます。
注意
OBKV-HBaseのPut、Delete、Get、Scanインターフェースは複数のカラムファミリーをサポートしています。例については、データ操作の例を参照してください。
CREATE TABLEGROUP htable1;
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576) NOT NULL,
PRIMARY KEY(K, Q, T))
TABLEGROUP = htable1
PARTITION BY KEY(K) PARTITIONS 97;
CREATE TABLE htable1$family2 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576) NOT NULL,
PRIMARY KEY(K, Q, T))
TABLEGROUP = htable1
PARTITION BY KEY(K) PARTITIONS 97;
OBKV-HBaseはHBaseのスキーマレス機能と互換性がありますが、OceanBaseデータベースに基づいて実装されたすべてのモデルにはスキーマがあります。上記のテーブル作成ステートメントは、OBKV-HBaseの物理ストレージモデルです。
パラメータ説明:
- htable1 は作成するHBaseテーブル名で、任意に名付けることができます。
- family1、family2 はカラムファミリー名で、任意に名付けることができます。
説明
テーブル名とカラムファミリー名はドル記号($)で結合し、OceanBaseデータベースのテーブル名とします。
- K列はHBaseテーブルのRowkeyを格納します。
- Q列はColumn Qualifierを格納します。
- T列はタイムスタンプバージョンのTimeStampを格納します。これは1970-01-01 UTCから現在までのミリ秒数です。
- V列はvalueを格納し、varbinary型を使用します。最大長は1MBです。長さが足りない場合はlongblob型を使用できますが、longblobを使用すると性能が約10%低下します。
- K、Q、Tが複合主キーを形成し、HBaseモデルのセルを識別します。
注意
列名はK、Q、T、Vとし、変更しないでください。
上記のSQLでテーブルを作成すると、HBaseテーブルの1行の複数列のデータが、リレーショナルテーブルでは隣接する複数行に格納されます。各行はHBaseの1つのセルを表します:<row, column family, column qualifier, timestamp, value>。
時系列テーブル
OBKV-HBaseは時系列テーブルのストレージをサポートしており、時系列のシナリオに適しています。詳細は以下のとおりです:
- 時系列テーブルモデルはK、T、S、V、Gの各列で構成され、列名は変更できません。
- パーティションとサブパーティションをサポートしており、サブパーティションの分割戦略は通常のテーブルモデルと同じです。
制限事項は以下のとおりです:
- 現在、put、get、scan、deleteの各インターフェースのみをサポートしています。各インターフェースには一定の制限があります。詳細は以下のとおりです:
- putインターフェースの制限:
- CellレベルのTTLはサポートされていません。
- 複数のカラムファミリーはサポートされていません。
- getインターフェースの制限:
- filterはサポートされていません。
- 複数のカラムファミリーはサポートされていません。
- maxVersionはサポートされておらず、設定可能ですが無効です。
- isCheckExistenceOnlyはサポートされていません。
- isClosestRowBeforeはサポートされていません。
- Rowkey TTLはサポートされていません。
- scanインターフェースの制限:
- filterはサポートされていません。
- 複数のカラムファミリーはサポートされていません。
- maxVersionはサポートされておらず、設定可能ですが無効です。
- setBatchはサポートされていません。
- setCachingはサポートされていません。
- setMaxResultSizeはサポートされていません。
- setRowOffsetPerColumnFamilyはサポートされていません。
- setCacheBlocksはサポートされていません。
- Rowkey TTLはサポートされていません。
- deleteインターフェースの制限:
- 複数のカラムファミリーはサポートされていません。
- putインターフェースの制限:
時系列テーブルの作成
CREATE TABLEGROUP htable1;
CREATE TABLE `htable1$family1` (
`K` varbinary(1024) NOT NULL,
`T` bigint(20) NOT NULL,
`S` bigint(20) NOT NULL,
`V` json NOT NULL,
`G` bigint(20) GENERATED ALWAYS AS (ABS(T)),
PRIMARY KEY (`K`, `T`, `S`)
) PARTITION BY RANGE COLUMNS(`G`) SUBPARTITION BY KEY(`K`) SUBPARTITIONS 97 (
PARTITION `p0` VALUES LESS THAN (1728921600000),
PARTITION `p1` VALUES LESS THAN (1729008000000),
PARTITION `p2` VALUES LESS THAN (1729094400000),
PARTITION `p3` VALUES LESS THAN MAXVALUE
);
CREATE TABLE `htable1$family2` (
`K` varbinary(1024) NOT NULL,
`T` bigint(20) NOT NULL,
`S` bigint(20) NOT NULL,
`V` json NOT NULL,
`G` bigint(20) GENERATED ALWAYS AS (ABS(T)),
PRIMARY KEY (`K`, `T`, `S`)
) PARTITION BY RANGE COLUMNS(`G`) SUBPARTITION BY KEY(`K`) SUBPARTITIONS 97 (
PARTITION `p0` VALUES LESS THAN (1728921600000),
PARTITION `p1` VALUES LESS THAN (1729008000000),
PARTITION `p2` VALUES LESS THAN (1729094400000),
PARTITION `p3` VALUES LESS THAN MAXVALUE
);
パラメータ説明:
- K列はHBaseテーブルのRowkeyを格納し、パーティションキーとして使用できます。
- T列はタイムスタンプバージョンのTimeStampを格納し、1970年1月1日UTCから現在までのミリ秒数です。
- S列は、同じKとT(タイムスタンプ)に対応する複数の異なる書き込みのシーケンス番号を格納します。通常、このシーケンス番号は書き込み操作のタイムスタンプです。S列はデータ書き込み時に指定する必要はなく、システムが自動的に生成します。
- V列は、複数のQ(Qualify)とV(value)をJSONにエンコードします。
- G列は仮想生成列で、T(タイムスタンプ)の絶対値(ABS)を格納し、時間次元のパーティションキーとして使用できます。
- K、T、Sは組み合わせて主キーを形成します。
注意
列名はK、T、S、V、Gとし、変更しないでください。
LOB
HBaseはKV型のデータベースであり、ユーザーのデータはすべてバイナリ形式にシリアライズされます。データは非常に大きくなる可能性があり、OceanBaseデータベースでは最大512MBまでのラージオブジェクト(LOB)をサポートしています。
ラージオブジェクトのDMLパフォーマンスは一般的に低いため、可能な限りラージオブジェクトの使用は避けることを推奨します。通常の場合、スキーマ定義時にV列には最大1MBのvarbinary型を使用することをお勧めします。ユーザーの実際のシナリオで1MBを超えるラージオブジェクトを扱うことが避けられない場合は、V列をlongblob型に定義することができます。
create table htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V longblob NOT NULL,
primary key(K, Q, T))
TABLEGROUP = htable1
partition by key(K) partitions 97;
インデックス
テーブル作成後、テーブルの1つまたは複数の列にインデックスを作成することで、テーブル上のステートメントの実行速度を向上させることができます。インデックスを適切に使用することで、物理I/Oまたは論理I/Oを削減できます。
OceanBaseデータベースは、グローバルインデックスとローカルインデックス、一意インデックスと非一意インデックスなどをサポートしています。
注意
OBKV-HBaseは現在、セカンダリインデックスをサポートしていません。
インデックスの種類と使用方法の詳細については、以下を参照してください:
パーティショニング
上記のテーブル作成プロセスにはパーティショニング方式が含まれていないため、作成されるテーブルは非パーティションテーブルであり、データ量が非常に少ないシナリオにのみ適用されます。一般的にHBaseの業務テーブルではデータ量が多いため、パーティションテーブルを作成する必要があります。OBKV-HBaseはサブパーティションとさまざまなパーティショニング戦略をサポートしており、現在はRangeパーティショニングとKeyパーティショニングをサポートしています。
1次パーティションでは、1種類のデータ配分方法のみを使用できます。例えば、Rangeパーティショニングのみを使用します。
サブパーティションを行う際、テーブルはまず1つのデータ配分方法でパーティション化され、その後2番目のデータ配分方法を使用して各パーティションをさらにサブパーティションに分割します。サポートされているサブパーティショニング戦略は以下の通りです:
- T列に基づいて1次Rangeパーティショニングを行い、その後K列に基づいて2次Keyパーティショニングを行います。
- K列に基づいて1次Keyパーティショニングを行い、その後T列に基づいて2次Rangeパーティショニングを行います。
現在、自動パーティション分割をサポートしているのは、1次パーティションのRange/Range Columnsパーティショニングのみです。このパーティショニング方式は範囲スキャンのシナリオに適しており、通常のRangeパーティショニングにはない、データ量に応じて自動的に分割し、データ量を均等に分散させる機能も備えています。詳細については、OBKV-HBaseの自動パーティション分割を参照してください。サブパーティションは現在、自動パーティション分割をサポートしていません。
パーティショニングの詳細については、パーティションタイプを参照してください。
注意
1つのテーブルグループ内のすべてのテーブルのパーティショニングルールは一致している必要があります。
1レベルのパーティション戦略
1レベルのパーティションを使用する場合は、以下のプロセスを参考に、どのようなパーティショニング方法を使用するかを決定できます。
Keyパーティション
業務でScanによる範囲スキャンを使用しない場合、またはGetインターフェースのみが必要な場合は、Keyパーティションを使用します。パーティション数は奇数である必要があり、素数が望ましいです。推奨値は97、193、389などです。Keyパーティションの顕著な利点はデータ分布が均一であり、一般的にデータの偏りやホットスポットが発生しないことです。例:
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576) NOT NULL,
PRIMARY KEY(K, Q, T))
TABLEGROUP = htable1
PARTITION BY KEY(K) PARTITIONS 97;
仮想列とKeyパーティションの組み合わせ
業務でScanの使用が必要だが、スキャン範囲が常にRowkeyの固定長のプレフィックスである場合(プレフィックススキャン)、Kに仮想列を定義し、その仮想列に対してKeyパーティションを行います。この方法により、毎回のスキャンが1つのパーティションのみに関与することを保証できます。プレフィックスデータに偏りがない限り、このパーティショニング方法はホットスポットの回避にも役立ちます。例:
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576),
K_PREFIX varbinary(1024) GENERATED ALWAYS AS (substring(K, 1, 4)),
PRIMARY KEY(K, Q, T))
TABLEGROUP = htable1
PARTITION BY KEY(K_PREFIX) PARTITIONS 97;
パラメータ説明:関数substring(K, 1, 4)は、K(つまりHBaseテーブルのRowkey)の最初の4バイトをサブ文字列として取得することを意味します。ここでの「4」は、業務のRowkeyの特性に応じて、プレフィックスの長さに置き換える必要があります。
説明
現在、仮想列の構築にはsubstringのみがサポートされています。
Rangeパーティション
プレフィックススキャンとGetだけでなく、Rangeスキャンも必要な場合は、Rangeパーティションを設定する必要があります。Rowkeyの分布を事前に推定またはサンプリングし、Rangeパーティションの分割点を選定することをお勧めします。予測が不適切な場合、このパーティショニング方法はデータの偏りやホットスポットを容易に引き起こす可能性があるため、可能な限り避けることが望ましいです。例:
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576),
PRIMARY KEY(K, Q, T)
)
TABLEGROUP = htable1
PARTITION BY RANGE columns (K)
(
PARTITION p0 VALUES LESS THAN ('a'),
PARTITION p1 VALUES LESS THAN ('w'),
PARTITION p2 VALUES LESS THAN MAXVALUE);
パラメータ説明: 'a'と'w'によって、全体のRowkey値の値域空間を3つのセグメントに分割します。
サブパーティショニング戦略
OBKV-HBaseは、K列/T列に基づくサブパーティショニング戦略をサポートしています。
注意点
現在のOBKV-HBaseのサブパーティションには、以下の制限があります:
- 期限切れデータ削除(TTL)機能はMaxVersionsおよびRowkey TTLをサポートしていません。
Range + Key
OBKV-HBaseは、T列に基づくパーティションの範囲分割と、K列に基づくサブパーティションのキー分割を組み合わせた戦略をサポートします。この戦略では、まず時間次元に基づいてデータをパーティションに分散し、その後キーに基づいてさらにデータを分割します。例:
CREATE TABLE `htable1$cf1` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
`G` bigint(20) GENERATED ALWAYS AS (ABS(T)),
PRIMARY KEY (`K`, `Q`, `T`)
) PARTITION BY RANGE COLUMNS(`G`) SUBPARTITION BY KEY(`K`) SUBPARTITIONS 97 (
PARTITION `p0` VALUES LESS THAN (1728921600000),
PARTITION `p1` VALUES LESS THAN (1729008000000),
PARTITION `p2` VALUES LESS THAN (1729094400000),
PARTITION `p3` VALUES LESS THAN MAXVALUE
);
CREATE TABLE `htable1$cf2` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
`G` bigint(20) GENERATED ALWAYS AS (ABS(T)),
K_PREFIX varbinary(1024) generated always as (substring(`K`, 1, 4)),
PRIMARY KEY (`K`, `Q`, `T`)
) PARTITION BY RANGE COLUMNS(`G`) SUBPARTITION BY KEY(`K_PREFIX`) SUBPARTITIONS 97 (
PARTITION `p0` VALUES LESS THAN (1728921600000),
PARTITION `p1` VALUES LESS THAN (1729008000000),
PARTITION `p2` VALUES LESS THAN (1729094400000),
PARTITION `p3` VALUES LESS THAN MAXVALUE
);
Key + Range
OBKV-HBaseは、K列に基づいて一次Keyパーティションを行い、さらにT列に基づいて二次Rangeパーティションを行う戦略をサポートしています。この戦略では、まずKeyに基づいてデータを一次パーティションに分散し、その後時間軸に沿ってデータを階層化します。例:
CREATE TABLE `htable1$cf3` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
`G` bigint(20) GENERATED ALWAYS AS (ABS(T)),
PRIMARY KEY (`K`, `Q`, `T`)
) PARTITION BY KEY(`K`) SUBPARTITION BY RANGE COLUMNS(`G`) SUBPARTITION TEMPLATE (
SUBPARTITION `p0` VALUES LESS THAN (1728921600000),
SUBPARTITION `p1` VALUES LESS THAN (1729008000000),
SUBPARTITION `p2` VALUES LESS THAN (1729094400000),
SUBPARTITION `p3` VALUES LESS THAN MAXVALUE
) PARTITIONS 97;
CREATE TABLE `htable1$cf4` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
`G` bigint(20) GENERATED ALWAYS AS (ABS(T)),
K_PREFIX varbinary(1024) generated always as (substring(`K`, 1, 4)),
PRIMARY KEY (`K`, `Q`, `T`)
) PARTITION BY KEY(`K_PREFIX`) SUBPARTITION BY RANGE COLUMNS(`G`) SUBPARTITION TEMPLATE (
SUBPARTITION `p0` VALUES LESS THAN (1728921600000),
SUBPARTITION `p1` VALUES LESS THAN (1729008000000),
SUBPARTITION `p2` VALUES LESS THAN (1729094400000),
SUBPARTITION `p3` VALUES LESS THAN MAXVALUE
) PARTITIONS 97;
パーティション管理
パーティションの詳細な操作手順については、以下を参照してください:
主キーの設計
KEYパーティションのパーティションキー設計
OBKV-HBaseにおいて、パーティションキーの設計はパフォーマンス向上に非常に重要です。ご存知の通り、分散システムでは、分散トランザクションのACIDや分散読み取りにおけるスナップショット整合性を保証するためには、追加のパフォーマンスコストが伴います。これが、多くのオープンソースNoSQLデータベースがクロス行トランザクションをサポートせず、グローバルなスナップショット整合性読み取りも提供しない理由です。
パフォーマンス上の理由から、OBKV-HBaseは分散トランザクションやグローバルな一貫性スナップショット読み取りをサポートしていません。しかし、ノードレベルのトランザクション(オープンソースHBaseは単一行トランザクションのみサポート)およびノードレベルの一貫性スナップショット読み取りをサポートしています。パーティションキーの設計により、業務リクエストを一つのパーティション内に限定できるため、拡張性の要件を満たしつつ、単一マシンと同等のパフォーマンスと一貫性を得ることが可能です。
パーティションキーは主キーのプレフィックスです。例を挙げると、ユーザーメッセージシステムの場合は次のとおりです:
- 各ユーザーには固定長64ビットの一意のID、useridがあります。
- 一つのメッセージには64ビットのメッセージID、msgidがあります。
主キーはuserid | msgidとして設計され、パーティションキーは以下のように定義されます:
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576),
K_PREFIX varbinary(1024) GENERATED ALWAYS AS (substring(K, 1, 64)),
PRIMARY KEY(K, Q, T))
TABLEGROUP = htable1
PARTITION BY KEY(K_PREFIX) PARTITIONS 97;
上記のように、substringを用いてK列の主キーから固定長のパーティションキーを抽出します。一つのuseridに対するすべてのscan/get/put/Batchなどの操作は、一つのパーティションにアクセスします。単一パーティション内では、OBKV-HBaseはクロス行トランザクションや一貫性読み取りを保証します。
KEYパーティションのパーティション数に関する考慮事項
なぜパーティション数に注目するのか
- パーティション数の調整はDDLであり、再調整には一定のコストがかかります。
- パーティション数が少なすぎるのは適切ではありません。例えば、DBの均衡アルゴリズムは、二つのノード間のパーティション数の差が1を超えないように保証します。3ノード、7パーティションの場合、各ノードのパーティション数は<3,2,2>となり、ノード間のパーティションの不均衡度は(3-2)/3 = 33%となります。データ偏りがないと仮定すると、パーティション数はデータのストレージ量およびアクセス量にほぼ比例し、パーティションの不均衡度は各ノードのリソース使用量の不均衡にも反映されます。
- パーティション数が多すぎるのも適切ではありません。例えば、パーティションがminiDBのようになり、一つのDBの中に複数のminiDBが存在する状態になります。各miniDBは独自にストレージ空間とデータアクセスを管理するため、まずminiDBが多すぎるとストレージ領域を十分に共有できなくなります。また、Scanが複数のDBにまたがる可能性があり、一定のパフォーマンス損失が発生します。業務上のBatch操作を直接ストレージに転送してパフォーマンスを最大限に最適化することも困難になります。
パーティション数がパフォーマンスに与える影響
- 一般的に、パーティションのサイズがパフォーマンスに与える影響は大きくありません。
- 主に影響を受けるのは、パーティションを粒度とするメジャーコンパクション/移行/バックアップなどのタスクです。パーティションが大きすぎると、単一タスクの実行時間が長くなり、ストレージ要件も高くなります。
パーティション数の選定方法
- 容量を考慮する場合、単一パーティション単一レプリカあたりのデータ量は、できれば100GBを超えないようにすることを推奨します。パーティション数を選定する際は、可能な限り23、59、97、193、389、997などの素数を選択します。例えば、3レプリカ、24Tのストレージ容量を使用する場合、1レプリカあたりの総データ量は8Tとなり、少なくとも80個のパーティションが必要と推定されます。上記の推奨値に基づき、97個のパーティションを選択します。
- パーティション数の変更はDDLであり、一定のオーバーヘッドが発生します。パーティション数を設計する際は、頻繁な変更を避け、事前に計画的なパーティション設計を行うことが重要です。現在のストレージ容量が24Tだが、将来1年以内に50Tに拡大する見込みである場合、初期設計時には50Tを基準に、できれば193個のパーティション数を選択するのが望ましいです。
- パーティション数は大きく設定しすぎない方が良く、最大でも997を超えないことを推奨します。
パーティション間のデータ偏りの判断方法
KEYパーティションでは、MurmurHashでパーティションキーをハッシュ化し、対応するパーティションにデータを振り分けます。例えば、1億件のうち1,000万件が同じパーティションキーを持つような極端な場合は、データに大きな偏りが生じます。一方、1億件のうち、一部のパーティションキーに数千件ずつのデータが属する程度であれば、通常は大きな偏りは生じません。十分な件数がある場合、ハッシュによって各パーティションのデータ量がおおむね均等になるためです。
主キーの一般的な設計上の考慮事項
主キーの分散
分散システムにおいて、主キーの分散は非常に重要です。リクエストをクラスタ内の各マシンに均等に分散させることで、分散システム全体の計算能力を最大限に活用できます。
- Rangeパーティションを選択する場合、主キープレフィックスに自動インクリメント列や時系列列を使用しない方が良いでしょう。例えば、メッセージシステムの主キーをtimestamp | msgidと設計するのは良い設計ではありません。これにより、書き込みリクエストがほぼすべて単一のマシンに集中してしまいます。
- 値の種類が多いプレフィックスを主キープレフィックスとして使用することは、可能な限り避けてください。例えば、メッセージシステムの主キーをmsgtype | msgidと設計するのは良い設計ではありません(msgtypeの列挙数が少ないため)。これも読み書きリクエストがほぼすべて単一のマシンに集中してしまう原因となります。
主キーの設計
- 主キーの長さは長くしすぎない方が良く、1Kを超えないようにするのが望ましいです。主キーが長すぎると、冗長なストレージが発生し、アクセス性能が不必要に低下します。特に、主キーにラージオブジェクト型を使用することはできません。
- Rangeパーティションを使用する場合でも、主キープレフィックスが自動インクリメント列や時系列列である必要がある場合、データアクセスのホットスポットが発生します。この場合、自動インクリメントされた主キープレフィックスをHash処理したものを新しい主キープレフィックスとして使用することを検討できます。例えば、優れていない主キー設計であるtimestamp | msgidの場合、主キーをhashvalueoftime | timestamp | msgidに変更することが考えられます。Keyパーティションを使用する場合、KeyパーティションはパーティションキーをHash処理して各パーティションに分散させるため、プレフィックスのHashを抽出する必要はありません。
関連ドキュメント
- OceanBaseデータベースオブジェクトの詳細については、データベースオブジェクトの紹介を参照してください。
- OceanBaseデータベースオブジェクトの操作に関するガイドについては、データベースオブジェクト管理を参照してください。
- OceanBaseデータベースオブジェクトの命名規則については、データベースオブジェクトの命名規則を参照してください。