LambdaのProvisioned Concurrencyについて調べました

# はじめに

2019年12月に提供された[LambdaのProvisioned Concurrency](https://aws.amazon.com/jp/about-aws/whats-new/2019/12/aws-lambda-announces-provisioned-concurrency/)に関して調べました。

## 注意

<font color="Red">本記事の記載内容は2020年12月6日時点の仕様に基づいています。</font>

# Lambdaに元々ある概念 → "同時並行性"(Concurrency) (公式でも日本語訳が曖昧)

Lambda関数を並行(水平方向)に実行する際のリソースとなる概念が同時並行性です。

同時並行性には制限が存在しており、定量化として同時実行数(Concurrency Executions)という単位になっています。

制限は、**リージョンごと**に適用され、引き上げることができます。引き上げをリクエストするには、サポートセンターコンソール経由で問い合わせる必要があります。

| リソース |デフォルトの制限|
|-------|------|
|同時実行数|1000|

## 予約した並行性(Reserved Concurrency)

Provisioned Concurrencyの機能が発表される前から、予約した同時並行性(Reserved Concurrency)の機能はありました。

予約した同時並行性の機能というのは、単にリージョン内のある対象Lambda関数に対して常にN個までの同時並行数を確保することを保証させる機能です。
(例えば、あるLambda関数Aに500、関数Bに300の予約数を設定した場合、関数Cは1000-500-300で200までしか同時並行数をどんなにリクエストが来てもスケールさせることができません。)

# Provisioned Concurrency とは

Provisioned Concurrencyは上述の同時並行数をリクエストが実際にくる前に事前に立ち上げておく機能です。

たとえ同時実行数自体を予約していたとしても、Lambda関数には以下の課題があります。Provisioned Concurrencyは以下の課題を解決するための新機能です。

### 課題1: 初期リクエストに関してコールドスタートとなりレイテンシーが大きくなる

Lambdaの代表的な課題でLambdaは利用されないと実行環境が存在しない状態になるため、そこからの初期リクエストでは実行環境構築に時間がかかりレスポンスが遅くなってしまいます。

### 課題2: スパイクなリクエストが来た場合、スケーリングが追いつかない

根本的には課題1と同じですが、スパイクなリクエスト来ると下記図のようにスケーリングが追いつかず、スロットリングに引っかかってしまう場合があります。

![clip-20200731160720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91562/49ce9b90-1e56-9174-e81c-31ac1cef4e96.png)

## そこでProvisioned Concurrencyの機能が提供された

下記図のように、事前に同時実行数を立ち上げておくことで上記の課題を解決することができます。

![clip-20200731155936.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91562/4b3070ee-5b33-0f7b-85f8-2e26d7d023fb.png)

https://dev.classmethod.jp/articles/lambda-provisioned-concurrency-coldstart/ の記事などを見るとコールドスタートの問題が解決できるようです。

# Provisioned Concurrency の料金

 [【公式】AWS Lambda 料金](https://aws.amazon.com/jp/lambda/pricing/) を参照しています。

LambdaのProvisioned Concurrencyを利用した場合、Lambda利用としての合計料金は下記のように独立した3つの概念の和となる内訳になります。


```
Lambda利用の合計料金 = Provisioned Concurrency料金 + リクエスト料金 + コンピューティング料金
```

Provisioned Concurrency は1 GB-秒あたり 0.0000053835USD とTokyoリージョンでは設定されています。例として、 対象のLambda関数に

* **256 MB のメモリ**を割り当て
* **同時実行数100**

の設定でその関数で Provisioned Concurrency を 31 日間有効したとき、その月のProvisioned Concurrencyの料金は、
279.02 USD になります

メモリ割り当て量と同時実行数はそれぞれ量に応じて料金に比例します。

#  Provisioned Concurrency を設定する上でのポイント

## Auto Scaling設定をしよう

以下の2つのページを参照しました。

* https://dev.classmethod.jp/articles/lambda-support-scheduled-autoscaling/
* https://dev.classmethod.jp/articles/lambda-support-provisioned-concurrency-autoscaling-2/

Provisioned Concurrencyを利用するにあたり、コストの面から"リクエスト開始からのリクエストの増減を事前に把握"した上で、必要なときにのみProvisionedさせておくことがベターだと言えます。

AWSのEC2やFargateなどと同様に[Application Auto Scaling](https://docs.aws.amazon.com/ja_jp/autoscaling/application/userguide/what-is-application-auto-scaling.html)から実行数やCPU利用率などの①パラメータベースのスケーリング設定と、②時間帯ベースのスケーリング設定の両方ともLambdaのProvisioned Concurrencyに対して設定することができます。

## 本当にLambdaを利用する必要ありますか？

[【クラメソ記事】安い？それとも高い？Provisioned Concurrencyを有効化したLambdaのコストに関する考察 #reinvent
](https://dev.classmethod.jp/articles/simulate-provisioned-concurrency-cost/)を参照しました。

Provisioned Concurrencyはある意味Lambdaの良さを失わせていると言えるようです。

コールドスタートを避けたりスケジュールされたスケーリングを求める場合はFargateにすることはできないか、など再検討する価値はあるようです。

# 参考

* [【公式】AWS Lambda 料金](https://aws.amazon.com/jp/lambda/pricing/)
* [【クラメソ記事】安い？それとも高い？Provisioned Concurrencyを有効化したLambdaのコストに関する考察 #reinvent
](https://dev.classmethod.jp/articles/simulate-provisioned-concurrency-cost/)