blog

TiDB 4.0では、ホットスポットに対処するためにどのような改善がなされたのか?

TiDBのデータアクセスホットスポット問題は、常にユーザーの大きな関心事でした。なぜこのような問題が目立つのでしょうか?これは実は「分散型」の構造的な影響です。分散データベースクラスタは、ストレージの...

Dec 13, 2020 · 8 min. read
シェア

時事問題の概要

TiDBのデータアクセスホットスポットの問題は、長い間ユーザーの大きな関心事でした。なぜこのような問題が目立つのでしょうか?これは実は「分散型」の構造的な影響なのです。分散データベースクラスタは、複数のノードが存在するストレージの拡張、読み取りおよび書き込み容量の拡張の目的を達成するために、私は、読み取りと書き込み圧力の多くは、各ノードに均等に広げることができることを願っている間スタンドアロンデータベースは、唯一のノードに起因するホットスポットの問題は、TiDBは、この目標に近づいています。

データベースには2-8の原則があり、80%の読み取りと書き込みが20%の最新データに対して行われます。 最も広く使われているMySQLを例にとると、MySQLからTiDBに移行する企業の多くは、移行前にセルフインクリメント型の主キーを使用し、ランダム書き込みをシーケンシャル書き込みに変換することでパフォーマンスを向上させています。その理由は、TiDBはデータのスライスにレンジを使用するため、新しい書き込みがノードの範囲に集中し、単一マシンへの書き込みのパフォーマンスが低下し、分散リード/ライトスケーリングを活用できないからです。

問題に直面

これらの問題を解決するために、TiDBは非常に初期の2.0バージョンでそれを改善する試みを始めました。それは新しいテーブル属性SHARD_ROW_ID_BITSです。その原理は、バイナリの上位ビットで主キーを自動的に生成してビット反転を行うことで、単調に増加するIDを一定の範囲内でランダムなIDに変換し、異なるノードに書き込みデータを自動的に分散させる圧力を達成することで、シングルポイント書き込みの圧力を緩和する良い方法です。多くのビジネスでは通常、単調に主キーを増やすのではなく、繰り返しのない主キーしか必要としないため、この機能によってシングルポイント書き込みの圧力をかなりの程度緩和することができます。さらに、PRE_SPLIT_REGIONSがサポートされ、テーブルの構築時に複数のリージョンをプリセットできます。PDとTiKVノードのホットスポットスケジューリングアルゴリズムは3.0以降のバージョンで最適化され、HOT-REGION-SCHEDULERが導入され、異なるノードのホットスポット範囲をタイムリーにバランスさせることができます。範囲のバランス

tiDBは、これらの問題に直面し、問題を解決する必要があり、3.0の開発は、次のようにまだいくつかの顕著な問題があります:

  • SHARD_ROW_ID_BITS フラグ

    • 使い勝手が悪く、ユーザーの理解や学習にコストがかかります;

    • トラブルの使用を引き起こすInt型主キーの使用をサポートすることはできません、テーブル構造の変換が大きく、Binlogの要件の使用と互換性がありません;

    • その結果、ユーザー自身がsnowflakeのようなランダムID生成サービスを導入する必要が生じることがあります。

  • ホットスポット派遣

    • バージョン3.0では、ホットスポット・リージョンのカウント方法が比較的単一で、リードまたはライトのトラフィックがある閾値を超えたリージョンを一定期間継続してカウントし、スケジューリングするため、トラフィックのカウントが不正確、オーバースケジューリング、ホットスポット数が多い場合の不安定などの問題が発生します。
  • ホットスポットチェック

    • ホットスポットが存在するかどうかを目視で判断することはできません;

    • どのテーブルにホットスポットがあり、どのステートメントがホットスポットの原因になっているかを視覚的に判断する方法はありません;

    • ホットスポットのトラブルシューティングは難しく、総合的な判断を下すには複数のモニターやログを組み合わせる必要があります。

バージョン4.0の改良点

ホットスポットの問題はTiDBにとって常に大きな懸念事項でしたが、一日にしてならず、2.x、3.x、4.0と進化してきました。では、上記3つの問題を最適化するために、4.0ではどのような改善がなされたのでしょうか?

AutoRandom ID

AutoRandomはTiDB 4.0で提供された拡張構文で、整数型の主キーにAutoIncrement属性でIDを割り当てた場合の書き込みホットスポットに対処するためのものです。

