動的なウェブ・エコシステムでは、システムのスケーリングと分散化が進み、可用性、自動化、堅牢なテストフレームワークの重要性が高まっています。 回復力のあるシステムを構築する上で中心となるのは カオスエンジニアリング です。これは、障害を意図的にシステムに注入して、実際の問題が発生する前に弱点を特定する手法です。 New Relicは、特にリレーショナルデータベースのような複雑な環境において、潜在的なシステム障害を発見して対処するために、本番前環境で毎週カオス実験を実行しています。

Amazon Auroraは、他のデータベースの中でも、その分散型の性質、アーキテクチャー、高可用性を実現するためのフェイルオーバー方式により、独特の課題を提起します。 この記事では、オブザーバビリティとカオスエンジニアリングを活用して、サービスがデータベースの劣化に対処できるようにする方法について説明します。

データベース向けのカオステスト

カオステストは、システムの回復力に貴重な洞察を提供し、チームが現実世界のシナリオで対応できるようにします。 データベースレイヤーでのカオステストの主な利点は次のとおりです。

  • フェイルオーバーとアプリケーションの堅牢性を検証: これにより、アプリケーションのエラー処理とドライバ設定の弱点が明らかになり、システム防御力を強化する機会が得られます。

  • 潜在的な機能停止の軽減とデータ保護: 定期的なカオステストにより、不測の事態を軽減し、停止を最小限に抑え、インシデントレスポンスタイムを改善することでデータ損失から保護します。

  • 効果的なオブザーバビリティとアラートの確保: カオスシナリオにより、インフラストラクチャ監視とアラートメカニズムをテストし、チームがインシデント対応戦略を改善できるようにします。

  • システムの深い理解とドキュメントの改善: チームは知識を深め、将来のトラブルシューティングとインシデント管理に役立つ徹底したドキュメントを作成します。

  • キャパシティとパフォーマンスの最適化: カオステストはストレスポイントとキャパシティ限界を強調し、チームがインフラストラクチャをより正確に計画および拡張できるようにします。

開始する

カオステストを成功させるには、オブザーバビリティと監視を確立することが不可欠です。 以下に主要なコンポーネントの詳細を示します。

これらのコンポーネントをクラウドアーキテクチャーに統合することで、カオス実験の実施やそこから学ぶために不可欠な詳細なオブザーバビリティの基盤を築くことができます。

データベースオブザーバビリティの準備

システムの変化を単に見るだけでなく観測することも重要です。つまり、生データを実用的な洞察に変換する自動化されたモニタリングを通じて、時間の経過とともにその背景と影響を理解します。

クライアントサイド

アプリケーションがデータベースと対話する際の動作を監視することが重要です。 リアルタイムアプリケーションパフォーマンスモニタリングに New Relic APM を使用して、次の点を観察します。

  • エラー率 カオステスト中のアプリケーション内のエラーの発生頻度を監視します。

  • スループット アプリケーションが処理するトランザクション数を追跡します。

  • レスポンスタイム さまざまなテスト段階で、アプリケーションがリクエストに応答するまでの時間を測定します。

  • アラート エラー率やスループットの異常に対するアラートを設定し、カオステストで明らかになる問題への迅速な対応を可能にします。

サーバーサイド

逆に、データベースサービスの内部で何が起こっているかを監視することも同様に必要です。 見ておくポイントは次のとおりです:

  • CloudWatch Aurora メトリクス Amazon CloudWatch を活用して、CPU使用率、1秒あたりの入出力操作数(IOPS)など、Aurora の主要パフォーマンス指標を追跡します。

  • データベースログ データベースの ログデータ を管理し、Aurora からの結果を調べて、テストでサーバー側で見つかった異常なパターンや問題を特定します。

  • スループット分析 カカオステストの前、テスト中、テスト後のスループットを比較して、パフォーマンスへの影響を理解します。

New Relic APM から収集したアプリケーション側のデータと CloudWatch メトリクスを組み合わせることで、カオス実験から最大の価値を引き出すために重要な多面的なビューを実現します。

留意事項: オブザーバビリティは単なるチェックリストではありません。何を測定するかを戦略的に決定し、適切なアラートを設定し、仮説、検証、反復に必要な洞察がスタック全体のデータからどのように得られるかを理解することが重要です。

Aurora フェイルオーバーの実行

