永続的な接続の問題 - Amazon ElastiCache

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

永続的な接続の問題

での永続的な接続問題のトラブルシューティング中に、次の項目を検証する必要があります ElastiCache。

セキュリティグループ

セキュリティグループは、 ElastiCache クライアント (EC2インスタンス、 AWS Lambda 関数、Amazon ECSコンテナなど) と ElastiCache キャッシュを保護する仮想ファイアウォールです。セキュリティグループはステートフルです。つまり、着信トラフィックまたは発信トラフィックが許可されると、そのトラフィックに対する応答は、その特定のセキュリティグループのコンテキストで自動的に承認されます。

ステートフル機能では、セキュリティグループがすべての許可された接続を追跡し続ける必要があり、追跡される接続には制限があります。制限に到達すると、新しい接続は失敗します。クライアントまたは ElastiCache 側で制限がヒットしたかどうかを確認する方法については、トラブルシューティングセクションを参照してください。

クライアントと ElastiCache クラスターに同時に単一のセキュリティグループを割り当てるか、それぞれに個別のセキュリティグループを割り当てることができます。

どちらの場合も、送信元からの ElastiCache ポートのTCPアウトバウンドトラフィックと、同じポートのインバウンドトラフィックを に許可する必要があります ElastiCache。デフォルトのポートは、Memcached の場合は 11211、Valkey または Redis の場合は 6379 ですOSS。デフォルトで、セキュリティグループはすべてのアウトバウンドトラフィックを許可します。この場合、ターゲットセキュリティグループのインバウンドルールのみが必要です。

詳細については、「Amazon の ElastiCache クラスターにアクセスするためのアクセスパターンVPC」を参照してください。

ネットワーク ACLs

ネットワークアクセスコントロールリスト (ACLs) はステートレスルールです。トラフィックを成功させるには、両方向 (インバウンドとアウトバウンド) で許可する必要があります。ネットワークACLsは、特定のリソースではなくサブネットに割り当てられます。特に同じサブネット内にある場合は、 ElastiCache とクライアントリソースに同じ ACL を割り当てることができます。

デフォルトでは、ネットワークはすべてのトラフィックACLsを許可します。ただし、トラフィックを拒否または許可するようにカスタマイズすることは可能です。さらに、ACLルールの評価はシーケンシャルです。つまり、トラフィックと一致する最小数を持つルールは、ルールを許可または拒否します。Valkey または Redis OSSトラフィックを許可する最小設定は次のとおりです。

クライアント側のネットワークACL:

  • インバウンドルール:

  • ルール番号: 好ましくは拒否ルールよりも低い。

  • タイプ: カスタムTCPルール

  • プロトコル: TCP

  • [Port Range]: 1024~65535

  • ソース: 0.0.0.0/0 (または ElastiCache クラスターサブネットの個別ルールを作成する)

  • [許可/拒否]: 許可

  • アウトバウンドルール:

  • ルール番号: 好ましくは拒否ルールよりも低い。

  • タイプ: カスタムTCPルール

  • プロトコル: TCP

  • [Port Range]: 6379

  • ソース: 0.0.0.0/0 (または ElastiCache クラスターサブネット。 特定の を使用すると、クラスターのフェイルオーバーやスケーリング時に問題が発生するIPs可能性があることに注意してください)

  • [許可/拒否]: 許可

ElastiCache ネットワークACL:

  • インバウンドルール:

  • ルール番号: 好ましくは拒否ルールよりも低い。

  • タイプ: カスタムTCPルール

  • プロトコル: TCP

  • [Port Range]: 6379

  • ソース: 0.0.0.0/0 (または ElastiCache クラスターサブネットの個別ルールを作成する)

  • [許可/拒否]: 許可

  • アウトバウンドルール:

  • ルール番号: 好ましくは拒否ルールよりも低い。

  • タイプ: カスタムTCPルール

  • プロトコル: TCP

  • [Port Range]: 1024~65535

  • ソース: 0.0.0.0/0 (または ElastiCache クラスターサブネット。 特定の を使用すると、クラスターのフェイルオーバーやスケーリング時に問題が発生するIPs可能性があることに注意してください)

  • [許可/拒否]: 許可

詳細については、「ネットワークACLs」を参照してください。

ルートテーブル

ネットワーク と同様にACLs、各サブネットには異なるルートテーブルを含めることができます。クライアントと ElastiCache クラスターが異なるサブネットにある場合は、それらのルートテーブルが互いに到達できることを確認してください。

複数の 、動的ルーティングVPCs、またはネットワークファイアウォールを含むより複雑な環境では、トラブルシューティングが困難になる場合があります。「ネットワーク接続性の検証」を参照して、ネットワーク設定が適切であることを確認してください。

DNS 解決

ElastiCache は、DNS名前に基づいてサービスエンドポイントを提供します。使用可能なエンドポイントは、ConfigurationPrimaryReader、および Node エンドポイントです。詳細情報については、「接続エンドポイントの検索」を参照してください。

フェイルオーバーまたはクラスターの変更の場合、エンドポイント名に関連付けられたアドレスが変更され、自動的に更新されます。

カスタムDNS設定 (つまり、 VPCDNSサービスを使用しない) では、 ElastiCacheが提供するDNS名前が認識されない場合があります。(次digに示すように) や などのシステムツールを使用して、システムが ElastiCache エンドポイントを正常に解決できることを確認しますnslookup

$ dig +short example.xxxxxx.ng.0001.use1.cache.amazonaws.com example-001.xxxxxx.0001.use1.cache.amazonaws.com. 1.2.3.4

VPC DNS サービスを通じて名前解決を強制することもできます。

$ dig +short example.xxxxxx.ng.0001.use1.cache.amazonaws.com @169.254.169.253 example-001.tihewd.0001.use1.cache.amazonaws.com. 1.2.3.4

