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

Tair (Redis® OSS-Compatible):ApsaraDB for Redisクラスターインスタンスのデータスキューの処理

最終更新日:Sep 26, 2024

ApsaraDB for Redisクラスターインスタンスの特定のデータノードのメモリ使用率、CPU使用率、帯域幅使用率などのパフォーマンスメトリックが他のデータノードよりもはるかに高い場合、ApsaraDB for Redisクラスターインスタンスにデータスキューの問題が発生する可能性があります。 インスタンスデータがひどく歪んでいる場合、インスタンスのメモリ使用量が少ない場合でも、キーの削除、メモリ不足 (OOM) エラー、応答の延長などの例外が発生する可能性があります。

迅速な取り扱い

このセクションでは、データスキューが存在するかどうかを確認する方法と、大きなキーを識別して処理する方法について説明します。

  1. インスタンスの詳細ページの左側のナビゲーションウィンドウで、[CloudDBA] > [リアルタイムパフォーマンス] を選択し、メモリ使用率 メトリックがデータノード間でバランスしているかどうかを確認します。

    この例では、db-0データノードのメモリ使用率のメトリックは、他のデータノードのメトリックよりも大幅に高くなっています。 これは、インスタンスでデータスキューが発生したことを示します。 image

    説明

    インスタンス診断機能を使用して、現在のインスタンスにデータスキューが存在するかどうかを確認することもできます。 詳細については、「」「診断レポートの作成」をご参照ください。

  2. 各データノードのキーの総数を表示します。

    この例では、キーの総数は、db-0が2.59百万、db-1が2.60百万、db-2が2.59百万である。 キーは、データノードにわたって均等に分散される。 この場合、db-0データノードは大きな鍵を有する可能性が高い。

    説明

    キーがデータノード間で不均一に分散されている場合、ビジネスロジックのキー名デザインに問題がある可能性があります。 例えば、ハッシュタグの使用は、巡回冗長検査 (CRC) アルゴリズムが配布のために使用されるとき、クライアントに同じデータノードにすべてのキーをルーティングさせることができる。 この場合、キー名に {} を使用しないように、アプリケーションレベルで調整する必要があります。

  3. オフラインキー分析機能を使用して、大きなキーをすばやく識別します。

    この機能は、オンラインビジネスに影響を与えることなく、インスタンスのバックアップファイルを分析します。 分析が完了したら、上部500の大きなキーを表示できます。 この例では、mylistという名前のキーが大きなキーとして識別されます。

    image

  4. (オプション) クエリと分析のために特定のデータノードに接続します。

    • プロキシモードのクラスターインスタンスの場合、Alibaba Cloudが社内で開発したISCANコマンドを使用して、指定されたデータノードでSCANコマンドを実行できます。 詳細については、「プロキシモードのApsaraDB For Redisインスタンスの社内コマンド」をご参照ください。

    • 直接接続モードのクラスターインスタンスの場合、DescribeDBNodeDirectVipInfo操作を呼び出して各データノードの仮想IPアドレス (VIP) を取得し、分析のためにクライアントをデータノードに接続できます。

  5. 次のいずれかのソリューションを使用します。

    • 暫定ソリューション: インスタンス仕様をアップグレードします。

    • 長期ソリューション (推奨): 大きなキーを適切に分割してビジネスロジックを再構築します。

データスキューの問題の原因と解決策の詳細については、次のセクションを参照してください。 このトピックは、標準インスタンスのメモリ使用率、CPU使用率、帯域幅使用率、レイテンシなどの高性能メトリックに関連する問題のトラブルシューティングにも適しています。

データスキューが発生するのはなぜですか?

ApsaraDB for Redisクラスターインスタンスは分散アーキテクチャを使用します。 クラスターインスタンスのストレージスペースは16,384個のスロットに分割されます。 各データノードは、データを特定のスロットに格納して処理する。 たとえば、3シャードクラスタインスタンスでは、スロットは次のように3つのシャードに分散されます。最初のシャードは [0,5460] 範囲のスロットを処理し、2番目のシャードは [5461,10922] 範囲のスロットを処理し、3番目のシャードは [10923,16383] 範囲のスロットを処理します。 クラスターインスタンスにキーを書き込むか、クラスターインスタンスのキーを更新すると、クライアントは次の式を使用してキーが属するスロットを決定します。slot=CRC16(key)% 16384 次に、クライアントは、スロットが属するデータノードにキーを書き込む。 理論的には、このメカニズムはキーをデータノード間で均等に分散し、メモリ使用量やCPU使用率などのメトリックの値をすべてのデータノードでほぼ同じレベルに維持するのに十分です。