フェイルオーバーは、予期しない障害時にデータの可用性を維持するための重要な手順です。 Amazon Aurora のフェイルオーバープロセスは、データベース操作をスタンバイインスタンスに自動的にリダイレクトすることで、ダウンタイムを最小限に抑えるように設計されています。 この操作を理解することで、システムの耐障害性を高める準備に役立ちます。

ここでは Aurora フェイルオーバー中に何が起こるかを簡潔に説明します。

  1. インスタンスの選択: Aurora は適切なリーダーインスタンスを選択してプライマリステータスに昇格します。 選択では、インスタンスの仕様、アベイラビリティゾーン、および事前定義されたフェイルオーバー優先順位が考慮されます。 このプロセスの詳細については、AWS が Amazon Aurora の高可用性に関するセクションで包括的な詳細を提供しています。

  2. インスタンスの昇格: 選択されたリーダーインスタンスは読み取り/書き込みモードで再起動され、新しいプライマリインスタンスとして機能します。

  3. プライマリインスタンスの降格: 同時に、古いプライマリノードが読み取り専用モードで再起動され、リーダーインスタンスのプールに参加する準備が整います。

  4. DNSエンドポイントの更新: 新しいロールを反映するために、Aurora は DNSレコードを更新します。 ライターエンドポイントは新しいプライマリインスタンスを指し、リーダーエンドポイントは古いプライマリノードをリーダーのリストに集約します。 DNS の変更では、5秒の有効期間(TTL)設定が使用されますが、クライアント側のキャッシュがこの変更を認識する速さに影響する可能性があります。

フェイルオーバーの移行中は、短時間の接続中断が予想されます。 Aurora がトラフィックを新しいライターに移行し、リーダーの設定を調整するため、クライアントは数秒間の中断に備える必要があります。 通常、フェイルオーバーについて文書化されたAWSの見解によれば、これらの中断は約5秒間続きます。

スムーズなフェイルオーバーを実現するには、アプリケーションとドライバがこれらの移行を適切に処理できるように調整されている必要があります。以降のセクションでは、これらの移行を最小限の影響で管理するための、ドライバ設定とクライアントアプリケーションの最適な設定について説明します。

ドライバ問題の特定とトラブルシューティング

ドライバとシステムのエラーを監視することは、アプリケーションがデータベースのフェイルオーバーをどのように切り抜けるかを理解するために不可欠な要素です。 APM のクライアント側のエラーと、データベースサーバー側のログに記録された、リーダー/レプリカロールへの書き込みに関連するエラーの兆候を監視してください。

APM とログイベント

MySQL または PostgreSQL データベースがフェイルオーバー中に読み取り専用状態に切り替わったときに発生する可能性のあるエラー例をいくつか示します。これは、アプリケーションが許可されていない書き込み操作を試みたことを示します。

PostgreSQL:

nested exception is org.postgresql.util.PSQLException: 
ERROR: cannot execute nextval() in a read-only transaction

MySQL:

Error 1290 (HY000): The MySQL server is running with the 
--read-only option so it cannot execute this statement

Go で書かれた MySQL アプリケーションは、フェイルオーバー後にデータベースが読み取り専用であることを強調するエラーをログに記録する場合があります。


Error 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
                                                                               main.(*Env).execQueryHandler (/src/handlers.go:204)
                                                             http.HandlerFunc.ServeHTTP (/usr/local/go/src/net/http/server.go:2136)
…in.configureServer.WrapHandleFunc.WrapHandle.func19 (/src/vendor/github.com/newrelic/go-agent/v3/newrelic/instrumentation.go:98)
                                                             http.HandlerFunc.ServeHTTP (/usr/local/go/src/net/http/server.go:2136)
          main.configureServer.WrapHandleFunc.func10 (/src/vendor/github.com/newrelic/go-agent/v3/newrelic/instrumentation.go:184)
                                                             http.HandlerFunc.ServeHTTP (/usr/local/go/src/net/http/server.go:2136)
                                                           mux.(*Router).ServeHTTP (/src/vendor/github.com/gorilla/mux/mux.go:212)
                                                             http.(*ServeMux).ServeHTTP (/usr/local/go/src/net/http/server.go:2514)
                                                           http.serverHandler.ServeHTTP (/usr/local/go/src/net/http/server.go:2938)
                                                                     http.(*conn).serve (/usr/local/go/src/net/http/server.go:2009)
                                                                        runtime.goexit (/usr/local/go/src/runtime/asm_amd64.s:1650)

