🍳 AWS Lambda ベストプラクティス

レストランキッチンで理解する効率的な関数実行

🏠 準備 ↔️ 🍳 調理 ↔️ 💰 コスト削減

Lambda関数を、プロのシェフのキッチン運営で分かりやすく説明します!

🤔 Lambda関数の基本って何?

📝 簡単に言うと...

AWS Lambda は、 レストランの一つのキッチン のようなもの。
お客さん(リクエスト)が来たら、 料理(処理) を作って提供します。

❌ 毎回準備する非効率なキッチン

お客さんが来るたびに...

  • 🔪 包丁を研ぐ
  • 🧂 調味料を取りに行く
  • 🔥 コンロを温める
  • 📦 食材を冷蔵庫から出す

👆 時間がかかって
お客さんを待たせる

✅ 準備済みの効率的なキッチン

事前に準備しておいて...

  • 🔪 包丁は常に手元に
  • 🧂 調味料は作業台に配置
  • 🔥 コンロは温めておく
  • 📦 よく使う食材は手の届く場所に

👆 すぐに調理開始
お客さんも満足

🍳 キッチンの準備エリアを理解しよう

Lambda関数 = レストランキッチン

🏪

ハンドラー外エリア
(グローバルスコープ)

キッチンの準備エリア
ここで道具や材料を準備しておくと、
次の注文でも 再利用 できます

配置するもの:
• SDK クライアント(包丁・フライパン)
• DB接続(調味料セット)
• 設定情報(レシピ本)
👨‍🍳

ハンドラー内エリア
(関数スコープ)

実際の調理エリア
お客さんの注文を受けて、
準備済みの道具で 料理を作る 場所

やること:
• リクエスト処理(注文を受ける)
• ビジネスロジック(料理を作る)
• レスポンス返却(料理を提供)
📁

/tmp ディレクトリ
(食材保管庫)

よく使う材料の保管場所
一度ダウンロードした画像や
ファイルを 一時保存

保存するもの:
• 画像・動画ファイル
• CSVデータ
• 機械学習モデル

⚡ コールドスタート vs ウォームスタート

🥶

コールドスタート(初回)

新しいキッチンを一から準備

3-5秒

やることリスト:

  • キッチンの電源を入れる
  • コードを読み込む
  • SDK クライアントを初期化
  • データベース接続を確立
  • やっと料理開始...
🔥

ウォームスタート(2回目以降)

準備済みキッチンですぐ調理

100-300ms

やることリスト:

  • ✅ キッチン準備済み
  • ✅ 道具は手元にある
  • ✅ 材料も揃っている
  • ✅ 接続も確立済み
  • 🍳 すぐに料理開始!

📋 実践的なベストプラクティス

🔧 効率的なキッチン設定法

1

SDK クライアントをハンドラー外で初期化

キッチンの基本道具を常設
AWS SDK(包丁・フライパン)は、ハンドラー外で準備しておく
次の注文でも同じ道具を再利用できる

// ✅ 良い例:ハンドラー外で初期化
import AWS from 'aws-sdk';
const s3 = new AWS.S3(); // ←包丁を常に手元に
const dynamodb = new AWS.DynamoDB(); // ←調味料セットを準備

export const handler = async (event) => {
    // ここですぐに s3 や dynamodb を使える
    const result = await s3.getObject({...}).promise();
};
2

データベース接続を使い回す

調味料棚を固定設置
データベース接続は時間がかかるので、一度接続したら使い回す
毎回新しい接続を作るのは非効率

// ✅ 良い例:接続を使い回し
let dbConnection = null;

export const handler = async (event) => {
    if (!dbConnection) {
        // 初回のみ接続を作成(調味料棚を設置)
        dbConnection = await createDbConnection();
    }
    
    // 既存の接続を使用(調味料棚から取る)
    const result = await dbConnection.query('SELECT ...');
};
3

/tmp ディレクトリで静的アセットをキャッシュ

よく使う食材を手の届く場所に保管
画像やCSVファイルなど、重いファイルは /tmp に保存
次回の処理で再ダウンロードを回避

// ✅ 良い例:ファイルキャッシュ
import fs from 'fs';

const CACHE_FILE = '/tmp/heavy_data.json';

export const handler = async (event) => {
    if (!fs.existsSync(CACHE_FILE)) {
        // 初回のみダウンロード(食材を仕入れ)
        const data = await downloadHeavyFile();
        fs.writeFileSync(CACHE_FILE, JSON.stringify(data));
    }
    
    // キャッシュから読み込み(保管庫から取り出し)
    const cachedData = JSON.parse(fs.readFileSync(CACHE_FILE));
};
4

環境変数と設定を外出しする

