レストランキッチンで理解する効率的な関数実行
Lambda関数を、プロのシェフのキッチン運営で分かりやすく説明します!
AWS Lambda
は、
レストランの一つのキッチン
のようなもの。
お客さん(リクエスト)が来たら、
料理(処理)
を作って提供します。
お客さんが来るたびに...
👆
時間がかかって
お客さんを待たせる
事前に準備しておいて...
👆
すぐに調理開始
お客さんも満足
キッチンの準備エリア
ここで道具や材料を準備しておくと、
次の注文でも
再利用
できます
実際の調理エリア
お客さんの注文を受けて、
準備済みの道具で
料理を作る
場所
よく使う材料の保管場所
一度ダウンロードした画像や
ファイルを
一時保存
新しいキッチンを一から準備
やることリスト:
準備済みキッチンですぐ調理
やることリスト:
キッチンの基本道具を常設
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();
};
調味料棚を固定設置
データベース接続は時間がかかるので、一度接続したら使い回す
毎回新しい接続を作るのは非効率
// ✅ 良い例:接続を使い回し
let dbConnection = null;
export const handler = async (event) => {
if (!dbConnection) {
// 初回のみ接続を作成(調味料棚を設置)
dbConnection = await createDbConnection();
}
// 既存の接続を使用(調味料棚から取る)
const result = await dbConnection.query('SELECT ...');
};
よく使う食材を手の届く場所に保管
画像や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));
};
レシピ本を見やすい場所に配置
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万回実行時:
平均実行時間: 0.8秒
月間100万回実行時:
月額
$45の節約
(75%コスト削減)
年間では
$540の節約
!
同じ機能でも、書き方でこんなに変わります
// 毎回新しいキッチンを準備(非効率)
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 で同時実行数を制御。他のサービスに影響を与えないよう適切な制限を設定。
🏪 ハンドラー外で準備 = キッチンの常設道具(SDK、DB接続、設定)
👨🍳 ハンドラー内で処理 = 実際の調理作業(ビジネスロジック)
📁 /tmp でキャッシュ = よく使う食材の保管庫(ファイル一時保存)
♻️ リソース再利用 = 準備済みキッチンの活用(ウォームスタート)
この4つのポイントを実践することで、 Lambda関数を3-10倍高速化 し、 大幅なコスト削減 を実現できます!
🎯 今すぐできること:
Created by SSuzuki1063
AWS SAP Learning Resources
Created by SSuzuki1063
AWS SAP Learning Resources