元ドキュメント: 同期テーブル
同期テーブル
概要
同期テーブルは特殊なテーブルです。データが書き込まれる際、その変更は複数の Follower レプリカに強同期されてからクライアントに応答が返されます。そのため、複数の Follower レプリカが強一貫性読み取りサービスを提供できます。書き込み頻度が低く、読み取り操作が多く、読み取り操作の遅延要件が厳しいワークロードに適しています。
現在、同期テーブルはブロードキャストテーブルの形式で外部にサービスを提供しています。ユーザーのすべての同期テーブルの Region は、特殊なブロードキャスト同期 RG(Replication Group)を共有します。この RG はユーザーが最初の同期テーブルを作成した際に生成され、以降のユーザーの同期テーブル Region もこの同期 RG にスケジューリングされます。ブロードキャスト同期 RG はシステム内の各ノードにレプリカを1つずつ配置し、各 Follower は定期的に Leader にリースを申請します。Leader で書き込みが発生すると、有効なリースを保持するすべての Follower に変更が強同期されるまで待機してから応答を返します。読み取りリクエストがある場合、同期テーブルはまずローカル読み取りを試み、ローカル読み取りが失敗した場合は Leader から読み取ります。
動作原理
通常のトランザクション書き込みフロー
- データはトランザクションのコミット前にトランザクションコンテキストの write batch に一時的に格納されます。
- コミットフェーズに入ると、Leader は write batch のデータをディスクに書き込んでトランザクションログを形成し、Raft プロトコルを通じて各レプリカ所在ノードに同期します。
- 多数派を形成した後、Leader はデータをまず RocksDB に書き込んでからクライアントに応答を返します。Follower レプリカは Raft ログを再生して RocksDB に書き込みます。
同期テーブルのトランザクション書き込みフロー
- 実行フェーズでは、同期テーブルのトランザクションは通常のトランザクションと同様にデータをトランザクションコンテキストの write batch に一時格納します。
- コミットフェーズに入ると、Leader は同様に Raft ログの形式でデータを Follower に同期します。
- 通常のトランザクションとは異なり、同期テーブルでは有効なすべての Follower がログを返してからクライアントに応答を返す必要があります。
具体的には、分散トランザクションにおいて Leader が Follower に強同期を行うロジックは以下の通りです:
- redo ログと prepare ログをコミットします。
- リースが有効なすべてのレプリカを取得します。
- 各レプリカが prepare ログを再生済みかどうかを確認します。
- すべてのレプリカが prepare ログを再生済みの場合、コーディネーターに応答します。
- そうでない場合、ステップ2に戻ってリトライします。
Follower が読み取りリクエストを受信した場合、直接エラーを返すのではなく、可読性チェック(リースチェックなど)を行う必要があります。可読性チェックを通過した後の読み取りロジックは Leader と同一で、まずロック情報を確認して prepare 状態のトランザクションが自身をブロックする必要があるかを確認し、なければ読み取りバージョン番号に基づいて RocksDB から直接読み取ります。
Leader は有効な Follower リストを維持する必要があり、コミットフェーズではすべての有効な Follower に対して強同期を行います。この有効な Follower リストはリースメカニズムによって維持されます。Follower は定期的に Leader にリースを申請し、Leader がリース申請を受け入れてリースを付与する場合、そのノードを有効な Follower リストに追加し、Raft ログを通じてリースログを同期します。その後の Leader でのすべての変更はこの Follower に同期される必要があります。Follower がリースを長期間更新せずリースが期限切れになった場合、Leader はその Follower を有効リストから除外し、以降はその Follower への強同期を行いません。Follower はリース有効期間内のみ強一貫性読み取りサービスを外部に提供でき、リース期限切れ後は強一貫性読み取りサービスの提供が禁止されます。このメカニズムにより、Follower 側のリースが先に期限切れになり(Follower が先に強一貫性読み取りサービスを停止)、Leader 側のリースが後に期限切れになる(Leader が後に強同期を停止する)ことが保証されます。
使用上の制限
- 現在、同期テーブルはブロードキャストテーブルの形式で外部にサービスを提供しています。同期テーブルを使用するにはブロードキャスト同期テーブルを作成する必要があります。
- いずれか1つの Follower レプリカの障害により、書き込みリクエストが1リース分の時間遅延する可能性があります。
- 読み取りリクエストのルーティングポリシーはローカル優先です。ローカルアクセスが失敗した場合は Leader にアクセスします。
- 現在、同期テーブルの属性変換はサポートされていません。同期テーブルから非同期テーブルへの変更、および非同期テーブルから同期テーブルへの変更はできません。
- 同期テーブルはパーティションテーブルにできません。
- ブロードキャスト同期ログストリームは一度作成されると、ユーザーがすべての同期テーブルを削除しても破棄されません。
- レプリカ数が多すぎると書き込みリクエストのパフォーマンスが低下します。
使用方法
同期テーブルは読み取りが多く書き込みが少ない、かつ遅延に敏感な業務テーブルに適しています。例えば、システムパラメータ、グローバル設定テーブル、データウェアハウスのディメンションテーブル(TPC-C の item テーブルなど)が該当します。
構文
CREATE TABLE table_name (
column_definitions
) sync_level = node(all) distribution = node(all);同期テーブルの読み書きアクセス構文は通常のテーブルと同じです。ただし読み取り時には、実際にアクセスするノードは接続先に依存します。具体的には、TDSQL Boundless は接続先のローカルノードにある同期テーブルのレプリカに優先的にアクセスし、ローカルノードが読み取り不可(例:リース期限切れ)の場合のみ Leader ノードへのアクセスにフォールバックします。
例
tdsql [demo]> CREATE TABLE test_sync_table(
c1 INT PRIMARY KEY,
c2 INT,
c3 INT,
INDEX idx(c2)
) sync_level = node(all) distribution = node(all);
Query OK, 0 rows affected (2.90 sec)関連パラメータ
| パラメータ名 | デフォルト値 | 説明 |
|---|---|---|
tdstore_sync_table_max_allowed_log_lag | 1024 | Leader が Follower にリースを付与するかどうかを決定する際に、Follower のログ再生進捗を考慮します。Follower の現在の再生進捗が Leader よりもこのパラメータ値以上遅れている場合、Leader はリースを付与しません |
tdstore_sync_table_lease_interval_ms | 2000 | Follower が Leader にリースを申請する周期 |
tdstore_sync_table_log_interval_ms | 1000 | Leader が Raft リースログを同期する周期 |
tdstore_sync_table_lease_len_us | 10000000 | Leader が Follower に毎回付与するリースの有効期間 |