ドライバの設定が適切でない場合、フェイルオーバー後にエラー率が高止まりする可能性があります。これは、New Relic APM で次のように確認できます。

このようなエラーメッセージを素早く特定することは、迅速なインシデント対応にとって非常に重要です。New Relic APM を使用してアプリケーションのパフォーマンスを分析している場合でも、より詳細なログデータを調査している場合でも、フェイルオーバー中およびフェイルオーバー後にこれらのエラーパターンに注意を払うことは、トラブルシューティングプロセスの大きな助けになります。

ドライバ設定とベストプラクティス

データベース接続ドライバは、計画されたメンテナンス操作や計画外のシナリオのフェイルオーバーを処理できるように適切に調整する必要があります。

ドライバ設定

フェイルオーバー イベントの中断を乗り切るには、データベース接続ドライバの正確なチューニングが必要です。 これは、計画的なメンテナンスに備えるだけでなく、計画外のシナリオに対処するための基礎固めにもなります。

データベースとキャッシュドライバを設定する際に留意すべき点は次のとおりです。

  • DNS TTL 設定: OS、DNS 管理レイヤー、データベースドライバが、AWS の5秒 DNS TTL ポリシーに準拠していることを確認します。

  • スマートデータベースドライバの使用: プライマリステータスが変更された場合に自動的に再接続できるように、DNSキャッシュとインスタンスの状態を効果的に管理するドライバを選択します。

  • ドライバオプションの指定: AWSデータベースの場合、専用の MySQL 用 JDBC ドライバPostgreSQL 用 JDBC ドライバ を検討してください。 スマートドライバが利用できない場合は、接続の有効期間設定を管理して、DNS TTL に従って接続がリフレッシュされるようにします。

接続の最大有効期間の設定: スマートデータベースドライバのオプションを使用しない場合、代替オプションとして、コネクションごとに最大有効期間を持つようにコネクションプーラーを設定することができます。 閾値Xの期間を過ぎた後は、コネクションを一旦クローズしてから再度オープンする必要があります。 このような設定を活用することで、DNSを確保することができます。

Goサービスドライバの設定例:

// DB ドライバの設定。 DBドライバの設定を調整し、
 // 接続プールの動作参照: https://go.dev/doc/database/manage-connections
// このアプリインスタンスの合計接続数を制限
// データベースサーバーで使用できます。
db.SetMaxOpenConns(10)
 // 維持されるアイドル接続数を制限します。
db.SetMaxIdleConns(3)
 // RWフェイルオーバーが1分以内に実行されるように、定期的に接続を再開します。
db.SetConnMaxLifetime(60 * time.Second)
// 30秒間アクティビティがない状態が続いたらアイドル接続を閉じます。
db.SetConnMaxIdleTime(30 * time.Second)

オブザーバビリティ、メトリクス、アラート

フェイルオーバー実験の混沌とした環境では、効果的なオブザーバビリティがあなたの目となり耳となります。 構造化されたモニタリングとアラートにより、常に最新の情報を入手し、すぐに行動できるようになります。

  • New Relic APM ライアント側の視点を理解するのに役立ちます。 アプリケーションは、データベースサーバーに対する自身のアクティビティはどうなっているのか?レスポンスタイム、スループット、エラー率はどれくらいでしたか?

  • Infrastructure エージェント データベースインテグレーション の併用 : システムのパフォーマンスを監視します。 MySQL および PostgreSQL の特別なインテグレーションにより、これらのデータベースに特化した洞察が提供されます。

  • Kinesis Firehose を使用した New Relic Amazon CloudWatch Metric Streamメトリックストリーム を利用して、Auroraデータベースのリアルタイムモニタリングデータを含む CloudWatch メトリクスの継続的なフローをNew Relicに送信します。

  • アラート 状況に応じて適切なアラートを設定します。 多くの場合、エラー・レート、スループット、レスポンスタイムが有力な候補となります。 フェイルオーバーの状況では、特にエラー率が重要ですが、書き込みスループットとレスポンスタイムの監視は、多くの状況で付加価値を提供できます。

このエラー率は、1分間に含まれるポジティブな経験を表しています。

カオステストの今後

レジリエンス戦略に磨きをかけていくにつれて、カオステストの範囲と複雑さが拡大していきます。 新しいサービス、さまざまな規模や負荷パターンの影響、より高度な障害シミュレ ーションなどの探求を予測します。