サーバー側の診断に関する問題の特定

CloudWatch ElastiCache エンジンからのメトリクスとランタイム情報は、接続問題の潜在的な原因を特定するための一般的なソースまたは情報です。適切な分析は、通常、次の項目から始まります。

  • CPU 使用状況: Valkey と Redis OSSはマルチスレッドアプリケーションです。ただし、各コマンドの実行は単一の (メイン) スレッドで行われます。このため、 はメトリクスCPUUtilizationと ElastiCache を提供しますEngineCPUUtilizationEngineCPUUtilizationは、Valkey または Redis OSSプロセス専用のCPU使用率と、すべての のCPUUtilization使用状況を提供しますvCPUs。複数の vCPU を持つノードは通常、 CPUUtilizationと の値が異なるためEngineCPUUtilization、2 つ目は通常高くなります。高 は、リクエスト数の増加や、完了までにかなりCPUの時間がかかる複雑な操作が原因EngineCPUUtilizationである可能性があります。両方を特定するには、以下を使用します。

    • リクエスト数の上昇: EngineCPUUtilization パターンに一致する他のメトリクスでの上昇がないか確認します。役に立つメトリクスは次のとおりです。

      • CacheHitsCacheMisses: 成功したリクエスト数、またはキャッシュで有効な項目を見つけられなかったリクエスト数。ヒットに対するミスの比率が高い場合、アプリケーションは実りのないリクエストで時間とリソースを浪費しています。

      • SetTypeCmdsGetTypeCmds: EngineCPUUtilization と相関しているこれらのメトリクスは、SetTypeCmds によって測定された書き込みリクエスト、または GetTypeCmds によって測定された読み取りに対して負荷が著しく高いかどうかを理解するのに役立ちます。負荷が主に読み取りである場合、複数のリードレプリカを使用すると、複数のノード間でリクエストをバランスさせ、プライマリを書き込み用に取っておくことができます。クラスターモードが無効になっているクラスターでは、 ElastiCache リーダーエンドポイントを使用してアプリケーションに追加の接続設定を作成することで、リードレプリカを使用できます。詳細情報については、「接続エンドポイントの検索」を参照してください。読み取りオペレーションは、この追加の接続に送信する必要があります。書き込みオペレーションは、通常のプライマリエンドポイントを介して実行されます。クラスターモードが有効の場合、リードレプリカをネイティブにサポートするライブラリを使用することをお勧めします。適切なフラグを使用すると、ライブラリはクラスタートポロジー、レプリカノードを自動的に検出し、READONLYValkey または Redis OSS コマンドを使用して読み取りオペレーションを有効にし、読み取りリクエストをレプリカに送信できます。

    • 昇格された接続数:

      • CurrConnectionsNewConnections: CurrConnection はデータポイント収集時に確立された接続の数であり、NewConnections はその期間に作成された接続数を示します。

        接続の作成と処理は、大幅なCPUオーバーヘッドを意味します。さらに、新しい接続の作成に必要な TCP3 方向ハンドシェイクは、全体的な応答時間に悪影響を及ぼします。

        1 分NewConnectionsあたり数千の ElastiCache ノードは、接続が作成され、いくつかのコマンドによって使用されることを示しますが、最適ではありません。確立された接続を維持し、新しいオペレーションのために接続を再使用することがベストプラクティスです。これは、クライアントアプリケーションが接続プーリングまたは永続的な接続をサポートし、適切に実装している場合に可能です。接続プーリングでは、currConnections の数には大きなバリエーションがないので、NewConnections をできる限り低くする必要があります。Valkey と Redis は、少数の で最適なパフォーマンスOSSを提供しますcurrConnections。数十から数百の順序 currConnection で保持すると、クライアントバッファや接続に役立つCPUサイクルなどの個々の接続をサポートするリソースの使用が最小限に抑えられます。

    • ネットワークスループット:

      • 帯域幅: ElastiCache ノードのネットワーク帯域幅がノードサイズに比例することを確認します。アプリケーションの特性が異なるため、結果はワークロードに応じて異なる場合があります。例えば、小さなリクエストのレートが高いアプリケーションは、ネットワークスループットよりもCPU使用量に影響する傾向があり、キーが大きいほどネットワーク使用率が向上します。そのため、制限をよりよく理解するために、実際のワークロードでノードをテストすることをお勧めします。

        アプリケーションからの負荷をシミュレートすると、より正確な結果が得られます。ただし、ベンチマークツールは、制限についての良いアイデアを提供することができます。

      • リクエストが主に読み取りの場合、読み取りオペレーションでレプリカを使用すると、プライマリノードの負荷が軽減されます。ユースケースが主に書き込みの場合、多くのレプリカを使用するとネットワークの使用が増大します。プライマリノードに書き込まれるすべてのバイトについて、N バイトがレプリカに送信され、ここで N はレプリカの数になります。書き込み集約型ワークロードのベストプラクティスは ElastiCache 、 (Redis OSS) を使用してクラスターモードを有効にし、複数のシャード間で書き込みのバランスを取るか、より多くのネットワーク機能を持つノードタイプにスケールアップすることです。

      • および CloudWatchmetrics NetworkBytesInは、ノードに出入りするデータ量をそれぞれNetworkBytesOut提供します。 ReplicationBytesは、データレプリケーション専用のトラフィックです。

      詳細については、「ネットワーク関連の制限」を参照してください。

    • 複雑なコマンド: Redis OSS コマンドは 1 つのスレッドで提供されます。つまり、リクエストは順番に提供されます。単一のスローコマンドは、他のリクエストや接続に影響を及ぼし、タイムアウトが発生する可能性があります。複数の値、キー、またはデータ型に作用するコマンドの使用は、慎重に行う必要があります。接続は、パラメータの数や入出力値のサイズに応じて、ブロックまたは終了できます。

      評判の悪い例は、KEYS コマンドです。これは、指定されたパターンを検索するキースペース全体をスイープし、その実行中に他のコマンドの実行をブロックします。Redis OSSは「ビッグ O」表記を使用して、コマンドの複雑さを記述します。

      キーコマンドには O(N) 時間の複雑さがあり、ここで N はデータベース内のキーの数になります。したがって、キーの数が多いほど、コマンドは遅くなります。KEYS は、さまざまな方法で問題を引き起こす可能性があります。検索パターンが使用されていない場合、コマンドは利用可能なすべてのキー名を返します。数千または数百万の項目を含むデータベースでは、巨大な出力が作成され、ネットワークバッファがフラッディングします。

      検索パターンを使用すると、パターンに一致するキーのみがクライアントに戻ります。ただし、エンジンはキースペース全体のスイープを続けるので、コマンドを完了する時間は同じになります。

      KEYS の代替は、SCAN コマンドです。これは、キースペースを反復し、特定の数の項目の反復を制限して、エンジン上の長引くブロックを回避します。

      スキャンには COUNT パラメータがあり、反復ブロックのサイズを設定するために使用されます。デフォルト値は 10 (1 回の反復あたり 10 個のアイテム) です。

      データベース内の項目数に応じて、小さな COUNT 値のブロックは、フルスキャンを完了するために多くの反復を必要とし、値を大きくすると、各反復でエンジンをビジー状態でより長く維持します。小さなカウント値は大きなデータベースで SCAN をより遅くしますが、値を大きくすると KEYS で説明されたものと同じ問題が生じる可能性があります。

      例として、10 のカウント値がある SCAN コマンドの実行は、100 万個のキーがあるデータベースでの 100,000 回の繰り返しを必要とします。平均ネットワークラウンドトリップ時間が 0.5 ミリ秒の場合、リクエストの転送に約 50,000 ミリ秒(50 秒)が費やされます。

      一方、カウント値が 100,0000 であった場合、1 回の反復が必要で、転送に費やされる時間はわずか 0.5 ミリ秒です。ただし、コマンドがすべてのキースペースのスイープを終了するまで、エンジンは他のオペレーションのために完全にブロックされます。

      KEYS に加えて、いくつかの他のコマンドは、正しく使用されない場合、潜在的に有害になります。すべてのコマンドとその時間の複雑さのリストを確認するには、「Valkey コマンド」と「Redis OSS コマンド」を参照してください。

      潜在的な問題の例:

      • Lua スクリプト: Valkey と Redis OSSは埋め込み Lua インタープリタを提供し、サーバー側のスクリプトの実行を許可します。Valkey および Redis の Lua スクリプトOSSはエンジンレベルで実行され、定義上原子です。つまり、スクリプトの実行中に他のコマンドやスクリプトを実行することはできません。Lua スクリプトは、複数のコマンド、意思決定アルゴリズム、データ解析などをエンジン上で直接実行する可能性を提供します。スクリプトのアトミック性とアプリケーションのオフロードの機会は魅力的ですが、スクリプトは小さなオペレーションでは注意を払って使用する必要があります。では ElastiCache、Lua スクリプトの実行時間は 5 秒に制限されます。キースペースに書き込まれていないスクリプトは、5 秒後に自動的に終了します。データの破損や不整合を避けるため、スクリプトの実行が 5 秒以内に完了せず、実行中に書き込みがあった場合、ノードはフェイルオーバーします。トランザクションは、Redis の複数の関連するキー変更の一貫性を保証する代替手段ですOSS。トランザクションは、コマンドのブロックの実行を可能にし、既存のキーの変更を監視します。トランザクションの完了前に監視キーのいずれかが変更された場合、すべての変更は破棄されます。

      • アイテムの一括削除: DEL コマンドは、削除するキー名である複数のパラメータを受け入れます。削除オペレーションは同期的であり、パラメータのリストが大きい場合、または大きなリスト、セット、ソートされたセット、ハッシュ (複数のサブ項目を含むデータ構造) が含まれている場合、かなりCPUの時間がかかります。言い換えれば、単一のキーを削除しても、多くの要素がある場合、多くの時間がかかることがあります。の代替DEL手段は です。これは UNLINKRedis OSS4 以降に利用可能な非同期コマンドです。 はDEL可能な限り よりも優先UNLINKする必要があります。 ElastiCache (Redis OSS) 6x 以降、 lazyfree-lazy-user-delパラメータは、有効UNLINKになっているときにDELコマンドの動作を のようにします。詳細については、「Redis OSS 6.0 パラメータの変更」を参照してください。

      • 複数のキーに作用するコマンド: DEL は、複数の引数を受け入れるコマンドとして前述されており、実行時間はそれに正比例します。ただし、Redis OSSには、同様の動作をするコマンドが他にも多数用意されています。例として、MSETMGET を使用すると、一度に複数の String キーを挿入または取得できます。これらの使用は、複数の個別の SET または GET コマンドに固有のネットワーク遅延を低減するために有益である可能性があります。ただし、パラメータの広範なリストはCPU使用状況に影響します。

        CPU 使用率だけでは接続の問題は発生しませんが、複数のキーで 1 つまたは少数のコマンドを処理するのに時間がかかりすぎると、他のリクエストが失敗し、全体的なCPU使用率が高くなる可能性があります。

        キーの数とそのサイズは、コマンドの複雑さ、また結果として完了時間に影響します。

        複数のキーに対して作用できるコマンドのその他の例: HMGETHMSETMSETNXPFCOUNTPFMERGESDIFFSDIFFSTORESINTERSINTERSTORESUNIONSUNIONSTORETOUCHZDIFFZDIFFSTOREZINTER または ZINTERSTORE

      • 複数のデータ型で動作するコマンド: Redis は、データ型に関係なく、1 つ以上のキーで動作するコマンドOSSも提供します。 ElastiCache (Redis OSS) は、このようなコマンドをモニタリングKeyBasedCmdsするためのメトリクスを提供します。このメトリクスは、選択した期間における次のコマンドの実行を合計します。

        • O(N) の複雑さ:

          • KEYS

        • O(1)

          • EXISTS

          • OBJECT

          • PTTL

          • RANDOMKEY

          • TTL

          • TYPE

          • EXPIRE

          • EXPIREAT

          • MOVE

          • PERSIST

          • PEXPIRE

          • PEXPIREAT

          • UNLINK (O(N) により、メモリを再利用します。しかし、メモリ再利用タスクは分離されたスレッドで発生し、エンジンをブロックしません

        • データ型によって異なる複雑さの時間:

          • DEL

          • DUMP

          • RENAME は O(1) の複雑さがあるコマンドとみなされますが、DEL を内部で実行します。実行時間は、名前が変更されたキーのサイズによって異なります。

          • RENAMENX

          • RESTORE

          • SORT

        • 大きなハッシュ: ハッシュは、複数のキー値サブ項目がある単一のキーを可能にするデータ型です。各ハッシュは 4.294.967.295 項目を格納することができ、大きなハッシュでのオペレーションは費用がかかる可能性があります。KEYS と同様に、ハッシュは O(N) 時間の複雑さがある HKEYS コマンドを持ち、ここで N はハッシュ内の項目数になります。長時間実行されるコマンドを避けるために、HSCANHKEYS より優先される必要があります。HDELHGETALLHMGETHMSET および HVALS は、大きなハッシュで注意して使用する必要があるコマンドです。

      • その他のビッグデータ構造: ハッシュに加えて、他のデータ構造も大量CPUになる可能性があります。セット、リスト、ソートされたセット、およびハイパーログログも、そのサイズと使用されるコマンドによっては、操作に多くの時間がかかることがあります。これらのコマンドの詳細については、「Valkey コマンドと Redis OSS コマンド」を参照してください。

ネットワーク接続性の検証

DNS 解決、セキュリティグループ、ネットワーク ACLs、ルートテーブルに関連するネットワーク設定を確認した後、VPCReachability Analyzer とシステムツールを使用して接続を検証できます。

Reachability Analyzer は、ネットワーク接続性をテストし、すべての要件と許可が満たされているかどうかを確認します。以下のテストでは、 で使用可能な ElastiCache ノードの 1 つの ENI ID (Elastic Network Interface Identification) が必要ですVPC。それを見つけるには、以下の操作を行います。

  1. https://console.aws.amazon.com/ec2/v2/home に移動しますか?#NIC:

  2. インターフェイスリストを ElastiCache クラスター名または以前にDNS検証した IP アドレスでフィルタリングします。

  3. ENI ID を書き留めるか、保存してください。複数のインターフェイスが表示されている場合は、説明を確認して正しい ElastiCache クラスターに属することを確認し、その 1 つを選択します。

  4. 次のステップに進みます。

  5. https://console.aws.amazon.com/vpc/自宅で分析パスを作成しますか?#ReachabilityAnalyzer で、次のオプションを選択します。

    • ソースタイプ : ElastiCache クライアントが Amazon EC2インスタンスで実行されている場合、または awsvpc ネットワークECSを使用する AWS Fargate Amazon などの別のサービスを使用している場合はネットワークインターフェイスで実行されている場合 AWS Lambda、インスタンスを選択します)、およびそれぞれのリソース ID (EC2インスタンスまたは ENI ID)。

    • 送信先タイプ : ネットワークインターフェイスを選択し、リストから Elasticache ENI を選択します。

    • 送信先ポート : ElastiCache (Redis OSS) には 6379、 ElastiCache (Memcached) には 11211 を指定します。これらはデフォルト設定で定義されたポートであり、この例では、変更されていないことを前提としています。

    • プロトコル : TCP