AutoIncrementとほぼ同じ形で使用されますが、テーブルのランダムな一意性を達成することができ、平均的なユーザーはもはや複雑なシャード機構を理解する必要はありません。

もちろん、AutoRandomはSHARD_ROW_ID_BITSと同様にPRE_SPLIT_REGIONS構文と組み合わせて使用することもできますし、1707676を使用してその値を取得することもできます。

AutoRandomはMySQLユーザのアップストリームおよびダウンストリームへの移行を容易にし、MySQLからTiDBへの同期はテーブル構造のわずかな変更で済み、元のMySQLのAUTOINCREMENT値を使用することができます。互換性のために、AutoRandomはテーブル構造のコメントとしても解析され、対応する機能を実装していないバージョンのTiDBでは無視されます。

赤いセクションのAutoRandomは、解析方法としてアノテーションを使用しています。

同時に、ランダムプログラムとしてのAutoRandomは、真にホットスポットの問題を解決するために、均一な分布を達成することができなければならない、挿入の多数の効果を観察するためのテストを通じて、異なるセグメントの行数の統計は非常に均一である見ることができます。

AutoRandomが生成した値が均等に分散されていることを確認する必要があります。

上の図では、dist_interval がセグメンテーションの基本区間を表し、interval が異なるセグメントの範囲を表し、length が AutoRandom の結果がその範囲にヒットする回数を表しています。

オートランダムの仕組みは以下の通りです。

AutoRandomがプライマリキーになることで、暗黙のTiDB内部プライマリキー_tidb_rowidが明示的なプライマリキーになり、SHARD_ROW_ID_BITS + auto_increment一意インデックススキームと実質的に同じメカニズムで、パフォーマンスも低下しません。64ビットのbigintを3つのセグメントに分割します:

  • SignBit - 符号ビット。符号がある場合に占有され、長さは1です。

  • ShardBits - ID値フィールドを分割するための乱数を生成します。属性auto_random(5)(デフォルトは5)で指定します。

  • increment_bits - 自己インクリメント・ビットで、IDの一意性と単一ステートメント内のアロケーションの連続性を確保するために使用されます。

最後に、AutoRandomについてのメモを見てください:

  • 通常、デフォルトで十分です。多すぎると、Incrementalセクションで割り当てられるビットが少なくなり、rpcインタラクションの消費量が増えます;

  • AutoIncrementのように、AutoRandomはユーザによる明示的な書き込みをサポートしますが、Incremental部分がユーザの値にリベースするため、割り当て可能なidを早期に使い果たしてしまう可能性があるため、非常に推奨されません;

新しいホットスポット・スケジューラー

ホットスポットのスケジューリングアルゴリズムに関しても、4.0では多くの改良が加えられています。バージョン3.0では単一リージョンの視点であったため、TiKVノード間の統計情報の集約がうまくいきませんでしたが、4.0ではTiDBがTiKVノードの視点からデータを集約して処理するため、ロードベースホットスポットスケジューリングとも呼ばれる新しいホットスポットスケジューラが採用されました。これは次のように最適化されています:

統計へのノイズ除去の追加: 統計処理について、新しいリーダによって初めて報告された統計を無視し、トラフィックの計算時間を修正するために、以下のポリシーが追加されました。これにより、不正確で膨らんだ統計の一部が修正されます。また、よりノイズを減らすために、2段階の処理メカニズムが追加されました。

より多くのホットスポットをカバーするためにTopNを使用:現在のホットスポット識別アルゴリズムは、ホットスポット地域の数が設定された期待値を超えると機能しません。より多くのホットスポットをカバーするために、ホットスポット地域のデータ構造を維持し、2つのキャッシュキューからTopNのデータ構造に変更します。

期待値スケジューリングの追加:冗長なスケジューリングを避けるため、期待値スケジューリングを追加します。つまり、各ストアの期待値を計算し、実数が期待値乗算係数より小さい場合のみ転送を許可し、実数が期待値乗算係数より大きい場合のみ転送を許可します。

多次元スケジューリング:ホットスポットスケジューラの能力をさらに向上させ、将来のスケーラビリティを考慮するために、多次元負荷分散に適応できる新しいホットスポットスケジューラフレームワークを設計し、それに基づいてトラフィックの負荷分散を実装します。可能なスケジューリング方式をまず列挙し、次にルールベースの比較によって最適な方式を見つけます。

