VPCのAWS Lambdaで接続タイムアウトの問題を解決する方法

ネットワークの制限を理解することで、VPCにおけるAWS Lambdaの接続タイムアウトに対処します。

Momentoのあるお客様は、次の製品リリースの準備のため、AWS Lambdaでの負荷テスト中にMomento Cacheへの接続確立のタイムアウトに直面しました。このテストは、最も突発的なアクティビティをシミュレートするもので、顧客採用のための最良のシナリオですが、実行にはコストがかかります。Momentoはサーバーレスアーキテクチャの重要な鍵であったため、タイムアウトはローンチの準備と再現の予算を危険にさらすものでした。

最高のカスタマー・エクスペリエンスを求めて、Momentoは調査を推進しました。私たちは単純な解決策を発見しただけでなく、Virtual Private Clouds(VPC)内でのLambdaの動作に関する重要な詳細も発見しました。VPCでLambdaを大規模に運用している方は、ぜひ参考にしてください。

糸を引っ張る

私たちはまずサービスを調査しました。ロードバランサーと内部サービスのメトリクスには、障害やエラー率の上昇の兆候は見られませんでした。実際、内部負荷テストでは、問題なくお客様の接続負荷をはるかに上回っていました。この結果を受けて、私たちはMomentoから顧客のアーキテクチャに注意を移しました。

このケースでは、顧客はVPC内のLambda機能をNAT Gateway経由でMomentoに接続していました。あまり一般的な設定ではありませんが、Lambdaから他のAWSサービスを利用するためには、VPC内のLambdaが必要であることがわかりました。

このセットアップを再現し、Momentoに高い接続コンカレンシーで接続したところ、まずNATゲートウェイに接続確立の問題が見つかりました。LambdaサービスVPCから顧客VPCへのアンダーザフッドのネットワーキングです。Hyperplaneと呼ばれるスケーラブルな内部サービス上に構築されたHyperplane Elastic Network Interfaces (ENI)は、Lambda機能からの新しい接続のバーストを処理するためにスケールしませんでした。その代わり、Lambda機能はネットワーク・インターフェイスの容量を使い果たし、Momentoへの接続は単にタイムアウトしました。

診断と主な所見

原因を究明するため、Momento に大量の接続を行うテスト環境を構築し、NAT ゲートウェイのアクティブ接続数を監視しました。その結果、次のことが判明しました:

NATゲートウェイのボトルネック: NAT Gatewayは飽和すると接続を開くことができません。このメトリクスはCloudWatchメトリクスでErrorPortAllocationとして表示されます。NATゲートウェイの容量を増やしたにもかかわらず、タイムアウトは残っており、NATゲートウェイのリソースの枯渇が唯一の原因であることを否定していました。

ハイパープレーンENIの接続制限: テスト中、アクティブな接続が 1 つの ENI の接続制限に近いピークに達することが確認されました。これは、30秒後に接続が確立されないことと相まって、ENIの限界を強く示唆しています。

最初に遭遇した制限は、NATゲートウェイにありましたた。デフォルトの設定では、NATゲートウェイは「一意の宛先(ソース)に対して最大55,000の同時接続」を開くことができまし。それ以降の新しい接続はオープンに失敗し、NATゲートウェイのCloudWatchメトリクス上でポート割り当てエラーとして報告されます。

2つ目の興味深い制限は、Lambdaサービスのネットワーキングに関するものでした。2019年の発表で説明されたように、顧客がVPCでLambda関数を実行するとき、AWSはLambdaサービスのVPCと顧客のVPCをAWS内部のネットワーキングサービスであるHyperplaneで接続します。今回の高同時接続シナリオに関連して、各Hyperplane ENIには65,000の同時接続制限があります。NAT Gatewayとは異なり、また残念ながら、このメトリックはCloudWatchのどこにもレポートされません。

興味深い余談:Momento への DNS リクエストが常に成功するのに対し、その直後の Momento への接続リクエストがタイムアウトする理由について、当初は困惑していました。ネットワークが明確になったことで、DNS リクエストは Lambda VPC のネームサーバーにルーティングされ、Momento 接続リクエストは Lambda Hyperplane ネットワークを経由してルーティングされ、ドロップされることがわかりました。

ソリューション ネットワーク容量の増加

これらのボトルネックには、それぞれ簡単な方法で対処できます:

NATゲートウェイの容量を増やす: NATゲートウェイにセカンダリのエラスティックIPをプロビジョニングします。各IPはさらに55,000接続をサポートし、総容量は440,000接続が上限となります(こちらを参照)。

追加サブネットのプロビジョニング: AWSはVPC-サブネット-セキュリティグループの組み合わせごとにハイパープレーンENIをプロビジョニングするため、VPCにプライベートサブネットを追加すると、Lambdaは追加のENIをプロビジョニングします(「Lambda Hyperplane ENI」を参照)。したがって、VPCにプライベートサブネットを追加するごとに、65,000コネクションずつ容量を増やすことができます。

教訓とベストプラクティス

サーバーレスのフラッグシップとして、AWS Lambdaは開発者のリソース管理を簡素化します。しかし、VPCで実行する場合、このサーバーレスの理想は崩れます。高い接続同時性が予想される場合、ネットワークリソースのキャパシティプランニングが必要です。ピーク負荷を見積もり、それに応じてNAT GatewayのセカンダリEIPとVPCサブネットをプロビジョニングする必要があります。

可能であれば、VPCの外でLambdaを実行することで、これらの制限を回避することができます。VPC内で実行する場合、PrivateLinkの方がNAT Gatewayよりも費用対効果が高く、キャパシティプランニングも少なくて済むかもしれません。

最後に、Lambda環境での接続の再利用に最適化されたクライアントライブラリを使用してください。Momentoでは、このような状況を想定してライブラリを防弾しています。

まとめ

私たちの顧客はこの解決策に感激し、”簡単な解決策を用意してくれた……リスク要因にさせる以上のことをしてくれた “と感謝してくれました。最終的に、Momento サービスは独自性を保ち、私たちはコミュニティにとって重要な教訓を発見しました。AWS Lambdaは開発者のエクスペリエンスを簡素化しますが、VPCで使用する場合、開発者はこれらの重要な考慮事項に注意する必要があります。

AWS Lambdaのシナリオに似たような高い並列性を扱っている場合、あるいは、私たちの専門家チームがあなたの代わりにこのレベルの厳密さで実行するというアイデアが好きな場合は、Momento Cacheをチェックしてください。