mybook

サーバーレスとは — FaaS と BaaS の理解

ダイチは週末の午後、カフェでノートパソコンを広げた。画像リサイズ処理のLambda移行に向けて、まずは「サーバーレスとは何か」を正しく理解するところから始めようと思っていた。

「サーバーレス」という言葉は少し誤解を招く。サーバーが存在しないわけではない。AWS のデータセンターにはサーバーがある。ただ、そのサーバーの管理をあなたが行わなくていい——それがサーバーレスの本質だ。

サーバーレスの二つの柱

サーバーレスアーキテクチャは大きく二つのカテゴリに分かれる。

FaaS — Function as a Service

コードを「関数」単位で実行する仕組み。AWS Lambda がその代表格だ。

  • イベントに応じてトリガーされる: HTTPリクエスト、S3へのファイルアップロード、SQSへのメッセージ投入など
  • ステートレス: 各実行は独立しており、実行間で状態を保持しない
  • 短命: 最大15分(Lambda の場合)
  • 自動スケーリング: 同時リクエスト数に応じて自動的にインスタンスが増える

BaaS — Backend as a Service

データベース、認証、ストレージなどのバックエンド機能を、マネージドサービスとして利用する仕組み。

BaaS カテゴリAWS サービス用途
データベースDynamoDB, Aurora Serverlessデータ永続化
オブジェクトストレージS3ファイル保存
認証Cognitoユーザー管理
メッセージキューSQS, SNS非同期通信
API管理API GatewayHTTP エンドポイント

INFO

サーバーレスアーキテクチャとは「FaaS + BaaS の組み合わせでアプリケーションを構築するアプローチ」と理解すると分かりやすい。Lambdaだけがサーバーレスではない。

Lambda の実行モデル

ダイチが最も知りたかったのは「Lambda は具体的にどう動くのか」だった。

実行フロー

Loading diagram...

コールドスタートとは、Lambdaの実行コンテナが初めて起動される時間のこと。コンテナのプロビジョニング、ランタイムの読み込み、関数コードの初期化が発生する。Ruby では通常100〜500ms程度かかる。

ウォームスタートは、既に起動済みのコンテナが再利用される場合。ハンドラの実行だけなので数ms〜数十msで応答する。

同時実行の仕組み

Loading diagram...

3つのリクエストが同時に来れば、3つのLambdaインスタンスが並行して実行される。EC2のように「サーバーが足りない」という状況は起きない(同時実行数の上限はあるが、デフォルト1000で申請により増やせる)。

サーバーレスのトレードオフ

「サーバーレスは万能ではない」とダイチは資料に書き込んだ。

向いているユースケース

  • 不規則なトラフィック: セール時だけ急増するECサイトのAPIなど
  • イベント駆動処理: ファイルアップロード後の変換処理、通知送信など
  • マイクロサービスの個々の機能: 独立した小さな処理単位
  • バッチ処理: 定時実行のデータ集計など

向いていないユースケース

  • 長時間実行処理: Lambda の最大実行時間は15分
  • 低レイテンシが必須: コールドスタートが問題になる
  • 大量のメモリが必要: 最大10GBだが、それを超える処理
  • 常時接続が必要: WebSocket(API Gateway の WebSocket APIで対応可能ではある)

WARNING

サーバーレスへの移行は段階的に行うのが賢明。「全てをLambdaに」ではなく、「この処理はLambdaに向いているか」を都度判断する。

Rails との概念比較

ダイチはRailsエンジニアとして、Lambdaのモデルをよく知っている概念に置き換えて理解しようとした。

Loading diagram...
RailsLambda
ApplicationControllerLambda ハンドラ関数
before_actionLambda Layer / ミドルウェア
config/routes.rbAPI Gateway のルーティング
config/environments/環境変数
GemfileGemfile + Lambda Layer
Puma プロセスLambda 実行コンテナ
rails consoleLambda テスト呼び出し

Rails では rails server で常駐プロセスが起動し、リクエストを受け付け続ける。Lambda では「コードをデプロイしておき、リクエストが来たときだけ起動する」という発想の転換が必要だ。

Lambda のランタイムと実行環境

Lambda がサポートするランタイムは多岐にわたる。

# Ruby 3.2 での Lambda ハンドラの基本構造
# handler: lambda_function.lambda_handler と設定する場合
 
def lambda_handler(event:, context:)
  # event: トリガーからのデータ(Hash)
  # context: 実行環境の情報(残り時間、関数名など)
 
  puts "Function name: #{context.function_name}"
  puts "Remaining time: #{context.get_remaining_time_in_millis}ms"
  puts "Event: #{event.inspect}"
 
  # レスポンスは Hash で返す
  {
    statusCode: 200,
    body: JSON.generate({ message: 'Hello from Lambda!' })
  }
end

event オブジェクトはトリガーによって異なる。API Gateway からのHTTPリクエストであれば、HTTPメソッド、パス、ヘッダー、ボディが含まれる。S3からのトリガーであれば、バケット名とオブジェクトキーが含まれる。

サーバーレスの責任モデル

従来のEC2 vs Lambdaで、何を管理する必要があるかが大きく変わる。

管理項目EC2Lambda
ハードウェアAWSAWS
ハイパーバイザーAWSAWS
OSあなたAWS
ランタイムあなたAWS(選択のみ)
アプリコードあなたあなた
スケーリングあなたAWS
可用性あなたAWS
パッチ適用あなたAWS

ダイチが担当していた「深夜3時のサーバー障害対応」の多くは、「あなた」の行に書かれた管理項目から発生していた。Lambdaに移行することで、管理すべき範囲がアプリケーションコードだけに絞り込まれる。

まとめ

ダイチはカフェのノートを閉じた。整理できた概念をSlackのメモチャンネルに書き残す。

  • サーバーレス = サーバーが無いのではなく、サーバーの管理をしなくていい
  • FaaS(Lambda)+ BaaS(DynamoDB, S3 etc.)の組み合わせ
  • イベント駆動、ステートレス、自動スケーリングが特徴
  • 向き・不向きを見極めることが大事

次のステップは、実際に手を動かすことだ。画像リサイズ処理のLambda移行、その第一歩として「Hello World」から始めよう。