このトピックでは、ホット行最適化機能を使用してデータベースシステムのパフォーマンスを向上させる方法について説明します。
前提条件
PolarDBクラスターは、次のいずれかのデータベースエンジンバージョンを実行します。
リビジョンバージョンが20200601以降のPolarDB for MySQL5.6。
リビジョンバージョンが5.7.1.0.17以降のPolarDB for MySQL 5.7。
リビジョンバージョンが8.0.1.1.10以降のPolarDB for MySQL 8.0。
ホット行最適化機能が期待どおりに実行されるようにするには、PolarDB for MySQLクラスターのバイナリログを有効にします。
バイナリログを有効にすると、クラスターの書き込みパフォーマンスが低下する場合があります。
バイナリログを有効にすると、ストレージ使用量が増加します。
クラスターのマイナーデータベースエンジンのバージョンをアップグレードする方法については、「マイナーバージョンの更新」をご参照ください。
背景情報
痛みのポイント:
ホット行は、頻繁に追加、削除、変更、または照会されるデータベース内の行です。 トランザクションが行内のデータを更新すると、トランザクションがコミットまたはロールバックされるまで行がロックされます。 各行は、一度に1つのトランザクションだけで更新できます。 ホット行を更新するための要求は、連続的な順序で処理されます。 その結果、従来のデータベースシャーディングおよびテーブルシャーディングポリシーは、処理性能を改善するのに効果がない。
eコマースプラットフォームでは、期間限定販売とフラッシュ販売がプロモーションに頻繁に使用されます。 このようなシナリオでは、ホット行を更新するための多数の要求が短時間でデータベースに送信されます。 この結果、行ロックの競合と待ち時間が長くなります。 その結果、システム性能が低下します。 更新要求が処理される前に更新要求が長時間待機する場合、サービスは悪影響を受けます。
ハードウェアアップグレードは、これらの課題に効果的に対処できなくなりました。 これらの課題を克服するために、PolarDBはデータベースエンジンレベルで革新的な最適化を導入しています。 最適化されたシステムは、特定の間隔内で、ホット行の更新要求と同じホット行のグループ更新要求を自動的に識別できます。 これらの異なるグループは、パイプライン手法を用いて並列に処理される。 これらの最適化により、システムの性能を著しく改善することができます。 解決策:
シリアル処理からパラレル処理への変換
並列処理は、データベースシステムのパフォーマンスを向上させる最も効果的な方法です。 しかし、システムは、同じホット行を並行して更新する要求を処理する際の課題に直面します。 PolarDBは、パイプラインアプローチを使用してこの問題に対処します。これにより、ホット行の更新要求の並列処理のパフォーマンスが大幅に向上します。
ホット行を更新するために実行されるSQL文には、
autocomit
またはcommit_on_success
ラベルが添付されています。 最適化されたMySQLエンジンは、前述のラベルが添付されている更新要求を自動的に識別できます。 エンジンは、プライマリキーまたは一意のキーに基づいてこれらの更新要求を、指定された間隔で異なるバケットにハッシュします。 同じバケットにハッシュされた更新要求は、到着の順序に基づいてグループおよびバッチで処理され、コミットされます。これらの更新要求をパイプラインで処理するために、2つの実行ユニットがこれらの要求をグループ化する必要があります。 第1のグループの更新要求が収集され、コミットされる準備ができると、第2のグループの更新要求が収集されます。 第2のグループの更新要求が収集され、コミットされる準備ができたとき、第1のグループの更新要求がコミットされます。 次に、更新要求の次のバッチが最初のグループに収集され始めます。 これにより、更新要求が並列に処理されることが保証されます。
マルチコアCPUは広く使用されています。 このパイプラインベースの処理方法は、ハードウェアリソースを最大限に活用し、CPU使用率を高め、データベースシステムの並列処理能力を向上させることができます。 これは、データベースシステムのスループットを最大化する。
行ロックの取得を待つ必要がなくなります
データの論理的一貫性を確保するには、更新時に行をロックする必要があります。 行ロックを取得する要求をすぐに処理できない場合、要求はキューで待機し、要求処理時間が増加し、デッドロック検出がトリガーされます。 その結果、追加のリソースが消費されます。
同じ行を更新する要求は、時系列順にグループ化されます。 グループ内の最初の更新要求はリーダーです。 リーダーは行のデータを読み取り、行をロックします。 同じグループ内の他の更新要求は、フォロワーです。 行がリーダーによってロックされている場合、フォロワーはすぐに行ロックを取得できます。
これにより、行ロックの数と、行をロックするのにかかる時間が削減され、データベースシステムのパフォーマンスが向上します。
B-treeインデックスの横断を減らす
MySQLは、B-treeインデックスに基づいてデータを管理します。 各クエリ中に、MySQLはすべてのインデックスをトラバースして必要な行をクエリします。 テーブルが大きく、複数のインデックスレベルがある場合、インデックスをトラバースするのに時間がかかります。
グループ化メカニズムを使用する場合、各グループのリーダーのみが、必要な行を照会するためにインデックスをトラバースする必要があります。 次に、リーダーは、更新された行をメモリにキャッシュします。 同じグループのフォロワーは、行ロックを取得した後にメモリから行を読み取ることができます。 フォロワーは、すべてのインデックスを再度トラバースする必要はありません。
これにより、インデックストラバーサルの数と消費時間が削減されます。
制限事項
ホット行最適化機能は、次のシナリオではサポートされていません。
ホット行はパーティションテーブルにあります。
トリガーは、ホット行が属するテーブルで定義されます。
ステートメントキューメカニズムは、ホット行用に設定されています。
使用量
ホット行最適化機能を使用してデータベースのパフォーマンスを向上させる前に、関連するパラメーターを設定する必要があります。 下表に、各パラメーターを説明します。 パラメーターの設定方法については、「クラスターおよびノードパラメーターの設定」をご参照ください。
パラメーター
説明
loose_hotspot
ホット行最適化機能を有効にするかどうかを指定します。 有効な値: ONとOFF。 デフォルト値: OFF。
loose_hotspot_for_自動コミット
自動コミット
モードでUPDATEステートメントのホット行最適化機能を有効にするかどうかを指定します。 有効な値: ONとOFF。 デフォルト値: OFF。説明このパラメーターは、hotspotパラメーターをONに設定した場合にのみ設定できます。
loose_hotspot_update_max_wait_time
グループ内のリーダーが、リクエストのグループ化中にフォロワーがグループに参加するのを待つのに必要な時間。 単位: μ s。 デフォルト値: 100 μ s。
loose_hotspot_lock_type
システムがグループ内の同じデータ行を更新する要求を処理するときに、新しい種類の行ロックを使用するかどうかを指定します。 有効な値: ONとOFF。 デフォルト値: OFF。
説明このパラメーターをONに設定した場合、同じホット行を更新するリクエストは行ロックの取得を待つ必要はありません。 これにより、データベースシステムの性能が向上します。
説明コンソールでhotspot_for_autocomit、hotspot_update_max_wait_time、およびhotspot_lock_typeパラメーターを設定することはできません。 パラメーターを設定するには、Quota Centerに移動します。 PolarDB hotspot行パラメーター調整に対応する [操作] 列の [適用] をクリックします。
ホット行最適化機能を使用するには、バイナリログ機能を有効にする必要があります。 バイナリログ機能が無効になっているときにhotspotパラメーターをONに設定しようとすると、エラーが発生します。
バイナリログ機能が無効になっているときに、
MySQL [(なし)]> set global hotspot=ON;
ステートメントを実行してhotspotパラメーターをONに設定すると、次のエラーが返されます。ERROR 3042 (HY000): Variable 'hotspot' cannot be enabled because 'bin logging' is enabled/disabled
であるため、変数「ホットスポット」を有効にできません
バイナリログを有効にする方法については、「バイナリログの有効化」をご参照ください。
バイナリログ機能がグローバルに有効で、セッションに対して無効になっている場合、hotspotパラメーターをONに設定できます。 ただし、ホット行の最適化はUPDATEステートメントでは有効になりません。
rds_ic_reduce_hint_enableパラメーターがONに設定されているときに、
MySQL [(なし)]> set global hotspot=ON;
ステートメントを実行してhotspotパラメーターをONに設定すると、次のエラーが返されます。ERROR 3042 (HY000): Variable 'hotspot' cannot be enabled because 'rds_ic_reduce_hint_enable' is enabled/disabled
次のステートメントを実行して、パラメーター設定を確認できます。
show variables like "hotspot%";
サンプル結果:
+------------------------------+-------+ | Variable_name | Value | +------------------------------+-------+ | hotspot | OFF | | hotspot_for_autocommit | OFF | | hotspot_lock_type | OFF | | hotspot_update_max_wait_time | 100 | +------------------------------+-------+
ホット行最適化機能には、3つの新しいオプティマイザヒントが含まれます。
ヒント
必須
説明
COMMIT_ON_SUCCESS
必須/任意
更新が成功すると、トランザクションをコミットします。
ROLLBACK_ON_FAIL
省略可能
更新が失敗したときにトランザクションをロールバックします。
TARGET_AFFECT_ROW (1)
省略可能
要求が1行のみを更新することを明示的に指定します。 複数の行が更新された場合、更新は失敗します。
次のステートメントを実行して、ホット行の最適化に関する統計を表示できます。
show global status like 'Group_update%';
制限事項
トランザクションのヒントが有効になると、トランザクションは自動的にコミットされます。 したがって、トランザクションの最後のSQLステートメントにヒントを配置する必要があります。
パフォーマンステスト
次のステートメントを実行して、パフォーマンステストを実行できます。
テーブルの作成
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: 1つのホット行と32コアCPU
このシナリオでは、32コアCPUが使用され、ホット行を更新するために同時要求が送信されます。 ホット行最適化機能を有効にすると、ピーククエリ /秒 (QPS) が63倍に増加します。 同時リクエスト数が8,000に達すると、データベースのパフォーマンスは46倍向上します。
シナリオ3: 8つのホット行と32コアCPU
このシナリオでは、32コアCPUが使用され、8つのホット行を更新するために同時要求が送信されます。 ホット行最適化機能が有効になった後、ピークQPSは20倍改善されます。
同時リクエストの数が16,000に達すると、データベース障害が発生し、ホット行最適化機能を無効にしても結果は返されません。 ただし、ホット行最適化を有効にすると、行データは期待どおりに更新され、QPSは安定したままです。