ステイル読み取りの使用シナリオ
このドキュメントでは、 ステイル読み取りの使用シナリオについて説明します。Stale ステイル読み取りは、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 クラスターの Resolved TS タイムスタンプを進め、TiDB がトランザクションの一貫性を満たすデータを読み取るようにします。Stale ステイル読み取りで使用されるタイムスタンプ (たとえば、 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 操作後の時間に変更できます。