のーずいだんぷ

主に自分用メモですが、もしかしたら誰かの役に立つかもしれません

API GatewayとLambdaで作ったREST APIのレイテンシが大きいときに確認した3つのこと

はじめに

最近仕事で初めてネットワーク外に公開するAPIを作成したのだが、最初に作ったAPIがレイテンシが1〜2sとかなり大きかった。 そこから0.3〜0.6sまで改善したので、そのときに行った調査とその方法について簡単に記録する。 技術的に深い内容はない。あくまでも探すときのポイントを記載する。

確認ポイント1: Lambdaのメモリ

正直今回のケースでは一番これが大きかった。結果の出力を見たときにあまりメモリを使っていなかったようなので最初は候補に上げていなかった。 デプロイスクリプトでデプロイするとうっかり忘れてしまうことがある、特にchaliceなんかはちゃんと設定を書かなくてもデプロイできてしまうので忘れやすい。

確認ポイント2: Lambdaのコールドスタート

Lambdaをよく使う人は知っていると思うが、Lambdaにはコールドスタートという概念があり、これは実行前に初期化処理を行うのでその分レイテンシが生じてしまう。 VPC Lambdaなんかは特に遅いと有名だが、(これはENIの割当に時間がかかるため)これは今年の発表で順次ローリングアップデートがかかるので今後は問題となりえないかもしれない。 (そもそもシビアな要件ならAPI Gateway + Lambdaは使いべきではないと思う)

確認ポイント3: API Gatewayのエンドポイントのタイプ

API Gatewayのエンドポイントには以下の3種類の種類があり、

  • REGIONAL…同じリージョンのクライアント、もしくは少数の要求の高いクライアントに対して提供することを目的としている。

  • EDGE…デフォルトのエンドポイントタイプ。地理的に分散したクライアントに対してCloudFrontを利用して最適なルーティングを行う。

  • PRIVATE…VPC内でしか使用できない。SPAやRESTによるマイクロサービスに使用するのはこれだと思う。

この内パフォーマンスはREGION>EDGEなので、自分のAPIがREGIONALで十分であれば変更したほうが良い。

その他の速度改善方法

  • LambdaをSPAのバックエンドプロキシサーバとして使用するなら(BFF)おそらくそこからDynamoやらにAPIを叩いている思う。その場合は並列化によって高速化が期待できる。

  • 上で紹介したLambdaのコールドスタートは一定時間起動しなければ発生するように見える。(正確な仕様は不明)だが、定期的にLambdaを実行させることで常にホットスタートの状態をキープする等の力技もある。 (Lambdaの料金は非常に安いのであまり影響はない気がする)

  • 実装言語を変更する。処理が複雑で計算量が大きくなるほどこの効果は大きくなると思うが、逆にシンプルな処理だとその恩恵は少ないかもしれない。

確認するための方法

  1. AWS Xray を使用する。 これはAPI Gatewayへのリクエスト〜レスポンスまでの時間配分を記録しており、例えばさっきのLambdaのコールドスタートなのかそうでないのかはこれによって判断できる。 API Gatewayからも簡単に設定できるので連携自体は非常に簡単にである。

  2. 実行コードで時間計測を行う。 自分がよく使うPythonなんかだと簡単にデコレータ化して各関数の処理時間を計測できるので、これによってボトルネックを見つけることができる。

ただし、これらは各リクエストが比較的シンプルな動作をする場合には役に立つが、複雑な場合はかなり難しくなると思う。

参考

docs.aws.amazon.com