分析パスを作成し、結果まで数分待ちます。ステータスが到達不能の場合は、解析の詳細を開き、[解析エクスプローラ] で、リクエストがブロックされた場所の詳細を確認してください。

到達可能性テストに合格した場合は、OS レベルでの検証に進みます。

ElastiCache サービスポートTCPの接続を検証するには: Amazon Linux では、 Npingがパッケージで利用可能nmapで、 ElastiCache ポートTCPの接続をテストできるだけでなく、接続を確立するためのネットワーク往復時間も指定できます。これを使用して、次に示すように、ネットワーク接続と ElastiCache クラスターへの現在のレイテンシーを検証します。

$ sudo nping --tcp -p 6379 example.xxxxxx.ng.0001.use1.cache.amazonaws.com Starting Nping 0.6.40 ( http://nmap.org/nping ) at 2020-12-30 16:48 UTC SENT (0.0495s) TCP ... (Output suppressed ) Max rtt: 0.937ms | Min rtt: 0.318ms | Avg rtt: 0.449ms Raw packets sent: 5 (200B) | Rcvd: 5 (220B) | Lost: 0 (0.00%) Nping done: 1 IP address pinged in 4.08 seconds

デフォルトでは、nping は、5 つのプローブをそれらの間で 1 秒の遅延で送信します。オプション「-c」を使用してプローブ数を増やし、「—delay」を使用して新しいテストを送信するための時間を変更できます。

テストがnping失敗し、VPCReachability Analyzer テストに合格した場合は、ホストベースのファイアウォールルール、非対称ルーティングルール、またはオペレーティングシステムレベルでのその他の制限を確認するようシステム管理者に依頼してください。

ElastiCache コンソールで、 ElastiCache クラスターの詳細で転送中の暗号化が有効になっているかどうかを確認します。転送中の暗号化が有効になっている場合は、次のコマンドを使用してTLSセッションを確立できるかどうかを確認します。

openssl s_client -connect example.xxxxxx.use1.cache.amazonaws.com:6379

接続とTLSネゴシエーションが成功すると、広範な出力が期待されます。最後の行で利用可能な戻りコードを確認してください。値は 0 (ok) である必要があります。openssl が別のものを返します。エラーの原因を https://www.openssl.org/docs/man1.0.2/man1/verify.html#DIAGNOSTICS で確認してください。

すべてのインフラストラクチャとオペレーティングシステムのテストに合格してもアプリケーションが に接続できない場合は ElastiCache、アプリケーション設定が ElastiCache 設定に準拠しているかどうかを確認します。よくある間違いは次のとおりです。

  • アプリケーションは ElastiCache クラスターモードをサポートしておらず、クラスターモードが有効になってい ElastiCache ます。

  • アプリケーションは TLS/ をサポートしておらずSSL、転送中の暗号化が有効になってい ElastiCache ます。

  • アプリケーションは TLS/SSL をサポートしていますが、適切な設定フラグや信頼できる認証機関はありません。

ネットワーク関連の制限

  • 最大接続数: 同時接続にはハード制限があります。各 ElastiCache ノードでは、すべてのクライアント間で最大 65,000 の同時接続が可能です。この制限は、 のCurrConnectionsメトリクスを通じてモニタリングできます CloudWatch。ただし、クライアントにはアウトバウンド接続にも制限があります。Linux では、次のコマンドを使用して、許可されているエフェメラルポート範囲を確認してください。

    # sysctl net.ipv4.ip_local_port_range net.ipv4.ip_local_port_range = 32768 60999

    前の例では、28231 接続は同じ送信元から同じ送信先 IP (ElastiCache ノード) とポートに許可されます。次のコマンドは、特定の ElastiCache ノード (IP 1.2.3.4) にいくつの接続が存在するかを示します。

    ss --numeric --tcp state connected "dst 1.2.3.4 and dport == 6379" | grep -vE '^State' | wc -l

    この数値が大きすぎると、接続リクエストを処理しようとしてシステムが過負荷になることがあります。接続をより適切に処理するために、接続プーリングや永続的な接続などの技術の実装を検討することをお勧めします。いつでも可能な限り、接続プールを設定して、接続の最大数を数百に制限します。また、タイムアウトやその他の接続例外を処理するためのバックオフロジックは、問題が発生した場合に接続チャーンを避けるようにすることをお勧めします。

  • ネットワークトラフィックの制限: CloudWatch Redis の次のメトリクスOSSを確認して、 ElastiCache ノードでヒットする可能性のあるネットワーク制限を特定します。

    • NetworkBandwidthInAllowanceExceeded/NetworkBandwidthOutAllowanceExceeded: スループットが集約された帯域幅制限を超えたためにシェーピングされたネットワークパケット。

      プライマリノードに書き込まれるすべてのバイトが N 個のレプリカに複製されることに注意することが重要で、ここで N はレプリカの数になります。小さなノードタイプ、複数のレプリカ、および集中的な書き込みリクエストがあるクラスターは、レプリケーションのバックログに対処できない場合があります。このような場合は、スケールアップ (ノードタイプを変更する)、スケールアウト (クラスターモードが有効なクラスターにシャードを追加する)、レプリカの数を減らす、または書き込み数を最小限に抑えることがベストプラクティスです。

    • NetworkConntrackAllowanceExceeded: ノードに割り当てられたすべてのセキュリティグループで追跡される接続の最大数を超過したため、パケットがシェーピングされます。この期間中、新しい接続が失敗する可能性があります。

    • NetworkPackets PerSecondAllowanceExceeded: 1 秒あたりの最大パケット数を超えています。非常に小さなリクエストの高いレートに基づくワークロードは、最大帯域幅よりも前にこの制限にヒットした可能性があります。

    上記のメトリクスは、ノードがネットワーク制限にヒットしていることを確認するための理想的な方法です。ただし、制限はネットワークメトリクスのプラトーによっても特定できます。

    プラトーが長期間観察されると、レプリケーションの遅延、キャッシュに使用されるバイトの増加、空きメモリのドロップ、スワップの増加、CPU使用量の増加が続く可能性があります。Amazon EC2インスタンスには、ENAドライバーメトリクス を通じて追跡できるネットワーク制限もあります。ネットワークサポートが強化され、ENAドライバーが 2.2.10 以降の Linux インスタンスは、 コマンドを使用して制限カウンターを確認できます。

    # ethtool -S eth0 | grep "allowance_exceeded"

CPU 使用状況

CPU 使用状況メトリクスは調査の出発点であり、以下の項目は ElastiCache 、側で発生する可能性のある問題を絞り込むのに役立ちます。

  • Redis OSS SlowLogs: ElastiCache デフォルト設定では、完了までに 10 ミリ秒以上かかった最後の 128 コマンドが保持されます。スローコマンドの履歴は、エンジンランタイム中は保持され、障害や再起動時に失われます。リストが 128 エントリに達すると、古いイベントは削除され、新しいイベントのためのスペースが開きます。スローイベントのリストとスローとみなされる実行時間のサイズは、[カスタムパラメータグループ] のパラメータ slowlog-max-len および slowlog-log-slower-than を介して変更できます。スローログのリストは、エンジンで SLOWLOG GET 128 を実行して取得でき、ここで 128 は最後に報告された 128 のスローコマンドになります。各エントリには以下のフィールドがあります。

    1) 1) (integer) 1 -----------> Sequential ID 2) (integer) 1609010767 --> Timestamp (Unix epoch time)of the Event 3) (integer) 4823378 -----> Time in microseconds to complete the command. 4) 1) "keys" -------------> Command 2) "*" ----------------> Arguments 5) "1.2.3.4:57004"-> Source

    上記のイベントは 12 月 26 日 19:26:07 に発生しUTC、完了までに 4.8 秒 (4.823 ミリ秒) かかり、クライアント 1.2.3.4 からリクエストされたKEYSコマンドによって引き起こされました。

    Linux では、タイムスタンプはコマンド date で変換できます。

    $ date --date='@1609010767' Sat Dec 26 19:26:07 UTC 2020

    Python の場合:

    >>> from datetime import datetime >>> datetime.fromtimestamp(1609010767) datetime.datetime(2020, 12, 26, 19, 26, 7)

    または を使用する Windows の場合 PowerShell:

    PS D:\Users\user> [datetimeoffset]::FromUnixTimeSeconds('1609010767') DateTime : 12/26/2020 7:26:07 PM UtcDateTime : 12/26/2020 7:26:07 PM LocalDateTime : 12/26/2020 2:26:07 PM Date : 12/26/2020 12:00:00 AM Day : 26 DayOfWeek : Saturday DayOfYear : 361 Hour : 19 Millisecond : 0 Minute : 26 Month : 12 Offset : 00:00:00Ticks : 637446075670000000 UtcTicks : 637446075670000000 TimeOfDay : 19:26:07 Year : 2020

    短時間 (同じ分以下) での多くのスローコマンドは、懸念の理由になります。コマンドの性質と、それらを最適化する方法を確認してください (前の例を参照)。O(1) 時間の複雑さを持つコマンドが頻繁に報告される場合は、前述のCPU使用率が高い他の要因を確認してください。

  • レイテンシーメトリクス: ElastiCache (Redis OSS) は、さまざまなクラスのコマンドの平均レイテンシーをモニタリングするための CloudWatch メトリクスを提供します。データポイントは、カテゴリ内のコマンドの実行総数を期間内の合計実行時間で割って計算されます。レイテンシーメトリクスの結果は、複数のコマンドの集合であることを理解することが重要です。1 つのコマンドで、メトリクスに大きな影響を与えずに、タイムアウトのような予期しない結果が発生する可能性があります。このような場合、スローログイベントはより正確な情報源になります。次のリストには、使用可能なレイテンシーメトリクスと、それらに影響する各コマンドが含まれています。

    • EvalBasedCmdsLatency: Lua Script コマンド、、evalevalsha

    • GeoSpatialBasedCmdsLatency: geodist, geohash, geopos, georadius, georadiusbymember, geoadd;

    • GetTypeCmdsLatency: データ型に関係なくコマンドを読み取る

    • HashBasedCmdsLatency: hexists, hget, hgetall, hkeys, hlen, hmget, hvals, hstrlen, hdel, hincrby, hincrbyfloat, hmset, hset, hsetnx;

    • HyperLogLogBasedCmdsLatency: pfselftest, pfcount, pfdebug, pfadd, pfmerge;

    • KeyBasedCmdsLatency: 、dump、、exists、、、keysobjectpttl、、、、randomkey、、ttltypedelexpireexpireat、、、、、movepersistpexpirepexpireatrenamerenamenx、、、、restoreK、、、、sort、、、、、、 unlink

    • ListBasedCmdsLatency: lindex、llen、lrange、blpop、brpop、brpoplpush、linsert、lpop、lpush、lpushx、lrem、lset、ltrim、rpop、rpoplpush、rpush、rpushx。

    • PubSubBasedCmdsLatency: psubscribe、publish、pubsub、punsubscribe、subscribe、unsubscribe;

    • SetBasedCmdsLatency: scard, sdiff, sinter, sismember, smembers, srandmember, sunion, sadd, sdiffstore, sinterstore, smove, spop, srem, sunionstore;

    • SetTypeCmdsLatency: データ型に関係なくコマンドを書き込む

    • SortedSetBasedCmdsLatency: zcard, zcount, zrange, zrangebyscore, zrank, zrevrange, zrevrangebyscore, zrevrank, zscore, zrangebylex, zrevrangebylex, zlexcount, zadd. zincrby, zinterstore, zrem, zremrangebyrank, zremrangebyscore, zunionstore, zremrangebylex, zpopmax, zpopmin, bzpopmin, bzpopmax;

    • StringBasedCmdsLatency: bitcount, get, getbit, getrange, mget, strlen, substr, bitpos, append, bitop, bitfield, decr, decrby, getset, incr, incrby, incrbyfloat, mset, msetnx, psetex, set, setbit, setex, setnx, setrange;

    • StreamBasedCmdsLatency: xrange, xrevrange, xlen, xread, xpending, xinfo, xadd, xgroup, readgroup, xack, xclaim, xdel, xtrim, xsetid;

  • Redis OSSランタイムコマンド:

    • info commandstats: Redis OSS エンジンの起動後に実行されたコマンドのリスト、累積実行数、合計実行時間、およびコマンドあたりの平均実行時間を提供します。

    • client list: 現在接続されているクライアントのリスト、およびバッファの使用状況、最後に実行されたコマンドなどの関連情報を提供します。

  • より前のバックアップとレプリケーション: ElastiCache (Redis OSS) バージョンでは、フォークプロセス2.8.22を使用してバックアップを作成し、レプリカとの完全な同期を処理します。このメソッドは、書き込み集中的なユースケースのために多くのメモリオーバーヘッドが発生する可能性があります。

    ElastiCache Redis OSS2.8.22 以降、 はフォークレスバックアップとレプリケーションメソッド AWS を導入しました。新しい方法は、障害を防ぐために書き込みを遅らせる場合があります。どちらの方法でも、CPU使用率が高い期間が発生し、応答時間が長くなり、その結果、実行中にクライアントがタイムアウトする可能性があります。バックアップウィンドウの間にクライアントの障害が発生したか、または SaveInProgress メトリクスが期間内で 1 であったかどうかを常に確認してください。クライアントの問題やバックアップ障害の可能性を最小限にするために、使用率の低い期間でバックアップウィンドウをスケジュールすることをお勧めします。

