データパーティションは、テーブル作成ステートメントに基づいて作成される論理オブジェクトであり、テーブルデータを分割および管理するメカニズムです。各テナントは複数のUnitで構成され、ログストリームは一定のルールに従ってこれらのUnitに分散配置されます。これにより、特定のログストリームに属するデータパーティションがどのUnit上に配置されるかが決定します。このセクションでは、データ及びそのトラフィックの分布ルールについて説明します。
OceanBaseデータベースは、通常テーブルとパーティションテーブルをサポートしています。パーティションテーブルはさらに、パーティションテーブルとサブパーティションテーブルに分類され、1つまたは複数のパーティションで構成されます。通常テーブルは1つのパーティションで構成されており、パーティションテーブルの特殊なケースと見なすことができます。OceanBaseデータベースの基本的なパーティション戦略には、範囲 (Range) パーティション、リスト (List) パーティション、ハッシュ (Hash) パーティション、キー (Key) パーティションなどが含まれます。
同一ゾーン構成と異種ゾーン構成
OceanBaseデータベースのV4.x以前のバージョン(V4.2.5を除く、V4.2.5 BP5以降のBPバージョンを含む)では、テナント管理に制限が加えられており、同一テナント内のすべてのゾーンにおいてユニット数が同一であることが求められていました。これが同一ゾーン構成です。
現在のバージョンではこの制限が撤廃され、同一テナント内のすべてのゾーンにおいてユニット数が同一である必要はなくなりました。これにより、テナントの異種ゾーン構成がサポートされるようになりました。
注意
通常、既存のテナントやアップグレードによって移行したテナントは、デフォルトで同一ゾーン構成になっています。異種ゾーン構成を有効にするには、テナントレベルの構成パラメータ zone_deploy_mode の値を hetero(異種ゾーン構成)に変更する必要があります。変更後は、homo(同一ゾーン構成)に戻すことはできません。
同一ゾーン構成と比較して、異種ゾーン構成の主な使用上の違いは以下のとおりです:
ログストリームの分散はユニットグループに束縛されなくなり、各ゾーンのレプリカが対称的なユニット上に限定される必要がなくなりました。均等化アルゴリズムがユニット単位で各ログストリームの分散を制御します。
テナントの各ゾーン内では、各ユニット上のログストリーム数が等しくなります(異なるゾーン間では、ユニット上のログストリーム数が異なる場合があります)。
UNIT_NUMが同じゾーン内では、そのログストリームは同一の方法で集約されます。
テナント内の各リソースプールの
UNIT_NUMは異なる場合がありますが、最大でも2種類の異なるUNIT_NUMしか存在できません。ALTER RESOURCE POOLステートメントを使用して、テナント内の特定のリソースプールのUNIT_NUMを個別に変更し、リソースプール単位でのスケーリングを実現できます。ALTER RESOURCE TENANTステートメントを使用してUNIT_NUMを減らしてスケールインする際、削除のためのUNIT_GROUPの指定はサポートされていません。ログストリームの運用コマンドである
ALTER SYSTEM CREATE LSおよびALTER SYSTEM MODIFY LSを使用する際、UNIT_GROUPパラメータの指定はサポートされていません。
Unit Groupの紹介
テナントの同種ゾーンモードでは、同一テナント内のすべてのゾーンにおいてユニット数が同一である必要があります。システムは各ゾーンのユニットに番号を付与しており、異なるゾーン間で同じ番号(UNIT_GROUP_ID)を持つユニットが1つのUnit Groupを形成します。Unit Groupには以下の特性があります:
各Unit Groupには一意のIDが割り当てられ、システムテナントは
oceanbase.DBA_OB_UNITSビューのUNIT_GROUP_IDフィールドからこのIDを確認できます。1つのログストリームは必ず1つのUnit Groupに属し、そのUnit Group内のユニット上にのみ配置されます。したがって、Unit Group内のすべてのユニットはログストリーム単位で同一のデータパーティションを分散して保持し、それによって一連のデータを定義します。同時に、各ゾーンのサービス能力が同等であることが求められます。
ゾーンごとにテナントのユニット数を個別に設定することはできません。Unit Group単位での全体調整のみ可能です。例えば、テナントの水平スケールアウトのためにユニット数を増やす場合、すべてのゾーンを一斉に拡張する必要があります。同様に、テナントのスケールインが必要な場合も、Unit Group単位でまとめてユニットを削除する必要があります。Unit Groupの仕組みにより、異なるゾーン間でのデータ分布が同種であることが保証されます。
sysテナントでは、oceanbase.DBA_OB_UNITSビューを使用して、すべてのユニットとそれらが属するUnit Groupを照会できます。例:
obclient(root@sys)[oceanbase]> SELECT UNIT_ID, TENANT_ID, UNIT_GROUP_ID, ZONE, SVR_IP, SVR_PORT FROM oceanbase.DBA_OB_UNITS WHERE TENANT_ID = 1004;
実行結果は次のとおりです:
+---------+-----------+---------------+--------------+-------------+----------+
| UNIT_ID | TENANT_ID | UNIT_GROUP_ID | ZONE | SVR_IP | SVR_PORT |
+---------+-----------+---------------+--------------+-------------+----------+
| 1004 | 1004 | 1003 | sa128_obv4_1 | xx.xx.xx.47 | 2882 |
| 1005 | 1004 | 1003 | sa128_obv4_2 | xx.xx.xx.81 | 2882 |
| 1006 | 1004 | 1003 | sa128_obv4_3 | xx.xx.xx.19 | 2882 |
+---------+-----------+---------------+--------------+-------------+----------+
3 rows in set
ログストリームグループの紹介
ログストリームグループの概念は、プライマリゾーンが複数のゾーンに分散している場合に適応するために導入されました。プライマリゾーンが単一のゾーンの場合、テナントのUNIT_LIST内には単一のログストリームを作成するだけで済みます。プライマリゾーンが複数のゾーンの場合、テナントのUNIT_LIST内に複数のログストリームを作成し、サービス能力の水平スケーリングを実現する必要があります。これらのログストリームは同じ分散属性を持ち、それらが共に1つのログストリームグループを形成します。ログストリームグループ内のログストリームの数は、プライマリゾーンのゾーン数に等しくなります。
したがって、1つのログストリームは1つのログストリームグループに属し、変更することはできません。ログストリームグループ内のすべてのログストリームは対応するUNIT_LIST上に分散配置され、ログストリームのリーダーはプライマリゾーン上に分散しています。
ログストリームグループ内のログストリームの数は、テナントのプライマリゾーン構成の変更に応じて動的に変化します。
sys テナントでは、oceanbase.CDB_OB_LS ビューを使用して、クラスタ内のすべてのテナントのログストリームと、それらが属するログストリームグループを確認できます。例:
obclient(root@sys)[oceanbase]> SELECT TENANT_ID, LS_ID, STATUS, PRIMARY_ZONE, LS_GROUP_ID, UNIT_LIST FROM oceanbase.CDB_OB_LS where TENANT_ID=1004;
実行結果は次のとおりです:
+-----------+-------+--------+--------------+-------------+-----------+
| TENANT_ID | LS_ID | STATUS | PRIMARY_ZONE | LS_GROUP_ID | UNIT_LIST |
+-----------+-------+--------+--------------+-------------+-----------+
| 1004 | 1 | NORMAL | z1;z2 | 0 | |
| 1004 | 1001 | NORMAL | z1;z2 | 1001 | 1013,1014 |
| 1004 | 1008 | NORMAL | z1;z2 | 1007 | 1025,1026 |
| 1004 | 1013 | NORMAL | z2;z1 | 1001 | 1013,1014 |
| 1004 | 1014 | NORMAL | z2;z1 | 1007 | 1025,1026 |
+-----------+-------+--------+--------------+-------------+-----------+
5 rows in set
まとめ
本記事で紹介した細かい概念をまとめると以下の通りです。
Unitは物理リソースの抽象化であり、各Unitはノード上の一定の物理リソース(CPU、メモリ、ストレージ容量などのリソース項目)を占有します。Unitはリソーススケジューリングの基本単位であり、同一Zone内の異なるノード間でUnitの配置を調整することで、ノードのロードバランシングやノードの災害復旧を実現できます。
各テナントは複数のUnitで構成されており、テナントのUnit数とPrimary Zoneを設定することで、業務トラフィックを担うUnitの集合を定義します。各Unitは1つのノードに配置されるため、テナント容量の水平スケーリングを容易に実現できます。
ログストリームは、複数のデータパーティションと順序付けられたRedoLogストリームを含む一連のデータを定義します。Paxosプロトコルによりマルチレプリカのログ同期が実現され、レプリカ間のデータ一貫性が保証されることで、データの高可用性が実現されます。ログストリームはトランザクションのコミット単位でもあり、トランザクションの変更が単一のログストリーム内で完了する場合は、1段階の原子的コミットを採用できます。トランザクションの変更が複数のログストリームにまたがる場合は、OceanBaseデータベースが最適化した2段階コミットプロトコルを用いて原子的コミットを完了し、ログストリームは分散トランザクションの参加者となります。ログストリームには位置属性と役割属性があり、ログストリーム内のすべてのデータパーティションはその属性を継承します。
テナントは同種ゾーンモードと異種ゾーンモードをサポートしています。
同種ゾーンモードでは:
システムは各ZoneのUnitに番号を付与し、同じ番号を持つUnitが1つのUnit Groupを形成します。Unit Groupは一連のログストリームを定義し、これらのログストリームはそのUnit GroupのUnit上にのみ配置されます。
ログストリームグループとUnit Groupは一対一で対応しており、各ログストリームグループ内のログストリームの数はPrimary ZoneのZone数によって決定されます。これにより、Primary ZoneのZoneリスト内の各Zoneには、ログストリームグループ内の1つのログストリームのLeaderが配置されることになります。
テナントが
unit_num =2、primary_zone ='Z1,Z2,Z3'に設定されている場合、そのテナントは2つのUnit Group、2つのログストリームグループ、6つのログストリームを定義します。以下の図のようになります。
異種ゾーンモードでは:
システムはUnitの粒度で各ログストリームの配置を制御します。テナントの各Zone内では、各Unit上のログストリームの数は等しくなります(異なるZone間では、Unit上のログストリームの数は異なる場合があります)。
ログストリームグループ内のすべてのログストリームは対応するUNIT_LIST上に配置され、ログストリームのLeaderはPrimary Zone上に分散配置されます。
以下の図のように、テナントが2つのZoneを持ち、
unit_num =1とunit_num =2に設定され、かつprimary_zone ='zone1'の場合、均衡状態ではユーザーログストリームの総数は2となります。そのうちLS1のUNIT_LISTは(UNIT1, UNIT2)、LS2のUNIT_LISTは(UNIT1, UNIT3)となります。図からわかるように、
LS1とLS2はzone1内では同一Unit上に配置されますが、zone2内では異なるUnitに配置されます。これにより、異種ゾーンモードでは、ログストリームの各Zone内でのレプリカの配置方法は異なることが可能であることがわかります。
OceanBaseデータベースは、複数の層面からデータとトラフィックを複数のノードに柔軟に分散配置し、UnitはZone内のノード間で移行することで、ノードのロードバランシングとノードの災害復旧を実現できます。