すべてのプロダクト
Search
ドキュメントセンター

PolarDB:ホット行更新の最適化

最終更新日:Oct 18, 2024

ホット行は、頻繁に更新または変更されるデータベース内の行です。 並行性の高いシナリオでは、複数のトランザクションがホット行を同時に更新しようとする可能性があり、これにより、行ロックの競合と待ち時間が大幅に発生します。 この競合は、システム性能を著しく低下させ得ます。 この問題を解決するために、PolarDBはデータベースカーネルレベルで革新的な最適化を実装して、ロックの競合を軽減し、システムパフォーマンスを向上させます。

背景情報

痛みのポイント:

  • トランザクションがデータベース内の行を更新すると、トランザクションがコミットまたはロールバックされるまで、行はロックされたままになります。 複数のトランザクションが同時に同じ行を更新しようとすると、1つのトランザクションのみが続行できます。 他のトランザクションは待機する必要があります。 同じホット行での更新のこのシリアル化では、従来のデータベースとテーブルのシャーディングポリシーは、パフォーマンスに限られた利点しか提供しません。

  • eコマースプラットフォームでは、購入制限やフラッシュセールなどのプロモーション戦略により、データベース内のホットな行を短期間で更新するリクエストが急増することがよくあります。 この結果、行ロックの競合が激しくなり、待ち時間が長くなります。 更新要求の待ち時間が長くなると、システムのパフォーマンスが低下し、ユーザーエクスペリエンスに悪影響を及ぼします。

ハードウェアの強化は、前述の問題に対する効果的な解決策ではありません。 この問題を解決するために、PolarDBはデータベースカーネルレベルで革新的な最適化を実装します。 これにより、システムは、特定の時間間隔で、ホット行の更新要求と、同じホット行のグループ更新要求とを自動的に識別することができます。 更新の異なるグループは、パイプライン手法を使用することによって並列に処理されます。 最適化により、トランザクションの待ち時間が短縮され、システムパフォーマンスが大幅に向上します。

解決策

  • シリアル処理からパイプライン処理への移行

    並列処理は、データベースシステムのパフォーマンスを向上させる最も効果的な方法です。 ただし、システムが同じホット行を並行して更新する要求を処理するときに問題が発生します。 PolarDBは、ホット行の更新要求の並列処理を最大化する革新的なパイプラインアプローチを使用して、上記の問題を解決します。

    image

    ホット行の更新に使用されるSQL文は、autocomitまたはCOMMIT_ON_SUCCESSラベルでマークされます。 最適化されたMySQLカーネルレイヤーは、マークされた更新リクエストを自動的に認識できます。 レイヤーは、特定の時間間隔で更新要求を収集し、プライマリキーまたは一意のキーに基づいて、更新要求をさまざまなバケットにハッシュします。 各バケット内の更新は、到着順序に基づいてグループ化され、処理されます。

    更新要求を処理するためにパイプライン手法を使用するために、2つの実行ユニットがグループ化されたオペレーションを管理するために使用されます。 第1のグループの更新要求がコミットされる準備ができると、第2のグループは新しい更新要求の収集を開始します。 第2のグループの更新要求がコミットされる準備ができたとき、第1のグループの更新要求がコミットされ、新しい更新要求が収集されます。 2つのグループは、並列処理を可能にする周期的に動作します。

    マルチコアCPUは業界で広く使用されています。 このパイプライン手法は、ハードウェア資源を最大限に活用し、CPU利用率を高め、データベースシステムの並列処理能力を改善し、データベースシステムのスループットを最大化することができます。

  • 行ロック取得の待ち時間を減らす

    データベース内の行が更新されると、データの整合性を確保するために行がロックされます。 別の操作が同じ行にアクセスしようとする場合、操作はロックが使用可能になるまで待機する必要があります。 ロック要求を直ちに処理できない場合、要求は待機状態に入ります。 これにより、処理遅延が増加し、デッドロック検出がトリガーされ、追加のリソースが消費されます。

    解決策は、時系列に基づいて更新をグループ化する方法を導入します。 グループ内の最初の更新要求はリーダーと呼ばれます。 リーダーは行を読み取り、ロックします。 同じグループ内の後続の更新要求は、フォロワーと呼ばれます。 フォロワーが行のロックを要求すると、最初にリーダーがすでにロックを保持しているかどうかを確認します。 リーダーがロックを持っている場合、フォロワーはすぐにロックを取得します。

    この戦略は、行ロックが要求される回数を最小限に抑え、ロックを取得するために必要な時間を短縮します。 その結果、データベースシステム全体の性能が向上します。

  • B-treeインデックスの横断を減らす

    MySQLは、B-treeインデックスに基づいてデータを管理します。 各クエリ中に、MySQLはすべてのインデックスをトラバースして必要な行を見つけます。 テーブルが大きく、複数のインデックスレベルを持つ場合、インデックスをトラバースするのに長時間が必要になります。

    前のセクションで説明した更新要求グループ化メカニズムでは、各グループのリーダーのみがインデックスをトラバースして、関連する行を見つける必要があります。 リーダーが行を更新した後、更新された行はメモリにキャッシュされます。 同じグループ内のフォロワーが行ロックを取得した後、フォロワーはすべてのインデックスをトラバースする必要なく、メモリから行を直接読み取ることができます。

    このメカニズムは、インデックストラバーサルの数と時間の消費を減らします。