サーバー側からの接続が終了している

デフォルトの ElastiCache (Redis OSS) 設定では、クライアント接続は無期限に確立されます。ただし、状況によっては、接続の終了が望ましい場合があります。例:

  • クライアントアプリケーションのバグにより、接続が忘れられ、アイドル状態で確立されたままになることがあります。これは「接続リーク」と呼ばれ、その結果は CurrConnections メトリクスで観測される確立された接続の数の着実な増加となります。この動作により、クライアントまたは ElastiCache 側で飽和が発生する可能性があります。クライアント側から即時修正ができない場合、一部の管理者は ElastiCache パラメータグループに「タイムアウト」値を設定します。タイムアウトは、アイドル接続が持続するために許容される時間 (秒単位) です。クライアントが期間中にリクエストを送信しない場合、Redis OSS エンジンは接続がタイムアウト値に達するとすぐに接続を終了します。タイムアウト値が小さいと、不要な切断が発生する場合があり、クライアントはそれらを適切に処理して再接続する必要があり、遅延が発生します。

  • キーの格納に使用されるメモリは、クライアントバッファと共有されます。大きなリクエストまたは応答があるスロークライアントは、バッファを処理するために多くの量のメモリを要求する場合があります。デフォルトの ElastiCache (Redis OSS) 設定では、通常のクライアント出力バッファのサイズは制限されません。maxmemory の制限にヒットした場合、エンジンはバッファの使用量を満たすために項目を削除しようとします。メモリが非常に低い状況では、 ElastiCache (Redis OSS) は、メモリを解放し、クラスターの状態を維持するために、大きなクライアント出力バッファを消費するクライアントを切断することを選択する場合があります。

    カスタム設定を用いてクライアントバッファのサイズを制限することができ、制限をヒットしているクライアントは切断されます。ただし、クライアントは予期しない切断を処理できる必要があります。通常のクライアントのバッファサイズを処理するパラメータは次のとおりです。

    • client-query-buffer-limit: 単一の入力リクエストの最大サイズ。

    • client-output-buffer-limit-normal-soft-limit: クライアント接続のソフト制限。で定義された秒単位の時間を超えてソフト制限を超えたままの場合、 client-output-buffer-limitnormal-soft-seconds またはハード制限に達した場合、接続は終了します。

    • client-output-buffer-limit-normal-soft-seconds: client-output-buffer-limit-normal-soft-limit; を超える接続に許可される時間

    • client-output-buffer-limit-normal-hard-limit: この制限に達する接続はすぐに終了します。

    通常のクライアントバッファに加えて、次のオプションは、レプリカノードと Pub/Sub (Publish/Subscribe) クライアントのバッファを制御します。

    • client-output-buffer-limit-replica-hard-limit;

    • client-output-buffer-limit-replica-soft-seconds;

    • client-output-buffer-limit-replica-hard-limit;

    • client-output-buffer-limit-pubsub-soft-limit;

    • client-output-buffer-limit-pubsub-soft-seconds;

    • client-output-buffer-limit-pubsub-hard-limit;