ただし、実際には、高度な計画の欠如、異常なデータ書き込み、またはデータアクセスの急増により、データスキューが発生する可能性があります。

説明
  • 通常、データスキューは、特定のデータノードのリソースが他のデータノードのリソースと比較して高い需要にあるときに発生します。 データノードのメトリックは、コンソールの [パフォーマンスモニター] ページの データノード タブで表示できます。 データノードのメトリックが他のデータノードのメトリックよりも一貫して20% に高い場合、データスキューが存在する可能性があります。 データスキューの重大度は、異常データノードと正常データノードのメトリックの差に比例します。

  • 単一のデータノードのメモリ使用量が100% に達すると、データノードはデータ追い出しをトリガする。 デフォルトの削除ポリシーはvolatile-lruです。

次の図は、2つの典型的なデータスキューシナリオを示します。 キーはクラスターインスタンス全体に均等に分散されますが (データノードごとに2つのキー) 、データスキューは依然として発生します。

image
  • Shard 1データノードのkey1の1秒あたりのクエリ数 (QPS) は、他のキーのクエリ数よりもはるかに多くなります。 これはデータアクセススキューの場合であり、データノードでのCPU使用率と帯域幅の使用率が高くなる可能性があります。 これは、データノード上のすべてのキーのパフォーマンスに影響します。

  • Shard2データノードのkey5のサイズは1 MBで、他のキーよりもはるかに大きくなっています。 これは、データボリュームスキューの場合と見なされ、データノードでのメモリと帯域幅の使用量が高くなる可能性があります。 これは、データノード上のすべてのキーのパフォーマンスに影響します。

暫定ソリューション

インスタンスでデータスキューが発生した場合は、短期的に問題を軽減するための暫定ソリューションを実装できます。

問題

考えられる原因

暫定ソリューション

メモリ使用量のスキュー

大きなキーとハッシュタグ

インスタンスの仕様をアップグレードします。 詳細については、「」「インスタンスの設定の変更」をご参照ください。

重要
  • ApsaraDB for Redisは、インスタンス仕様の変更中にデータスキューの事前チェックを開始します。 選択したインスタンスタイプがデータスキューの問題を処理できない場合、 ApsaraDB for Redisはエラーを報告します。 仕様の高いインスタンスタイプを選択して、もう一度お試しください。

  • インスタンス仕様をアップグレードすると、メモリ使用量のスキューが緩和される可能性があります。 しかしながら、スキューは、帯域幅およびCPUリソース上でも発生し得る。

帯域幅使用スキュー

大きなキー、ホットキー、およびリソース集約型のコマンド

1つ以上のデータノードの帯域幅を増やします。 詳細については、「」「インスタンスの帯域幅を手動で増やす」をご参照ください。

説明

データノードの帯域幅は、インスタンスのデフォルト帯域幅の最大6倍に増やすことができますが、帯域幅の増加は192 Mbit/sを超えることはできません。 それでもこの方法でデータスキューの問題が解決されない場合は、アプリケーションレベルで調整することをお勧めします。

CPU使用率スキュー

大きなキー、ホットキー、およびリソース集約型のコマンド

  • ホットキーが異なるスロットに分散されている場合は、オフピーク時にデータノードを追加して、システム全体でより均等に負荷を分散します。

  • リソース集約型のコマンドを最適化します。 たとえば、SCANコマンドごとに取得されるキーの数を減らします。

説明

スケーリング中に発生するデータ移行プロセスがかなりのCPUリソースを消費する可能性があるため、オフピーク時にインスタンスをスケーリングします。