新しいホットスポットスケジューリングをオンにすると、テストトラフィックを迅速に均一化できます。

ホットスポットの可視化

4.0Featureの紹介では、ダッシュボード機能を紹介しましたが、その中の一つである「ホットスポットの可視化」は、KeyVizとも呼ばれ、どのライブラリ、どのインデックス、どのセグメント範囲に読み書きのトラフィックが集中しているかを、熱イメージの形でユーザーに直感的に伝えるもので、ホットスポットの問題を発見し、場所を特定するための強力なツールでもあり、ユーザーのトラブルシューティングを非常に容易にします。ホットスポットの問題

上のイメージの明るい部分を見ると、規則的な斜めの線が見えます。これは、Region の範囲に伴ってトラフィックが増加しているヒートマップであり、自己インクリメント型プライマリキーによる典型的なホットスポットであることがよくわかります。色のついたブロックの上にマウスオーバーすると、そのホットスポットの背後にあるライブラリテーブルの情報が表示されます。

小型テーブルのホットスポット最適化

これまでの最適化手法では、小テーブルのホットスポット問題を解決できません。PDのホットスポットスケジューリングはリージョンを粒度として取ることしかできないため、小さなテーブルは通常1つのリージョンにしか存在せず、PDはそれに対して何もできません。例えば、ある構成テーブルの大量のフルテーブルスキャンとインデックス検索は、単一リージョンのホットスポットを生成し、多くの場合、分割リージョンで手動介入を必要としますが、その操作は面倒で時間がかからず、ホットスポットがいくつかのキーにしか存在しない場合、切断位置を決定するのは容易ではありません。

バージョン4.0では、ホットスポットのスモールテーブルを自動的に分割するLoad Base Split機能が導入されました。Load Base Splitは、統計情報に基づいてリージョンを自動的に分割し、読み込みトラフィックが常に10秒以内に閾値を超えるリージョンを統計情報から特定し、適切な位置で分割します。分割場所を選択する際には、分割後の2つのリージョンのアクセス量のバランスをとり、リージョンをまたいだアクセスを避けるようにします。この機能はバージョン4.0ではデフォルトで有効になっています。

概要

ホットスポットのハンドリングは分散データベースにおける不変のトピックであり、4回のメジャーリリースを経て、TiDB 4.0はAutoRandom、新しいホットスポットスケジューラ、ホットスポットの可視化によって大幅に最適化されました。これらの変更はユーザーエクスペリエンスに静かに影響を与えます。

もちろん、ホットスポットはまだ完成しておらず、コミュニティ全体の協力を得ながら調査・改良していく必要があります:

  • クラスタ化されたインデックスによってテーブルの返り値を削減することで、読み込みホットスポット・シナリオにおけるデータ・アクセスの効率が向上します。最新のマスター・バージョンが完成し、ユーザーはすでに対応するシナリオでTPC-Cをテストし、TPC-Cが50%の性能向上を持つことを確認しました。クラスタ化されたインデックスは、次のGAバージョンで提供される予定です;

  • もうひとつの方向性は、AIによる予測を組み込んで、事前にオペレーションをスケジューリングすることです;

  • 小さなテーブルのホットスポットについては、バージョン5.0では読み取り専用テーブル機能でさらに最適化されます;

  • KeyVizはリージョンの粒度でホットスポットの範囲を特定することができますが、よりワンステップ化することができます。例えば、読み取り/書き込みのホットスポットがあるかどうかをビジネスに直接知らせたり、どのタイプのSQLがホットスポットを引き起こすかを直接表示したり、ワンクリックでホットスポットのリージョンを分割したり、潜在的なホットスポットの根本原因を自動的に分析したりすることができます。

Read next

JSの基本原則、スタック、変数、オブジェクトの詳細ポイントの過程でコードを実行する

コードが実行され、内容が占有されていない場合、スタックアウト操作が発生します。 グローバルに宣言された変数は、GOに何らかのマッピングを持ちますが、これはGOにもこれらの属性の1つを追加することと同じです。もし変数が宣言されておらず、ECを知っているスコープを通してルックアップが実行され、何も見つからなかった場合、それはGOウィンドウにこの属性を追加するもので、特別なオブジェクトです...

Dec 13, 2020 · 3 min read