AWS Well-Architected Lens – Serverless Applications まとめ パフォーマンス編
アーキテクチャを検討する上で、とても役に立つフレームワークであるAWS Well Archtected Framework。
サーバーレス版が公開されたのでベストプラクティスについてまとめておきます。
https://d1.awsstatic.com/whitepapers/architecture/AWS-Serverless-Applications-Lens.pdf
運用編、セキュリティ編、信頼性編、パフォーマンス編、コスト編の5回に分けてメモしていきます。
解釈が間違っているかもしれないので、ご注意ください。
SERVPER 1:サーバレスアプリケーションで最適な容量単位(メモリ、シャード、1秒あたりの読み書き)をどのように選択しますか?
- Lambdaのデフォルトのメモリ設定とタイムアウト設定は、パフォーマンス、コストに望ましくない影響を及ぼす可能性がある。
- タイムアウトを平均実行時間よりもはるかに高く設定すると、コードが誤動作したときに長く実行される可能性があり、その結果、コストが高くなり同時実行数の限界に達する可能性がある。
- 一時的なネットワーキングの問題またはダウンストリームサービスの異常が発生した場合、サーバレスアプリケーションが実行を突然停止させる可能性がある。
- さらに重要なのはアップストリームサービスを考慮せずに、負荷テストを行わずにタイムアウトを設定し、いずれかのパーツがタイムアウトになるとエラーが発生する可能性がある。
SERVPER 2:サーバーレスアプリケーションのパフォーマンスをどのように最適化しましたか?
- サーバーレスのアーキテクチャーが成長するにつれ、さまざまなワークロード・プロファイルで共通に使用される特定のメカニズムが存在する。
- パフォーマンスを向上させるために、API Gatewayのキャッシュを有効にすることができる。
- 同様に、DAXを有効にすることで、読み取り応答を大幅に向上させ、グローバルおよびローカルセカンダリインデックスを改善して、DynamoDBフルスキャン操作を防止する。
- Lambda関数コード内のグローバルスコープを利用して、Lambdaコンテナを再利用することで、データベース接続とAWSサービスの初期接続と設定の処理に再利用される。
- Lambda関数は必ずしもVPCにデプロイする必要はない。
- CPUとネットワークの帯域幅は、Lambda機能用に設定されたメモリ設定に基づいて比例して割り当てられる。
- 必要に応じてVPCへのアクセスを設定する必要がある。VPCに関数をデプロイするとENIを作成する必要があるため起動時間が増える。
- Lamba機能がVPCとインターネットにアクセスする必要がある場合は、Lambdaからインターネット上で公開されているすべてのリソースへのトラフィックを許可するために、NATゲートウェイが必要です。
- 高い可用性とパフォーマンスを実現するために、複数のAZにNATゲートウェイを配置することをお勧めする。
SERVPER 4:パフォーマンスのためにラムダコードをどのように最適化していますか?
- Lambda関数は単一の目的で、可能な限り高速に実行されます。
- AWSでは、コンテナの再利用、ランタイムの展開パッケージサイズの最小化、依存関係の複雑さの最小化など、Lambda関数を使用する際のベストプラクティスに従います。
- この決定を下す際には、トレードオフが重要です。
- AWS Lambda 関数を使用する際のベストプラクティス - AWS Lambda
- VPCのLambda機能では、VPCのパブリックホスト名のDNS解決に数秒かかることがあるので避ける。リクエストに数秒の請求時間が追加される。
- たとえば、Lambda関数がVPC内のAmazon RDS DBインスタンスにアクセスする場合、nopublicly-accessibleオプションでインスタンスを起動します。
- VPC 内の Amazon RDS DB インスタンスの使用 - Amazon Relational Database Service
SERVPER 5:どのようにデータベース接続を初期化していますか?
- Lambda関数が実行された後、別のLambda関数呼び出しを予期してしばらくの間、ランタイムコンテナを維持します。
- グローバルスコープを活用する。
- たとえば、Lambda関数がデータベース接続を確立した場合、接続を再確立する代わりに、元の接続が後続の呼び出しで使用される。
- Lambda関数ハンドラコードの外側でデータベース接続やその他のオブジェクト/変数を宣言することで、関数が再度呼び出されたときに最適化される。
- コードにロジックを追加して、接続を作成する前に接続がすでに存在するかどうかを確認できる。