HBaseモデル
以下では、HBaseの概念モデルを説明します。HBaseモデルは、リレーショナルモデルと多くの点で異なります。
Namespace
HBaseはnamespaceを使用してテーブルを論理的に分割します。これはリレーショナルデータベースのdatabaseの概念に似ています。異なるnamespace下で同名のテーブルを作成することができます。OBKV-HBaseは、namespaceへのアクセスを対応するdatabaseへのアクセスに変換します。ただし、対応するdatabaseを事前に作成しておく必要があります。
Table
リレーショナルデータベースのテーブルと同様です。
Row
リレーショナルデータベースの行にはいくつか類似点がありますが、概念モデルには違いがあります。主な違いは以下の通りです:
- リレーショナルデータベースでは、1つのrowkeyがデータベース内の1行の物理データに対応し、各行のschemaは同じです。HBaseはschemaレスなデータベースであり、各行データのschemaは全く関連性がない場合もあります。
- HBaseはユーザーが意識できるマルチバージョンをサポートしており、ユーザーはデータをクエリする際に、取得したい行のバージョンを指定できます。 以下の例では、K列にHBaseの主キーが格納されています。HBaseモデルでは、主キーがdefaultKey1の1行が、OBKVのストレージでは5行に分解されています。つまり、defaultKey1のこの1行には5行(OBKVの行)分のデータが格納されており、この行には4列があります。そのうちdefaultColumn3のデータは2行あり、それぞれが2つのデータバージョンに対応しています。
+--------------+----------------+----------------+--------------+
| K | Q | T | V |
+--------------+----------------+----------------+--------------+
| defaultKey1 | defaultColumn3 | -1715698988310 | defaultValue |
| defaultKey1 | defaultColumn6 | -1715698988310 | defaultValue |
| defaultKey1 | defaultColumn9 | -1715698988310 | defaultValue |
| defaultKey1 | defaultColumn1 | -1715698965577 | defaultValue |
| defaultKey1 | defaultColumn3 | -1715698965577 | defaultValue |
+--------------+----------------+----------------+--------------+
Column Family
リレーショナルデータベースにはColumn Familyの概念はありません(一部のリレーショナルデータベースの垂直パーティショニングの概念に近いです)。Column Familyは列の集合を指し、1つのColumn Family内のすべての列の値は、物理的にまとめて保存されます。 Column Familyの設計はパフォーマンスを考慮しています。HBaseのモデルは無限に広いテーブルをサポートしているため、頻繁にアクセスされる値をColumn Familyに集約して保存することで、パフォーマンスを大幅に向上させることができます。
Column Qualifier
リレーショナルデータベースは固定のスキーマを持ち、各行の列数や同じ位置にある列の型などがすべて同じです。HBaseはスキーマレスなデータベースであり、列の概念はありますが、各行の列数や列の型などは完全に異なり得ます。 以下の例では、2行のHBaseデータを挿入しています。そのうち、defaultKey1 の行には3つの関連列があり、defaultKey11 の行には2つの関連列があります。これらをOceanBaseデータベースに書き込んだ後の対応するデータは以下のとおりです:
+--------------+----------------+----------------+--------------+
| K | Q | T | V |
+--------------+----------------+----------------+--------------+
| defaultKey1 | defaultColumn3 | -1715698988310 | defaultValue |
| defaultKey1 | defaultColumn6 | -1715698988310 | defaultValue |
| defaultKey1 | defaultColumn9 | -1715698988310 | defaultValue |
| defaultKey11 | defaultColumn1 | -1715698965577 | defaultValue |
| defaultKey11 | defaultColumn2 | -1715698965577 | defaultValue |
+--------------+----------------+----------------+--------------+
TimeStamp
HBaseに格納される各Valueにはバージョンがあり、このバージョンはTimestampによって区別されます。Timestampはデータを書き込む際に明示的に指定することができますが、指定しない場合、デフォルト値はストレージエンジンへの挿入時のタイムスタンプとなります。
以下の例では、T列がTimestampを表します。OBKV-HBaseのモデル層が処理する際、新規挿入データを前面に配置する観点から、Timestampの負の値を格納します。
+-------------+----------------+----------------+--------------+
| K | Q | T | V |
+-------------+----------------+----------------+--------------+
| defaultKey1 | defaultColumn1 | -1715672642104 | defaultValue |
Cell
HBaseでは、特定バージョンの値を1つのセル(Cell)として扱います。セルはHBaseの基本的なデータ格納単位です。テーブル(Table)、行キー(Row Key)、カラムファミリー(Column Family)、列修飾子(Column Qualifier)、タイムスタンプ(Timestamp)によって値(Value)を特定します。
上記の5つの要素に基づき、HBase内の各Cellは一意に決定されます。これは、これら5つの情報によってHBase内の特定のデータユニットを正確に特定できることを意味します。例えば、あるテーブル名、行の主キー、カラムファミリー、列名、タイムスタンプを知っていれば、そのCellの具体的な値を取得できます。
上述の例のように、OBKV-HBaseに保存される各行はHBaseの1つのCellです。
OBKV-HBaseデータモデル
データベースオブジェクトの種類
OBKV-HBaseクラスタは、実際にはMySQLテナントモードのOceanBaseクラスタです。
OceanBaseデータベースのMySQLモードにおけるデータベースオブジェクトには、主にデータベース(Database)、テーブル(Table)、ビュー(View)、インデックス(Index)、パーティション(Partition)などが含まれます。
MySQLモードのユーザー(User)は、関連する権限を付与された後、データベースに接続し、データベースオブジェクトにアクセスまたは操作を実行できます。データベース(Database)はデータベースオブジェクトの集合であり、権限管理と名前空間の分離に使用されます。
OceanBaseデータベースのMySQLモードにおけるデータベースオブジェクトの詳細情報は、次の表のとおりです。
オブジェクトタイプ |
説明 |
|---|---|
| データベース(Database) | 権限管理と名前空間の分離に使用されるデータベースオブジェクトの集合です。 |
| テーブル(Table) | データベース内で最も基本的なストレージ単位であり、テーブル内のデータは行と列によって整理されています。 |
| インデックス(Index) | インデックスは、データベーステーブルの1列または複数列の値をソートする構造であり、インデックスを使用することでデータベーステーブル内の指定情報に迅速にアクセスできます。例えば、特定の従業員の姓でその人を検索したい場合、テーブル内のすべての行を検索するのと比較して、インデックスは情報をより迅速に取得するのに役立ちます。 |
| パーティション(Partition) | OceanBaseデータベースでは、通常のテーブルのデータを一定のルールに従って複数のブロックに分割し、同一ブロック内のデータを物理的にまとめて保存することができます。このようにブロックに分割されたテーブルはパーティションテーブルと呼ばれます。OracleのPartitionの概念と同じで、OceanBaseデータベースでは水平パーティションのみが存在し、テーブルの各パーティションはレコードの一部を含みます。行データとパーティションのマッピング関係によって、Hashパーティション、Rangeパーティション(範囲)、Listパーティションなどに分類されます。各パーティションはさらに異なる次元で複数のパーティションに細分化することができ、これをサブパーティションと呼びます。例えば、取引記録テーブルをユーザーIDに基づいて複数のHashパーティションに分割し、各一次Hashパーティションを取引時間に基づいてさらに複数の二次Rangeパーティションに分割することができます。 |
| テーブルグループ(TableGroup) | 一連のテーブルの集合を表す論理的概念です。デフォルトでは、異なるテーブル間のデータはランダムに分散しており、直接的な関連性はありません。テーブルグループを定義することで、一連のテーブルの物理的な配置における隣接関係を制御できます。 |
OBKV-HBaseデータモデルの実装
以下の簡単なテーブル作成ステートメントを例に、OBKV-HBaseデータモデルの実装を説明します。
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;
OBKV-HBaseはHBaseモデルを実装する際、以下のマッピング戦略を採用しています:
- OBKV-HBaseは、HBaseのテーブルをOceanBaseのテーブルグループにマッピングします。
- OBKV-HBaseは、HBaseのColumn FamilyをOceanBaseの通常のテーブルにマッピングします。
命名規則として、HBaseにhtable1というテーブルがあり、family1というカラムファミリーがある場合、OceanBaseデータベースではhtable1のテーブルグループを作成し、通常のテーブルhtable1$family1を作成して、htable1のテーブルグループにバインドする必要があります。通常のテーブルの命名規則はTableGroupName$ColumnFamilyNameです。
また、OBKV-HBaseはHBaseのSchemaless機能に対応していますが、OceanBaseを基盤として実装されたいかなるモデルもスキーマを持ちます。上記のテーブル作成ステートメントが、OBKV-HBaseの物理ストレージモデルです。
具体的には:
- `htable1`は作成されるOBKV-HBaseテーブル名です。
- `family1`はカラムファミリー名で、任意に命名できます。
説明
テーブル名とカラムファミリー名はドル記号($)で結ばれ、OceanBaseデータベースのテーブル名となります。
- K列はOBKV-HBaseテーブルのrowkeyを格納します。
- Q列はColumn Qualifierを格納します。
- T列はタイムスタンプ版のTimeStampを格納し、これは1970年1月1日UTCから現在までのミリ秒数です。
- V列はデータ値を格納し、VARBINARY型を使用します。最大長は1MBですが、長さが足りない場合はLONGBLOB型を使用できます。
- K、Q、Tが組み合わさって主キーを形成し、HBaseモデルの1つのCellを識別します。
- `TABLEGROUP = htable1`は、そのテーブルがhtable1テーブルグループに属することを示します。
注意
- OBKV-HBaseはHBaseモデルでのColumn FamilyレベルおよびCellレベルのTTLをサポートしています。詳細については、OBKV-HBaseの期限切れデータ削除を参照してください。
- テーブル作成時の命名は、K、Q、T、V、TTLを使用する必要があります(CellレベルTTLを有効にする場合はTTL列を作成する必要があります)。変更はできません。
上記のSQLでテーブルを作成すると、HBaseテーブルの1行分の複数列のデータが、関係テーブルでは隣接する複数行に格納されます。各行がHBaseの1つのcellを表します:<row, column family, column qualifier, timestamp, value>。
HBaseモデルの適用シナリオ
一部のシナリオでは、HBaseモデルはリレーショナルモデルよりも大きな利点があります。
スキーマレス
従来のリレーショナルデータベースではスキーマを定義する必要があり、定義後に変更は可能ですが、ほとんどのシナリオではデータの再構成が必要となり、データベースにとっては比較的重い操作です。
HBaseはスキーマレスなデータベースであり、主キー・列名・列値を格納することでスキーマから切り離されており、各行データが同じ列定義を持つ必要はありません。
例えば、ある業務の上流にHiveがあり、Hiveのオフライン計算後のデータをHBaseデータベースに書き込む場合があります。業務がMySQLなどのリレーショナルデータベースを選択しなかった主な理由は、Hiveタスクのスキーマが動的に変化し、毎日MySQLにDDLを実行することができないためです。
部分更新
従来のリレーショナルデータベースでは、更新を行う際には、まずデータベース内の既存レコードをクエリしてから更新できます。つまり、更新のたびに少なくとも1回のデータベース読み取りと1回の書き込み操作が必要です。
HBaseでは、行データを複数のCellに分割して独立して格納し、PUTセマンティクス(上書き)のインターフェースを提供しています。更新シナリオでは、Cellレベルでの更新が可能であり、更新時のクエリも回避できます。
例えば、金融リスク管理業務では、毎日大規模なデータ計算後に、一部ユーザーの一部の特徴を変更します。HBaseを利用すれば、更新後のCellをHBaseにPutするだけで、極めて高い更新パフォーマンスを得ることができます。LSM-Treeベースのデータベースは、書き込みに適したアーキテクチャです。
ワイドテーブル・スパースカラム
例えば、あるAPPがユーザーのプロファイリングを行う場合、ユーザープロファイルの次元は非常に多く、またその次元は頻繁に変更される可能性があります。また、ユーザープロファイリングのシナリオでは、一般的に特定のユーザーはごく少数のプロファイル次元にのみマッチします。これをリレーショナルモデルで記述すると、典型的なワイドテーブル・スパースカラムのシナリオとなります。従来のリレーショナルデータベースは強いスキーマを持ち、ワイドテーブル・スパースカラムを効率的に処理することはできません。例えば、各行データは非常に多くの列値を維持する必要があり、その列に値がなくても空のマーカーなどを維持する必要があります。
ワイドテーブル・スパースカラムはHBaseに非常に適したシナリオであり、HBaseは保存時には非空の列のみを保存し、スキーマの制約がないため、保存・書き込み・クエリが非常に効率的です。
マルチバージョン
特定のシナリオでは、マルチバージョンが非常に役立ちます。例えば、リスク管理シナリオでは、ユーザーの直近数回のログイン・消費などの履歴を記録する必要があります。業務では、特定ユーザーの複数バージョンの履歴を抽出して意思決定を行うことがよくありますが、同時に維持するマルチバージョンの数は限られています。HBaseでは、クエリ時に取得するバージョン数を指定し、テーブル作成時に維持するバージョン数を指定するだけで済みます。しかし、リレーショナルデータベースでは、業務がテーブルスキーマの設計(例えばタイムスタンプ列の追加)を通じてマルチバージョンを実現する必要がありますが、特定数のバージョンを維持することは、リレーショナルデータベースでは比較的難しい課題です。
TTL
HBaseは、ネイティブのColumn FamilyレベルおよびCellレベルでTTLをサポートしており、データベースカーネル内でデータの期限切れ削除をサポートしています。そのため、リソース利用率と削除効率が共に高くなっています。リレーショナルデータベースでも外部コンポーネントを利用することでTTLを実現できますが、期限切れデータをアプリケーションから見えなくすることや、削除が本番環境の処理に与える影響を抑えることが難しく、外部コンポーネントは業務システムに余分なリソース消費と業務アーキテクチャの複雑さをもたらします。