Amazon EC2インスタンスのクライアント側のトラブルシューティング

クライアント側の負荷と応答性は、 へのリクエストにも影響します ElastiCache。EC2 断続的な接続やタイムアウトの問題をトラブルシューティングする際には、インスタンスとオペレーティングシステムの制限を慎重に確認する必要があります。観察すべきいくつかの重要なポイント:

  • CPU:

    • EC2 インスタンスCPUの使用状況: CPUが飽和していないか、100% に近いことを確認してください。履歴分析は を介して行うことができますが CloudWatch、データポイントの粒度は 1 分 (詳細モニタリングが有効になっている) または 5 分であることに注意してください。

    • バーストインスタンス を使用する場合はEC2、CPUクレジット残高が枯渇していないことを確認してください。この情報は、 CPUCreditBalance CloudWatch メトリクスで入手できます。

    • CPU 使用率が高い期間が短いと、 の使用率を 100% 反映せずにタイムアウトが発生する可能性があります CloudWatch。このような場合は、topps および mpstat のようなオペレーティングシステムツールによるリアルタイムの監視が必要です。

  • ネットワーク

    • インスタンスの機能に応じて、ネットワークスループットが許容可能な値未満であるかどうかを確認してください。詳細については、「Amazon EC2 インスタンスタイプ」を参照してください。

    • ena 拡張ネットワークドライバーのインスタンスで、タイムアウトまたは超えられた制限がないか [ENA 統計] を確認してください。次の統計情報は、ネットワーク制限の飽和状態を確認するのに役立ちます。

      • bw_in_allowance_exceeded/bw_out_allowance_exceeded: 過剰なインバウンドまたはアウトバウンドのスループットのためにシェーピングされたパケット数;

      • conntrack_allowance_exceeded: セキュリティグループの [接続追跡制限] のためにドロップされたパケット数。この制限が飽和すると、新しい接続は失敗します。

      • linklocal_allowance_exceeded: NTPを介したインスタンスメタデータへの過剰なリクエストが原因でドロップされたパケットの数VPCDNS。制限は、すべてのサービスで毎秒 1024 パケットです。

      • pps_allowance_exceeded: 1 秒あたりの過剰なパケット比率のためにドロップされたパケット数。ネットワークトラフィックが 1 秒あたり数千または数百万の非常に小さなリクエストで構成されている場合、PPS制限に達する可能性があります。 ElastiCache トラフィックは、 MGETではなく複数のオペレーションを同時に実行するパイプラインまたはコマンドを介してネットワークパケットをより適切に使用するように最適化できますGET

