Lambda関数のスケーラビリティについてまとめてみた

# はじめに
SAA（AWS Certified Solutions Architect - Associate）取得に向けて勉強を進めていく中でLambdaのスケーラビリティについてよくわからなかったため、まとめてみました。
資格取得を目指すだけの方は「Lambdaにはスケーラビリティがある」という認識だけで十分だと考えています。ただ、知識があって損することはないと思うのでそのような方でもできれば最後まで読んでいただけると幸いです。

※Lambdaに関して資格勉強で学習しているだけで実際に触ったことはありません。
## 目次
**1.Lambdaとは**
**2.スケーラビリティとは**
**3.Lambdaのスケーラビリティについて**
　**3-1.同時実行数とは**
　**3-2.同時実行数の上限(クォータ)について**
　**3-3.同時実行数の算出方法について**
　**3-4.同時実行数と1秒あたりのリクエスト数の違いについて**
　**3-5.スケーリングレートについて**
　**3-6.プロビジョニングされた同時実行について**
**4.まとめ**
**5.参考文献**
# 1.Lambdaとは
Lambdaとはサーバーレスでプログラムのコードを実行できるフルマネージドサービスです。サーバーレスとは、EC2インスタンスなどのサーバーを必要とせずリクエスト発生時にだけプログラムが実行されるアーキテクチャのことで、インフラストラクチャの管理は完全にAWSによって行われます。そのため、サーバー管理が不要というメリットがあります。

発生する金額はリクエスト数に基づいて課金されていくため、コスト効率がいい反面、リクエスト数が多いデータに関してはコストが高くなってしまうという特徴があります。

Lambdaに関して公式ドキュメントでは以下のように説明されています。
>Lambda は可用性の高いコンピューティングインフラストラクチャでコードを実行し、コンピューティングリソースに関するすべての管理を行います。これには、サーバーおよびオペレーティングシステムのメンテナンス、容量のプロビジョニングおよび自動スケーリング、さらにログ記録などが含まれます。Lambda で必要なことは、サポートするいずれかの言語ランタイムにコードを与えることだけです。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html
# 2.スケーラビリティとは
スケーラビリティとはシステムの拡張性のことをいい、具体的にはスケーラビリティは二種類にわけることができる。１つはデータ量やメモリの容量に応じて実行数や容量を増減する（垂直方向）ことで、２つめは負荷が増大した時に予備のサーバーに分散処理させる（水平方向）ことを指します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834095/c9000033-e4a8-98a1-a145-c6b093823e5f.png)

AWSのサービスでイメージしやすいサービスとしてはAuto Scalingなどがあげられます。
私用するメリットとしては、コストの最適化や高可用性の維持が容易にできるという点があります。ただ、その反面デメリットもあります。それは、オートスケールで増えたサーバーが落ち着いた際に削除されるため、データの保存を行っていないとデータが消失してしまうことやアクセスの増加への対応が難しいという点になります。

Auto Scalingについて公式ドキュメントでは以下のように説明されています。
>AWS Auto Scaling は、安定した予測可能なパフォーマンスを可能な限り低コストで維持するためにアプリケーションをモニタリングし、容量を自動で調整します。AWS Auto Scaling を使用すると、複数のサービスにまたがる複数のリソースのためのアプリケーションスケーリングを数分で簡単に設定できます。
AWS Auto Scaling では、アプリケーションが常に適切なリソースを適切なタイミングで取得できます。

https://aws.amazon.com/jp/autoscaling/

# 3.Lambdaのスケーラビリティについて
ここからやっと、本題となるLambdaのスケーラビリティについてお話しをしていこうと思います。

Lambdaはサーバーレスのサービスであるため、スケーラビリティについてイメージすることがあまりなく難しいですが、公式ドキュメントにも少し書いているように自動スケーリングの性質があります。これは、Lambdaのリクエスト数が増えた際に、同時実行数が増えることで内部的にリソース数が増えることを指しています。
つまり、Lambda自身にスケーラビリティがあるわけでなく、Lambdaを実行するインスタンスなどがスケーラビリティがあるため、間接的にLambdaにもスケーラビリティがあるということができるということになります。

以下では、Lambdaには様々な制約やオプションがあるため、それらについて説明していきたいと思います。
#### 1.同時実行とは
Lambdaにおける同時実行とは、複数のリクエストを同時に実行することを指します。
以下の図で説明するとt1では同時実行数は3になり、t2では同時実行数は2になります。
※数字は何回目のリクエストかを表しています

![コメント 2024-08-30 162944.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834095/99ea7416-74e0-90dc-c7e4-978e52a6bdeb.png)

#### 2.同時実行数の上限(クォータ)について
AWSがクラウドサービスであるとは言っても、その実態は物理サーバーがあることには変わりがないためサービスの高可用性などをあげるためにも、Lambdaの同時実行数はアカウントに対して、１つのAWSリージョン内のすべての関数全体での合計数1,000を上限（クォータ）とした同時実行をデフォルトで設定されています。また、上限を超えるとリクエストがドロップされます。
しかし、クォータの引き上げをリクエストしたり、同時実行数を予約しておくことで予約した分を常に確保（予約した分も同時実行数として加算される）することができたりと、可用性を高めることができます。