前提条件

  • PolarDBクラスターは、次のデータベースエンジンバージョンのいずれかを実行します。

    • リビジョンバージョンが20200601以降のPolarDB for MySQL 5.6

    • リビジョンバージョンが5.7.1.0.17以降のPolarDB for MySQL 5.7。

    • リビジョンバージョンが8.0.1.1.10以降のPolarDB for MySQL 8.0。

  • PolarDB for MySQLクラスターでは、バイナリログ機能が有効になっています。

  • rds_ic_reduce_hint_enableパラメーターはOFFに設定されています。

説明

制限事項

ホット行更新の最適化機能は、次のシナリオではサポートされていません。

  • ホット行を含むテーブルはパーティション分割されます。

  • ホット行を含むテーブルに対してトリガーが定義されます。

  • ステートメントキューメカニズムは、ホット行に適用されます。

  • グローバルバイナリロギングが有効で、セッションレベルのバイナリロギングが無効の場合、ホット行更新最適化機能をupdateステートメントに使用することはできません。

使用量

  1. ホット行更新の最適化機能を有効にする

    PolarDBコンソールで次のパラメーターを使用して、ホット行更新の最適化機能を有効または無効にできます。

    パラメーター

    説明

    ホットスポット

    ホット行更新最適化機能を有効にするかどうかを指定します。 有効な値:

    1. オン

    2. OFF (デフォルト)

    説明
  2. ホット行更新最適化機能には、3つの新しいオプティマイザヒントが含まれます。

    ヒント

    必須ですか?

    説明

    COMMIT_ON_成功

    必須/任意

    更新が成功すると、トランザクションをコミットします。

    ROLLBACK_ON_FAIL

    省略可能

    更新が失敗したときにトランザクションをロールバックします。

    TARGET_AFFECT_ROW (1)

    省略可能

    要求が1行のみを更新することを明示的に指定します。 複数の行または行が更新されない場合、更新は失敗します。

    説明

    トランザクションのヒントが有効になると、トランザクションは自動的にコミットされます。 したがって、トランザクションの最後のSQLステートメントにヒントを配置する必要があります。

    例: sbtestテーブルの列cの値を更新します。

    UPDATE /*+ COMMIT_ON_SUCCESS ROLLBACK_ON_FAIL TARGET_AFFECT_ROW(1) */ sbtest SET c = c + 1 WHERE id = 1;

関連する API

カスタムパラメーター設定

PolarDBコンソールで次のパラメーターを変更することはできません。 パラメーターを変更するには、クォータセンターに移動し、PolarDBホットスポット行パラメーター調整クォータ名を見つけて、[操作] 列の [適用] をクリックします。

パラメーター

説明

hotspot_for_自動コミット

自動コミットモードでupdateステートメントのホット行更新最適化機能を有効にするかどうかを指定します。 有効な値:

  • オン

  • OFF (デフォルト)

hotspot_update_max_wait_time

グループ内のリーダーが、同じデータ行に対する更新要求のグループ化および処理中のプロセス中に、フォロワーがグループに参加するのを待つ最大時間。

  • 単位:マイクロ秒。

  • デフォルト値: 100 μ s。

hotspot_lock_type

同じデータ行に対する更新要求のグループ化および処理中に新しい種類の行ロックを使用するかどうかを指定します。 有効な値:

  • オン

  • OFF (デフォルト)

説明
  • このパラメーターをtrueに設定すると、グループのリーダーがロックを取得した後、フォロワーは同じ行に対して直接ロックを使用できます。

パラメーター設定の表示

次のステートメントを実行して、ホット行更新最適化機能のパラメーター設定を表示できます。

SHOW variables LIKE "hotspot%";

サンプル結果:

+------------------------------+-------+
|Variable_name                 | Value |
+------------------------------+-------+
|hotspot                       | OFF   |
|hotspot_for_autocommit        | OFF   |
|hotspot_lock_type             | OFF   |
|hotspot_update_max_wait_time  | 100   |
+------------------------------+-------+

ホット行更新最適化機能の使用状況の表示

次のステートメントを実行して、ホット行更新最適化機能の使用状況を表示できます。

SHOW GLOBAL status LIKE 'Group_update%';

パフォーマンステスト

  • テストテーブルとステートメント:

    • テーブル

      CREATE TABLE sbtest (id INT UNSIGNED NOT NULL, c BIGINT UNSIGNED NOT NULL, PRIMARY KEY (id));
    • UPDATE /*+ COMMIT_ON_SUCCESS ROLLBACK_ON_FAIL TARGET_AFFECT_ROW(1) */ sbtest SET c = c + 1 WHERE id = 1;
  • テストツール: Sysbench。

  • テストシナリオと結果

    • シナリオ1: 1つのホット行と8コアCPU

      このシナリオでは、8コアCPUが使用され、ホット行を更新するために多数の同時要求が送信されます。 ホット行更新最適化機能を有効にすると、データベースのパフォーマンスは最大64倍向上します。

      2

    • シナリオ2: 1つのホット行と32コアCPU

      このシナリオでは、32コアのCPUが使用され、ホット行を更新するために多数の同時要求が送信されます。 ホット行更新最適化機能を有効にすると、1秒あたりのピーククエリ (QPS) が63倍に増加します。 同時リクエスト数が8,000に達すると、データベースのパフォーマンスは46倍向上します。

      2

    • シナリオ3: 8つのホット行と32コアCPU

      このシナリオでは、32コアのCPUが使用され、8つのホット行を更新するために多数の同時要求が送信されます。 ホット行更新最適化機能が有効になった後、ピークQPSは20倍改善されます。

      ホット行更新最適化機能が無効になっており、同時リクエストの数が16,000に達すると、データベース障害が発生し、結果は返されません。 対照的に、ホット行更新最適化機能が有効になっている場合、行データは予想通りに更新され、QPS値は安定したままです。

      4