ステイル読み取りの使用シナリオ
このドキュメントでは、 ステイル読み取りの使用シナリオについて説明します。 ステイル読み取り は、TiDB に保存されているデータの履歴バージョンを読み取るために TiDB が適用するメカニズムです。このメカニズムを使用すると、特定の時点または指定された時間範囲内の対応する履歴データを読み取ることができるため、storageノード間のデータ レプリケーションによってもたらされるレイテンシーを節約できます。
ステイル読み取りを使用している場合、TiDB はデータ読み取り用のレプリカをランダムに選択します。これは、すべてのレプリカがデータ読み取りに使用できることを意味します。アプリケーションが非リアルタイム データの読み取りを許容できない場合は、 ステイル読み取りを使用しないでください。そうしないと、レプリカから読み取られたデータが TiDB に書き込まれた最新のデータではない可能性があります。
シナリオの例
シナリオ 1: トランザクションに読み取り操作のみが含まれ、データの古さがある程度許容される場合は、 ステイル読み取り を使用して履歴データを取得できます。 ステイル読み取りを使用すると、TiDB はリアルタイム パフォーマンスを犠牲にしてクエリ リクエストを任意のレプリカに送信するため、クエリ実行のスループットが向上します。特に、小さなテーブルがクエリされる一部のシナリオでは、強い一貫性のある読み取りが使用されると、リーダーが特定のstorageノードに集中し、クエリの負荷がそのノードにも集中する可能性があります。したがって、そのノードがクエリ全体のボトルネックになる可能性があります。ただし、 ステイル読み取りと、クエリ全体のスループットが向上し、クエリのパフォーマンスが大幅に向上します。
シナリオ 2: 地理分散展開の一部のシナリオでは、強力な一貫性のあるフォロワー読み取りが使用されている場合、フォロワーから読み取られたデータがLeaderに保存されているデータと一致していることを確認するために、TiDB は検証のためにさまざまなデータ センターに
Readindex
を要求します。クエリ プロセス全体のアクセスレイテンシーが増加します。 ステイル読み取りを使用すると、TiDB は現在のデータ センターのレプリカにアクセスして、リアルタイム パフォーマンスを犠牲にして対応するデータを読み取ります。これにより、クロスセンター接続によってもたらされるネットワークレイテンシーが回避され、クエリ全体のアクセスレイテンシーが削減されます。詳細については、 3 つのデータセンター展開におけるローカル読み取りを参照してください。
用途
TiDB は、次のように、ステートメント レベル、セッション レベル、およびグローバル レベルでステイル読み取りを実行するメソッドを提供します。
- ステートメントレベル
- 正確な時点の指定 (推奨): TiDB が分離レベルに違反することなく、特定の時点からグローバルに一貫したデータを読み取る必要がある場合は、クエリ ステートメントでその時点の対応するタイムスタンプを指定できます。詳しい使い方は
AS OF TIMESTAMP
句を参照してください。 - 時間範囲の指定: TiDB が分離レベルに違反せずに、時間範囲内でできるだけ新しいデータを読み取る必要がある場合は、クエリ ステートメントで時間範囲を指定できます。指定された時間範囲内で、TiDB は適切なタイムスタンプを選択して、対応するデータを読み取ります。 「適切」とは、このタイムスタンプより前に開始され、アクセスされたレプリカでコミットされていないトランザクションがないことを意味します。つまり、TiDB はアクセスされたレプリカで読み取り操作を実行でき、読み取り操作はブロックされません。詳しい使い方については、
AS OF TIMESTAMP
句とTIDB_BOUNDED_STALENESS
関数の紹介を参照してください。
- 正確な時点の指定 (推奨): TiDB が分離レベルに違反することなく、特定の時点からグローバルに一貫したデータを読み取る必要がある場合は、クエリ ステートメントでその時点の対応するタイムスタンプを指定できます。詳しい使い方は
- セッションレベル
- 時間範囲の指定: セッション中、TiDB が分離レベルに違反することなく、後続のクエリで時間範囲内でできるだけ新しいデータを読み取る必要がある場合は、
tidb_read_staleness
システム変数を設定して時間範囲を指定できます。詳しい使い方はtidb_read_staleness
を参照してください。
- 時間範囲の指定: セッション中、TiDB が分離レベルに違反することなく、後続のクエリで時間範囲内でできるだけ新しいデータを読み取る必要がある場合は、
さらに、TiDB は、セッションまたはグローバル レベルでtidb_external_ts
システム変数を設定することにより、正確な時点を指定する方法を提供します。詳しい使い方はtidb_external_ts
を使用してステイル読み取りを実行するを参照してください。
ステイル読み取りレイテンシーを削減する
ステイル読み取り機能は、TiDB クラスターの解決済み TS タイムスタンプを定期的に進めます。これにより、TiDB はトランザクションの一貫性を満たすデータを確実に読み取ります。 ステイル読み取りで使用されるタイムスタンプ (たとえば、 AS OF TIMESTAMP '2016-10-08 16:45:26'
) が Resolved TS より大きい場合、 ステイル読み取りは TiDB をトリガーして Resolved TS を先に進め、その進みが完了するのを待ってからデータを読み取ります。これにより、レイテンシーの増加につながります。
ステイル読み取り レイテンシーを短縮するには、次の TiKV 構成項目を変更して、TiDB が解決済み TS タイムスタンプをより頻繁に進めるようにします。
[resolved-ts]
advance-ts-interval = "20s" # The default value is "20s". You can set it to a smaller value such as "1s" to advance the Resolved TS timestamp more frequently.
注記:
前述の TiKV 構成項目を減らすと、TiKV の CPU 使用率とノード間のトラフィックが増加します。
Resolved TS の内部と診断技術の詳細については、 TiKV のステイル読み取りとsafe-tsを理解するを参照してください。
制限
テーブルのステイル読み取りクエリがTiFlashにプッシュダウンされるとき、クエリで指定された読み取りタイムスタンプの後に実行された新しい DDL 操作がこのテーブルにある場合、クエリはエラーを返します。これは、 TiFlash が最新のスキーマを含むテーブルからのデータの読み取りのみをサポートしているためです。
次の表を例として取り上げます。
create table t1(id int);
alter table t1 set tiflash replica 1;
1 分後に次の DDL 操作を実行します。
alter table t1 add column c1 int not null;
次に、 ステイル読み取り を使用して 1 分前のデータをクエリします。
set @@session.tidb_enforce_mpp=1;
select * from t1 as of timestamp NOW() - INTERVAL 1 minute;
TiFlash は次のようなエラーを報告します。
ERROR 1105 (HY000): other error for mpp stream: From MPP<query:<query_ts:1673950975508472943, local_query_id:18, server_id:111947, start_ts:438816196526080000>,task_id:1>: Code: 0, e.displayText() = DB::TiFlashException: Table 323 schema version 104 newer than query schema version 100, e.what() = DB::TiFlashException,
このエラーを回避するには、 ステイル読み取りで指定された読み取りタイムスタンプを DDL 操作後の時刻に変更します。