例外処理と再試行 - Amazon Neptune

例外処理と再試行

Neptune で堅牢なアプリケーションを構築することは、特にデータベースから返されるエラーを処理する場合に、予期しない事態に備えることを表します。サーバー側の例外に対する最も一般的な応答の一つは、失敗したオペレーションを再試行することです。復元性に優れたシステムでは再試行ロジックが不可欠ですが、すべてのエラーを同じように処理するわけではないことを認識する必要があります。一般的な再試行動作に依存するのではなく、慎重なアプローチにより、より信頼性が高く効率的なアプリケーションを構築できます。

再試行ロジックが重要な理由

再試行ロジックは、分散アプリケーションの重要なコンポーネントです。ネットワークの不安定性、一時的なリソースの制約、同時変更の競合などの一時的な問題により、オペレーションが失敗する可能性があります。多くの場合、これらの障害は永続的な問題を示すものではなく、待機して再試行することで解決できます。強固な再試行戦略を実装することで、分散システムにおける不完全な環境の現実を認識し、手動による介入の必要性を少なくして、信頼性と継続性を強化できます。

無差別再試行のリスク

デフォルトですべてのエラーを再試行すると、いくつかの意図しない結果が生じる可能性があります。

  • 競合の増加 – 同時実行数が多いために失敗したオペレーションが繰り返し再試行されると、競合全体が悪化する可能性があります。これにより、トランザクションが繰り返し失敗し、パフォーマンスが低下する可能性があります。

  • リソースの枯渇 — 無差別の再試行によって、クライアント側とサーバー側の両方で追加のシステムリソースが消費される可能性があります。これにより、スロットリングやさらにはサービスの低下につながる可能性があります。

  • クライアントのレイテンシーの増加 – 過剰な再試行は、特に各再試行に待機期間が含まれる場合、クライアントアプリケーションの大幅な遅延を引き起こす可能性があります。これは、ユーザーエクスペリエンスとダウンストリームプロセスに悪影響を及ぼす可能性があります。

実践的な再試行戦略の策定

回復力と効率性に優れたアプリケーションを構築するには、アプリケーションが遭遇する可能性のある特定のエラー条件に合わせた再試行戦略を策定します。アプローチの指針となる考慮事項をいくつか示します。

  • 再試行可能なエラーを特定する – すべての例外を再試行することが必要なわけではありません。例えば、構文エラー、認証の失敗、無効なクエリによって再試行がトリガーされるように設定しないでください。Neptune によって、エラーコードとエラーを再試行しても安全な一般的な推奨事項が提示されますが、ユースケースに合ったロジックを実装する必要があります。

  • エクスポネンシャルバックオフの実装 – 一時的なエラーの場合は、エクスポネンシャルバックオフ戦略を使用して、再試行間の待機時間を徐々に長くします。これにより、競合が緩和されて、カスケード障害のリスクが軽減されます。

  • 最初の一時停止の長さを考慮する – 最初の再試行を過剰に速く実行すると、クエリを成功させるために必要なリソースを解放するのに十分な時間がサーバーに与えられていない場合、同じエラーで終了する可能性があります。適切な状況で一時停止時間を長くすると、無駄なリクエストやサーバーのプレッシャーを軽減できます。

  • バックオフにジッターを追加する – エクスポネンシャルバックオフは有効ですが、同時に多くのクライアントが失敗し、同じタイミングで再試行すると、同期された再試行ストームが発生する可能性があります。バックオフ遅延に小規模かつランダムなバリエーションであるジッターを追加すると、再試行回数が増加するため、すべてのクライアントが同時に再試行し、負荷が再び急増する可能性が低くなります。

  • 再試行回数の制限 – 無限ループとリソースの枯渇を防ぐために、妥当な最大再試行回数を設定します。

  • モニタリングと調整 — アプリケーションのエラー率を継続的にモニタリングし、必要に応じて再試行戦略を調整します。特定のオペレーションの再試行回数が多い場合は、オペレーションを最適化できるかシリアル化できるかを検討してください。

シナリオ例

適切な再試行戦略は、障害の性質、ワークロード、および観察するエラーパターンによって異なります。次の表は、一般的な障害シナリオと、再試行戦略の考慮事項がそれぞれにどのように適用されるかをまとめたものです。追加のコンテキストについては、説明文の段落を参照してください。

シナリオ

再試行可能なのは?

バックオフとジッター

最初の一時停止

再試行の制限

モニタリングと調整

ショートクエリにおける一時的な CME

あり

ショートバックオフ、ジッターの追加

短い (例: 100 ミリ秒)

CME レートの上昇をモニタリングする

長期実行クエリにおける頻繁な CME

あり

バックオフを長くしてジッターを追加する

長い (例: 2 秒)

競合を調査して軽減する

高コストなクエリのメモリ制限

あり

ロングバックオフ

長い (例: 5~10 秒)

クエリを最適化し、永続的な場合は警告する

中程度のクエリにおけるタイムアウト

おそらく

中程度のバックオフ、ジッターの追加

