こんにちは。技術開発部部長の川住です。
弊社プロダクトにて、「オリジナル画像を適切な大きさに縮小してから読み込む仕組み」を作る必要が生じたので、遅ればせながらLambda@Edgeを使ってみたので、利用時のポイントを紹介したいと思います。
Lambda@Edgeとは?
Lambda@Edgeは、Amazon CloudFrontのエッジサーバで、AWS Lambdaの関数を実行できる仕組みです。リクエスト-レスポンス間の以下4つのタイミングに対してLambda関数を設定できます。
- CloudFrontのエッジサーバがユーザからのリクエストを受け取る時 (Viewer Request)
- (エッジサーバにキャッシュがなく)、オリジンサーバへリクエストを転送する前 (Origin Request)
- オリジンサーバからレスポンスを受信した後 (Origin Response)
- エッジサーバからユーザへレスポンスを転送する前 (Viewer Response)
Lambda関数に機能を実装することで、例えば以下のような仕組みを実現できます。
- ユーザ認証やリダイレクトを行う
- HTTPヘッダを操作する (追加, 削除, 変更)
- コンテンツを必要に応じて加工してレスポンスする
Lambda@Edgeを使用した画像のリサイズ
Lambda@Edgeを利用した画像のリサイズの仕組みの構築方法に関しては、こちら にて詳しく紹介されていますので、実装の詳細については割愛します。大雑把に言いますと、2つのLambda関数を実装しそれらをCloudFrontに設定することで実現しています。
- Viewer Requestとして、リサイズ後の幅や高さなどのパラメータを受け取り、パスに組み込む関数をCloudFrontに登録する
- エッジにリサイズ後の画像のキャッシュがあれば、オリジンへリクエストは転送されず、キャッシュデータがレスポンスされる
- Origin Responseとして、必要に応じてオリジンから受け取った画像をリサイズし、レスポンスとして返す関数をCloudFrontに登録する
- オリジンにリサイズ後の画像がすでに保管されている場合は、保管されている画像をレスポンスする
- オリジンにリサイズ後の画像が保管されていない場合は、画像を取得してリサイズした後、オリジンにデータを格納し、画像をレスポンスする
Lambda@Edge利用時のポイント
Lambda@EdgeはAWS Lambdaと同様の制約を受けるほかに、Lambda@Edge特有の制約や注意点があったので紹介します。
スペック面での制約
AWS Lambdaでは実行時のメモリ量やタイムアウト時間を設定できますが、Lambda@Edgeでの実行時にはこれらの設定上限が通常よりも厳しくなります。
- メモリ量の上限: 128MB
- タイムアウトの上限: 5秒
その他制約に関してはこちらが詳しいです。また、AWS Lambdaでは複数の言語をサポートしていますが、Lambda@Edgeで使用できるのは「 node.js 6.10, node.js 8.10 」のみとなっています。
Lambda関数はus-east-1 (バージニア北部) に登録する必要がある
CloudFrontに設定できるLambda@Edge関数はバージニア北部に登録されているものだけです。
バージョンつきのarnを紐つける必要がある
CloudFrontには $LATEST
や $ALIAS
のarnを設定できないので、バージョンを発行したLambda関数をCloudFrontに設定する必要があります。
実行時のCloudWatch Logはエッジサーバのリージョンに排出される
Lambda関数の登録自体はus-east-1 (バージニア北部) ですが、実行はCloudFrontのエッジサーバであるため、実行時のCloudWatch Logの排出先はエッジサーバのロケーションに依存します。 (日本からアクセスした場合には、東京、ソウル、シンガポールリージョンあたりにログが排出されていました。大半は東京。)
使ってみた感想
- 今回の用途以外にも、A/Bテストなどにも利用できそう
- 大量アクセスのある場面には注意が必要
- リクエスト数とLambdaのコード実行時間に比例して利用料金が発生。キャッシュヒット率を高める工夫が必要になってきそう。
今回は以上となります。