データスキューに一時的に対処するために、大きなキーとホットキーの要求を減らすこともできます。 大きなキーとホットキーに関連する問題を解決するには、アプリケーションレベルで調整する必要があります。 インスタンスのデータスキューの原因を迅速に特定し、アプリケーションレベルで問題を処理してインスタンスのパフォーマンスを最適化することを推奨します。 詳細については、このトピックの [原因と解決策] セクションを参照してください。

原因と解決策

データスキューの根本的な原因を解決するために、ビジネスの成長を評価し、将来の成長に必要な準備をすることをお勧めします。 大きなキーを分割して, 想定した用途に合わせてデータを書き込むことができます。

原因

説明

解決策

大きなキー

大きなキーは、キーのサイズおよびキー内のメンバーの数に基づいて識別される。

通常、大きなキーは、Hash、List、Set、Zsetなどのキー値データ構造では一般的です。 大きなキーは、これらの構造が多数のフィールドまたは過度に大きなフィールドを格納する場合に発生します。 大きなキーは、データスキューの主な原因の1つです。

ビジネスに影響を与えずに大きなキーまたはホットキーを適切に削除する方法の詳細については、「」「大きなキーとホットキーの識別と処理」をご参照ください。

  • 大きなキーの発生を防ぎます。

  • 数万のメンバーを含むハッシュキーを、管理可能な数のメンバーを持つ複数のハッシュキーに分割します。

ホットキー

ホットキーは、他のキーよりもはるかに高いQPS値を持つキーです。 ホットキーは、単一のキーのストレステスト中、または人気のある製品IDを含むフラッシュ販売シナリオでよく見られます。 ホットキーの詳細については、「」「ラージキーとホットキーの識別と処理」をご参照ください。

  • ホットキーの発生を防ぎます。

  • Tairのプロキシクエリキャッシュ機能を使用して、ホットデータをキャッシュします。 詳細については、「」「ラージキーとホットキーの最適化」をご参照ください。

リソース集約型コマンド

各コマンドには、リソースと時間消費を測定する時間複雑度と呼ばれるメトリックがあります。 ほとんどの場合、コマンドの時間の複雑さが高いほど、コマンドが消費するリソースは多くなります。 例えば、HGETALLコマンドの時間複雑度はO(n) である。 これは、コマンドに指定されたフィールドの数に比例してコマンドがリソースを消費することを示します。 同様に、SETまたはGETコマンドに大量のデータが含まれる場合、コマンドは大量のデータノードリソースを消費します。

  • データノードの低速クエリログを照会します。 詳細については、「」「スローログの照会」をご参照ください。

  • 大量のパフォーマンスリソースを消費するコマンドを表示するには、レイテンシインサイト機能を使用します。 詳細については、「遅延インサイト」「」をご参照ください。

  • リソース集約型のコマンドは使用しないでください。 特定のコマンドを無効にするには、パラメーター設定 ページで #no_loose_disabled-commandsパラメーターを設定します。

ハッシュタグ

Tairは、キー名の {} 部分に含まれる内容に基づいて、特定のデータノードにキーを配布します。 たとえば、{item}id1{item}id2、および {item}id3キーは、同じ {} コンテンツを共有するため、同じデータノードに格納されます。 その結果、このデータノードのメモリ使用量とリソース消費量が大幅に増加します。

  • キー名に {} を使用しないでください。

    説明

    キー名に {} を使用する場合は、キーごとに {} の内容が異なることを確認してください。 これにより、複数のデータノードにキーを保存できます。

よくある質問

  • 大きなキーを持つクラスターインスタンスでは、大きなキーが存在するデータノードの仕様をアップグレードできますか。

    いいえ。 Tairでは、個々のデータノードの仕様を個別にアップグレードすることはできません。 インスタンス内のすべてのデータノードの仕様の同時アップグレードのみが可能です。

  • データノードを追加してキーを再配布し、クラスターインスタンス内の大きなキーを削除できますか?

    いいえ。 データノードを追加すると、既存のデータノードからのメモリ負荷を軽減できますが、Tairはキーレベルでデータを分散します。つまり、大きなキーを自動的に分割することはできません。 その結果、キーが再配布された後でも、1つのデータノードが他のものよりも高いメモリ使用量を有することがあり、データスキューが生じる。 推奨されるアプローチは、大きなキーを小さなキーに手動で分割することです。