ステイル読み取りの使用シナリオ
このドキュメントでは、 ステイル読み取りの使用シナリオについて説明します。Stale ステイル読み取り は、TiDB が TiDB に保存されているデータの履歴バージョンを読み取るために適用するメカニズムです。このメカニズムを使用することで、特定の時点または指定された時間範囲内の対応する履歴データを読み取ることができ、storageノード間のデータレプリケーションによって生じるレイテンシーを削減できます。
ステイル読み取り を使用する場合、TiDBはデータ読み取りのためにレプリカをランダムに選択します。つまり、すべてのレプリカがデータ読み取りに利用可能になります。アプリケーションが非リアルタイムデータの読み取りを許容できない場合は、 ステイル読み取り を使用しないでください。そうしないと、レプリカから読み取られたデータがTiDBに書き込まれた最新のデータではない可能性があります。
シナリオ例
シナリオ 1: トランザクションが読み取り操作のみを伴い、ある程度のデータの古さが許容される場合は、 ステイル読み取りを使用して履歴データを取得できます。 ステイル読み取りを使用すると、TiDB はリアルタイム パフォーマンスをある程度犠牲にしてクエリ要求を任意のレプリカに送信するため、クエリ実行のスループットが向上します。特に、小さなテーブルをクエリするシナリオでは、強力な一貫性のある読み取りを使用すると、リーダーが特定のstorageノードに集中し、クエリの負荷もそのノードに集中する可能性があります。そのため、そのノードがクエリ全体のボトルネックになる可能性があります。しかし、 ステイル読み取り を使用すると、クエリ全体のスループットが向上し、クエリのパフォーマンスが大幅に向上します。
シナリオ 2: 地理的に分散したデプロイメントの一部のシナリオでは、フォロワーから読み取ったデータがLeaderに保存されているデータと整合していることを確認するために、強力な整合性を持つフォロワー読み取りを使用する場合、TiDB は検証のために異なるデータセンターに
Readindex
要求します。これにより、クエリプロセス全体のアクセスレイテンシーが増加します。Stale ステイル読み取りを使用すると、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_enable_external_ts_read
設定することで、セッションレベルまたはグローバルレベルで正確な時点を指定する方法を提供しています。詳細な使用方法については、 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 操作後の時間に変更できます。