1 つのリクエストを完了するのにかかった時間の解読

  • ネットワーク上: Tcpdumpおよび Wireshark (コマンドライン上のサメ) は、リクエストがネットワークを移動し、 ElastiCache エンジンをヒットしてリターンを得るのにかかった時間を把握するための便利なツールです。次の例では、次のコマンドで作成された 1 つのリクエストを強調表示します。

    $ echo ping | nc example.xxxxxx.ng.0001.use1.cache.amazonaws.com 6379 +PONG

    上記のコマンドと並行して、tcpdump が実行中であり、次のように返されました。

    $ sudo tcpdump -i any -nn port 6379 -tt tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes 1609428918.917869 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [S], seq 177032944, win 26883, options [mss 8961,sackOK,TS val 27819440 ecr 0,nop,wscale 7], length 0 1609428918.918071 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [S.], seq 53962565, ack 177032945, win 28960, options [mss 1460,sackOK,TS val 3788576332 ecr 27819440,nop,wscale 7], length 0 1609428918.918091 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 0 1609428918.918122 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [P.], seq 1:6, ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 5: RESP "ping" 1609428918.918132 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [F.], seq 6, ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 0 1609428918.918240 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [.], ack 6, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 0 1609428918.918295 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [P.], seq 1:8, ack 7, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 7: RESP "PONG" 1609428918.918300 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 8, win 211, options [nop,nop,TS val 27819441 ecr 3788576332], length 0 1609428918.918302 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [F.], seq 8, ack 7, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 0 1609428918.918307 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 9, win 211, options [nop,nop,TS val 27819441 ecr 3788576332], length 0 ^C 10 packets captured 10 packets received by filter 0 packets dropped by kernel

    上記の出力から、TCP3 方向ハンドシェイクが 222 マイクロ秒 (918091 ~ 917869) で完了し、ping コマンドが送信され、173 マイクロ秒 (918295 ~ 918122) で返されたことを確認できます。

    リクエストから接続を閉じるまで、438 マイクロ秒 (918307~917869) かかりました。これらの結果では、ネットワークとエンジンの応答時間が良好であることを確認し、調査は他のコンポーネントに焦点を当てることができます。

  • オペレーティングシステム上: Strace は、OS レベルでのタイムギャップを特定するのに役立ちます。実際のアプリケーションの分析では、より広範で特殊なアプリケーションプロファイラやデバッガを使用することをお勧めします。次の例は、基本オペレーティングシステムコンポーネントが予期したとおりに動作しているかどうかを示しています。そうでない場合、さらに調査が必要になることがあります。で同じ Redis OSS PING コマンドを使用するとstrace、次のようになります。

    $ echo ping | strace -f -tttt -r -e trace=execve,socket,open,recvfrom,sendto nc example.xxxxxx.ng.0001.use1.cache.amazonaws.com (http://example.xxxxxx.ng.0001.use1.cache.amazonaws.com/) 6379 1609430221.697712 (+ 0.000000) execve("/usr/bin/nc", ["nc", "example.xxxxxx.ng.0001.use"..., "6379"], 0x7fffede7cc38 /* 22 vars */) = 0 1609430221.708955 (+ 0.011231) socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 1609430221.709084 (+ 0.000124) socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 1609430221.709258 (+ 0.000173) open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3 1609430221.709637 (+ 0.000378) open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3 1609430221.709923 (+ 0.000286) open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3 1609430221.711365 (+ 0.001443) open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3 1609430221.713293 (+ 0.001928) socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3 1609430221.717419 (+ 0.004126) recvfrom(3, "\362|\201\200\0\1\0\2\0\0\0\0\rnotls20201224\6tihew"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.31.0.2")}, [28->16]) = 155 1609430221.717890 (+ 0.000469) recvfrom(3, "\204\207\201\200\0\1\0\1\0\0\0\0\rnotls20201224\6tihew"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.31.0.2")}, [28->16]) = 139 1609430221.745659 (+ 0.027772) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 1609430221.747548 (+ 0.001887) recvfrom(0, 0x7ffcf2f2ca50, 8192, 0, 0x7ffcf2f2c9d0, [128]) = -1 ENOTSOCK (Socket operation on non-socket) 1609430221.747858 (+ 0.000308) sendto(3, "ping\n", 5, 0, NULL, 0) = 5 1609430221.748048 (+ 0.000188) recvfrom(0, 0x7ffcf2f2ca50, 8192, 0, 0x7ffcf2f2c9d0, [128]) = -1 ENOTSOCK (Socket operation on non-socket) 1609430221.748330 (+ 0.000282) recvfrom(3, "+PONG\r\n", 8192, 0, 0x7ffcf2f2c9d0, [128->0]) = 7 +PONG 1609430221.748543 (+ 0.000213) recvfrom(3, "", 8192, 0, 0x7ffcf2f2c9d0, [128->0]) = 0 1609430221.752110 (+ 0.003569) +++ exited with 0 +++

    上記の例では、コマンドは完了に 54 ミリ秒を若干超える時間がかかりました (752110 - 697712 = 54398 マイクロ秒)。

    nc をインスタンス化し、名前解決 (697712 から 717890 まで) を行うには、約 20 ミリ秒というかなりの時間がかかりました。その後、TCPソケットの作成に 2 ミリ秒 (745659 から 747858)、リクエストの応答を送信して受信するには 0.4 ミリ秒 (747858 から 748330) が必要でした。