中程度 (例: 1 秒)

低から中程度

サーバーの負荷とクエリ設計を評価する

シナリオ 1: ショートクエリにおける一時的な CME

短時間の簡単な更新中に ConcurrentModificationException が頻繁に表示されないワークロードの場合、これらのエラーは通常一時的なものであり、再試行しても安全です。最初の再試行の前に短い最初の一時停止 (例: 100 ミリ秒) を使用します。今回は、短いロックをクリアできます。これを短いエクスポネンシャルバックオフおよびジッターと組み合わせて、同期された再試行を回避します。再試行のコストは低いため、再試行制限の値を引き上げるのが合理的です。その場合も、CME レートをモニタリングして、データ内の競合が増加する傾向をキャッチします。

シナリオ 2: 長時間実行されるにおける頻繁な CME

長時間実行されるクエリでアプリケーションに頻繁に CME が表示される場合は、より深刻な競合があることを示唆しています。この場合は、最初の一時停止を長い時間 (例: 2 秒) に設定して開始し、ロックを保持する現在のクエリに完了するのに十分な時間を付与します。エクスポネンシャルバックオフを長くしてジッターを追加します。過剰な遅延やリソースの使用を回避するため、再試行回数を制限します。競合が解決しない場合は、ワークロードのパターンを確認し、根本原因に対処するために更新のシリアル化または同時実行数の削減を検討してください。

シナリオ 3: 高コストなクエリのメモリ制限

既知のリソースを大量に消費するクエリ中にメモリベースのエラーが発生した場合、再試行は理にかなっていますが、サーバーがリソースを解放できるように、最初の長い一時停止 (例: 5~10 秒以上) の後に限られます。クエリやワークロードを変更せずに繰り返し失敗が解決する可能性が低いため、長いバックオフ戦略を使用し、再試行制限を低く設定します。永続的なエラーはアラートをトリガーし、クエリの複雑さとリソースの使用状況の確認を促す必要があります。

シナリオ 4: 中程度のクエリにおけるタイムアウト

中程度のコストのクエリのタイムアウトは、よりあいまいなケースです。タイムアウトがサーバーの負荷やネットワークの状態が一時的に急増した場合に、再試行が成功する可能性があります。システムを回復させるには、最初は中程度の一時停止 (例: 1 秒) から始めます。同期された再試行を回避するために、中程度のバックオフを適用し、ジッターを追加します。再試行制限を低ら中程度に保ちます。タイムアウトを繰り返すと、クエリまたはサーバーの容量に関するより深い問題を示している可能性があるためです。パターンをモニタリングする: タイムアウトが頻繁になった場合は、クエリの最適化が必要かどうか、または Neptune クラスターのプロビジョニングが不足しているかどうかを評価します。

モニタリングとオブザーバビリティ

モニタリングは、再試行戦略の重要な部分です。効果的なオブザーバビリティは、再試行ロジックがどの程度機能しているかを理解し、ワークロードまたはクラスター設定で注意が必要なときに早期シグナルを提示します。

MainRequestQueuePendingRequests

この CloudWatch メトリクスは、Neptune の入力キューで待機しているリクエストの数を追跡します。値が上昇することは、クエリがバックアップされていることを示します。これは、過剰な競合、プロビジョニング不足のリソース、または再試行ストームの兆候である可能性があります。このメトリクスをモニタリングすることで、再試行戦略がキューイングの問題の原因または複雑化しているタイミングを特定し、障害がエスカレートする前にアプローチを調整するように促すことができます。

他の CloudWatch メトリクス

CPUUtilizationTotalRequestsPerSecond、クエリレイテンシーなどの他の Neptune メトリクスは、追加のコンテキストを提示します。例えば、高 CPU かつ高 I/O の状態でキューの長さが増加すると、クラスターが過負荷になっているか、クエリのサイズが過剰に大きい、または過剰に高頻度であることを示している可能性があります。CloudWatch アラームは、これらのメトリクスに設定して異常な動作についての警告を受信し、エラーの急増や再試行を基盤となるリソースの制約に関連付けることができます。

Neptune Status API と Query API

Gremlin 用の Neptune Status APIOpenCypher および SPARQL 用の類似 API は、クラスターで受け入れられ実行されているクエリをリアルタイムで表示します。これは、ボトルネックの診断や再試行ロジックの影響をリアルタイムに把握するために活用できます。

これらのモニタリングツールを組み合わせることで、次のことが可能になります。

  • 再試行がキューイングとパフォーマンスの低下に寄与しているタイミングを検出します。

  • Neptune クラスターをスケールする、またはクエリを最適化するべきタイミングを特定します。

  • 再試行戦略が、より深い問題を隠匿することなく一時的な障害を解決していることを検証します。

  • 新たな競合やリソースの枯渇に関する早期警告を受け取ります。

プロアクティブなモニタリングとアラートは、特にアプリケーションの同時実行数と複雑さが増大するにつれて、Neptune の正常なデプロイを維持するために不可欠です。