以下の図では縦軸は同時実行数、横軸は時間を全体で同時実行の上限について表しています。

![コメント 2024-08-29 140520.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834095/3f782a64-c7d7-2e7b-afd6-d997c94b20d1.png)
#### 3.同時実行数の算出方法
Lambdaの同時実行数とリクエスト数同じになるとイメージされやすいですが、実際は異なります。

まず、Lambdaの同時実行数は、**同時実行数＝1秒あたりのリクエスト数×1リクエストの所要時間(秒)** という計算式で算出することが可能です。
つまり、リクエスト数が100件でリクエストの所要時間が1秒だった場合は、同時実行数は100(100×1=100)となり、リクエスト数が100件でリクエストの所要時間が0.5秒だった場合は、同時実行数は50(100×0.5=50)となります。
このことから、同時実行数と１秒あたりのリクエスト数は異なるということが分かります。
#### 4.同時実行数と1秒あたりのリクエスト数の違いについて
同時実行数と1秒あたりのリクエスト数が異なるということは、リクエスト所要時間が0.1秒未満の関数を扱う場合に特に重要になります。

まず、Lambdaには同時実行数の10倍に相当する1秒あたりのリクエスト数という制限があります。つまり、デフォルトの同時実行上限は1,000であるため、デフォルトで1秒あたり最大10,000件のリクエストを処理することができます。

例えば、リクエスト所要時間が0.1秒の場合で、1秒あたり10,000件のリクエストの場合です。同時実行数は1000(20,000×0.05=1,000)になります。この処理は同時実行の制限を満たしているため、正常に実行されます。

一方で、リクエスト所要時間が0.05秒の場合で、1秒あたり20,000件のリクエストの場合です。同時実行数は1000(20,000×0.05=1,000)になります。この処理は同時実行数の10倍に相当する1秒あたりのリクエスト数という制限を満たしていないため、10,000件までのリクエストしか処理されず、スロットリングが発生します。

このような場合は、同時実行数の上限を2,000に引き上げることで同時実行数の10倍に相当する1秒あたりのリクエスト数という制限を満たすことができるようになり、1秒あたりのリクエスト数が20,000件のリクエストも処理できるようになります。

#### 5.スケーリングレートについて
Lambdaがスケーリングできる速度の事をスケーリングレートと呼びます。また、同時実行数や1秒あたりのリクエスト数の上限と同様にスケーリングレートも制限されています。これは、突然のリクエスト数の急増によって必要以上にスケーリングされるのを防ぐために設けられています。もし、スケールの速度が入ってくるリクエストの速度に追いつけない場合は、エラーで失敗してしまいます。

同時実行のスケーリングレートは10秒ごとに1,000の実行環境インスタンス(1秒あたり10,000リクエスト) です。つまり、10秒ごとに最大1,000の追加実行環境インスタンスを各関数に割り当てるか、1秒あたり10,000件の追加リクエストに対応することができます。

#### 6.プロビジョニングされた同時実行について
Lambdaを実行処理をする際に初期化をする時間（コールドスタート）があるため、呼び出し時間が長くなる可能性があり、事前に初期化されているプロビジョニングされた同時実行を使うことで、即座にリクエストへ応答することができます。
また、リクエストが来なくなる時間が一定時間発生した際も通常はインスタンスを終了してしまうことためコールドスタートが発生してしまうが、プロビジョニングされた同時実行に関してはインスタンスを終了されずに保たれるという観点からもリクエストへの応答に関して優位性があります。
しかし、予約された同時実行とは違い追加料金が発生してしまうため、コストに関しては考慮しながら使用する必要もあります。

※以下の図では通常の同時実行とプロビジョニングされた同時実行の呼び出し時間の差を示しています。（数字は何回目のリクエストかを表してます）

![コメント 2024-08-29 120341.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834095/5ac10843-2ea9-0cfe-9180-6a84e4096600.png)

# 4.まとめ
今回私はSAAの勉強を進めていくなかで感じたのは、サービスの特徴など表面的な理解だけでなく、内部的にどう動いているのかまで理解することが大事だと気付きました。ただ、「資格勉強」に標準を合わせて勉強するなら、冒頭で述べさせていただいた通り、ここまでの理解は必要でないと思います。

余談にはなりますが、、、資格取得を目指す場合に何か目的があって目指すと思います。その目的に沿った勉強方法などを意識することで資格取得がその先に繋がると考えているため、是非目的意識を忘れずに持って欲しいと思います（資格はあくまで証明書のようなものだと思ってます）。

# 5.参考文献
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html

https://aws.amazon.com/jp/autoscaling/

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/scaling-behavior.html

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-concurrency.html#concurrency-quotas

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/monitoring-concurrency.html