Dev Study
AWSサービスの内部原理 コース

19. 同時実行の正体 — 1環境1リクエスト、並行数だけ環境を複製する

Lambdaの同時実行は「スレッドを増やす」のではなく「実行環境を丸ごと複製する」——その仕組みを6つの図で追います。

① 1つの環境は同時に1リクエストだけ

リクエスト 1件環境に到着
1つのmicroVMが順に処理
Init フェーズハンドラ外のコードを実行
Invoke フェーズハンドラ本体を実行
完了するまで
環境はビジー他のリクエストを一切受け付けない
並行リクエスト環境の内側では走らない
  • Lambdaは「リクエスト並行のためのスレッド共有」を起こさない → 開発者はそれを心配しなくてよい
  • ただし自分のコードが明示的にスレッド/非同期を作れば、その中では競合が起こり得る
  • ウォーム環境に残るグローバル状態には別途注意(⑤で詳述)

microVMはリクエストを受けるとInit→Invokeと進み、終わるまで「ビジー」。Lambdaが環境内にスレッドを注入して複数リクエストを詰め込むことはない。

② 2つ目が来たら? — スレッドを増やさず環境を丸ごと複製

同時リクエスト × 3
どうスケールする?
スレッドモデル1台の中でスレッド追加・メモリ共有
採用しない
プロセスの複製独立したmicroVMを水平に並べる
Lambdaの答え
同時実行数(Concurrency)ちょうどの数だけ
環境Aリクエスト1
環境Bリクエスト2
環境Cリクエスト3
  • 10リクエストが本当に同時に重なれば10環境、100なら100環境が並ぶ
  • 環境間は完全隔離 — 片方のクラッシュやメモリ状態が他方に漏れない

同時リクエストにはmicroVMごとの複製(スケールアウト)で応える。共有メモリがない代わりに環境間は完全に隔離され、クラッシュや状態が他方に漏れない。

③ 必要な環境数はリトルの法則で決まる

平均リクエスト毎秒流入レート
×
平均実行秒数1件がシステムに滞在する時間
掛け算すると
Concurrency必要な環境の数
同じ毎秒100リクエストでも
処理 1秒100 × 1 = 100環境
処理 0.5秒100 × 0.5 = 50環境
早く解放→再利用に回る
  • 処理が長いほど環境が長く占有され、同じ流入量でも必要な環境数は増える
  • 同時実行数はアカウント単位でデフォルト上限1000 — 見積もりが超えるなら上限緩和を申請

Concurrency = 平均リクエスト毎秒 × 平均実行秒数。必要な並列度は流入レートだけでなく「各仕事の滞在時間」との積で決まる。

④ 新しいリクエストが来たら — 再利用 or 新規作成

新しいリクエスト到着
初期化済みで空いている環境はあるか?
あり → 再利用Initを丸ごと省略(速い)
なし → 新規作成Initやり直し = コールドスタート
  • 公式の例: リクエスト6〜8は処理を終えて空いた環境A・B・Cを再利用
  • 空きがなかった5番と9番のときだけ新しい環境E・Fを作成
  • 過剰なスケール防止: 環境を作れる速さは1関数あたり10秒ごとに最大1000環境まで

空いている初期化済み環境があれば再利用し、Init(コールドスタート)を丸ごと省く。空きがないときだけ新しい環境を作る。

⑤ 再利用される環境は「まっさら」ではない

呼び出し N 終了環境は破棄されず待機
同じmicroVMが次の呼び出しへ — 引き継がれるもの
グローバル変数・DB接続ハンドラ外(Init)で作ったオブジェクト
/tmp の内容凍結をまたいで残る
未完了のバックグラウンド処理次の呼び出し冒頭で再開されることも
使い方しだいで
定石接続・クライアント初期化はハンドラ外に置いて再利用
落とし穴前回の状態がグローバル変数や/tmpに残り次のリクエストへ漏れる
  • 新規作成された環境は初期化からやり直すため、コールドスタートを伴う

前の呼び出しと同じmicroVMが回ってくるため、ハンドラ外で作った状態はそのまま次の呼び出しに引き継がれる。定石にも落とし穴にもなる。

⑥ まとめ — 同時実行の正体は三点セット

1環境 1リクエスト環境内に並行なし
並行数だけ環境を複製Concurrency = 毎秒 × 実行秒
空きは状態を保ったまま再利用Init省略・状態は引き継ぎ

この3つを押さえれば、Lambdaのスケーリングとウォームスタートの挙動が一本の線でつながる。

公式ドキュメントで詳しく ↗