レシピ本を見やすい場所に配置
API キーやDB接続文字列は環境変数に設定
ハンドラー外で読み込んで、毎回参照しない

// ✅ 良い例:設定を事前読み込み
const DB_HOST = process.env.DB_HOST; // ←レシピ本を準備
const API_KEY = process.env.API_KEY;

export const handler = async (event) => {
    // 設定はすでに読み込み済み
    const connection = connect(DB_HOST);
};

💰 コスト削減効果を数字で見る

📊 実際の効果測定

ベストプラクティスを適用すると、 実行時間が大幅短縮 され、
Lambda の課金時間も減り、 コストが削減 されます!

❌ 非効率なパターン

毎回の実行時間: 3.2秒

月間100万回実行時:

  • 実行時間: 3,200,000秒
  • 概算費用: $60/月
😰

✅ 最適化後のパターン

平均実行時間: 0.8秒

月間100万回実行時:

  • 実行時間: 800,000秒
  • 概算費用: $15/月
😍

🎯 節約効果

月額 $45の節約 (75%コスト削減)
年間では $540の節約

🎯 具体的な実装例

📝 悪い例 vs 良い例

同じ機能でも、書き方でこんなに変わります

❌ 悪い例:毎回準備するパターン

// 毎回新しいキッチンを準備(非効率)
export const handler = async (event) => {
    // ハンドラー内で毎回初期化(道具を毎回準備)
    const s3 = new AWS.S3();
    const dynamodb = new AWS.DynamoDB();
    
    // 毎回データベース接続(調味料を毎回取りに行く)
    const dbConnection = await createDbConnection();
    
    // 毎回ファイルダウンロード(材料を毎回仕入れ)
    const heavyData = await downloadHeavyFile();
    
    // やっと処理開始...
    const result = await processData(heavyData);
    
    return result;
};

問題点: 毎回3-5秒の準備時間がかかる 😰

✅ 良い例:準備済みキッチンパターン

// キッチンの常設準備(効率的)
import AWS from 'aws-sdk';

// グローバルスコープ:基本道具を常設
const s3 = new AWS.S3();
const dynamodb = new AWS.DynamoDB();

// 接続を使い回し用
let dbConnection = null;

// キャッシュ管理
const CACHE_FILE = '/tmp/heavy_data.json';

export const handler = async (event) => {
    // データベース接続の再利用
    if (!dbConnection) {
        dbConnection = await createDbConnection();
    }
    
    // ファイルキャッシュの活用
    let heavyData;
    if (fs.existsSync(CACHE_FILE)) {
        heavyData = JSON.parse(fs.readFileSync(CACHE_FILE));
    } else {
        heavyData = await downloadHeavyFile();
        fs.writeFileSync(CACHE_FILE, JSON.stringify(heavyData));
    }
    
    // すぐに処理開始!
    const result = await processData(heavyData);
    
    return result;
};

メリット: 2回目以降は0.1-0.3秒で開始! 😍

✨ その他の重要なベストプラクティス

🔒

機密情報の管理

AWS Systems Manager Secrets Manager を使って機密情報を安全に管理。ハードコーディングは絶対NG!

適切なメモリ設定

処理内容に応じて メモリサイズを最適化 。多すぎると無駄、少なすぎると遅い。128MB〜3008MBで調整。

📊

監視とログ

CloudWatch Logs でエラー監視。 AWS X-Ray でパフォーマンス分析。問題の早期発見が重要。

🎯

並行実行数の制御

Reserved Concurrency で同時実行数を制御。他のサービスに影響を与えないよう適切な制限を設定。

❓ よくある質問

🤔 /tmp ディレクトリの容量制限は?
⏰ ウォームスタートはいつまで続くの?
💾 データベース接続数の制限は?
🚀 他に性能向上のコツは?

🎯 まとめ

🏪 ハンドラー外で準備 = キッチンの常設道具(SDK、DB接続、設定)

👨‍🍳 ハンドラー内で処理 = 実際の調理作業(ビジネスロジック)

📁 /tmp でキャッシュ = よく使う食材の保管庫(ファイル一時保存)

♻️ リソース再利用 = 準備済みキッチンの活用(ウォームスタート)


この4つのポイントを実践することで、 Lambda関数を3-10倍高速化 し、 大幅なコスト削減 を実現できます!


🎯 今すぐできること:

  • 既存のLambda関数を見直して、ハンドラー外に移動できるものを探す
  • CloudWatch Logs で実行時間をチェックして改善効果を測定
  • 頻繁にダウンロードするファイルがあれば /tmp キャッシュを検討

Created by SSuzuki1063

AWS SAP Learning Resources

Created by SSuzuki1063

AWS SAP Learning Resources