AWS Lambda 无服务器 — 按函数调用次数付费,无需管理服务器¶
一句话说明¶
AWS Lambda 让你只写函数代码,AWS 自动管理服务器、扩容、负载均衡,函数被触发时才运行,闲置时不收费,适合处理 S3 上传事件、定时任务、API 请求等场景。
安装与配置¶
# 安装 AWS SAM CLI(Lambda 本地开发工具)
pip install aws-sam-cli
sam --version
# 安装 AWS CLI(如未安装)
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
# 初始化 SAM 项目
sam init --runtime python3.12 --name my-lambda-app # Python 3.12 运行时
# 项目目录结构
# my-lambda-app/
# ├── template.yaml # SAM 模板(描述资源)
# ├── hello_world/
# │ ├── app.py # Lambda 函数代码
# │ └── requirements.txt # Python 依赖
# └── tests/ # 测试目录
# template.yaml — SAM 模板(定义 Lambda 和触发器)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31 # 使用 SAM 简化语法
Resources:
ProcessFastqFunction: # 资源逻辑名
Type: AWS::Serverless::Function # Lambda 函数类型
Properties:
FunctionName: process-fastq # 函数名称
CodeUri: process_fastq/ # 代码目录
Handler: app.lambda_handler # 入口:文件名.函数名
Runtime: python3.12 # 运行时
Timeout: 900 # 最大运行时间(秒),Lambda 最长15分钟
MemorySize: 1024 # 内存(MB),越大越贵但也越快
Environment:
Variables:
RESULT_BUCKET: my-results-bucket # 环境变量
Events:
S3Upload: # 触发器:S3 上传事件
Type: S3
Properties:
Bucket: !Ref RawDataBucket
Events: s3:ObjectCreated:* # 任何文件创建都触发
Filter:
S3Key:
Rules:
- Name: suffix
Value: .fastq # 只响应 .fastq 文件
RawDataBucket:
Type: AWS::S3::Bucket # 创建 S3 桶
核心用法¶
# process_fastq/app.py — Lambda 函数代码
import json
import boto3 # AWS SDK
import os
# 在函数外初始化客户端(Lambda 容器复用,可提高性能)
s3 = boto3.client('s3')
result_bucket = os.environ['RESULT_BUCKET'] # 从环境变量读取桶名
def lambda_handler(event, context):
"""
Lambda 入口函数
event: 触发事件的数据(JSON 格式)
context: 运行时信息(剩余时间、内存等)
"""
print(f"接收到事件: {json.dumps(event)}") # 打印日志(自动发送到 CloudWatch)
# ── 从 S3 事件中提取文件信息 ──
for record in event['Records']: # 可能一次触发多个文件
bucket = record['s3']['bucket']['name'] # 来源桶名
key = record['s3']['object']['key'] # 文件路径(URL 编码)
key = key.replace('+', ' ') # 解码空格
print(f"处理文件: s3://{bucket}/{key}")
# ── 下载文件到 /tmp(Lambda 临时空间,最大 10GB)──
local_path = f'/tmp/{os.path.basename(key)}' # 本地临时路径
s3.download_file(bucket, key, local_path)
# ── 处理文件(示例:统计 FASTQ 读段数)──
read_count = count_reads(local_path)
print(f"读段总数: {read_count}")
# ── 上传结果 ──
result_key = f'results/{os.path.basename(key)}.stats.txt'
result_content = f"File: {key}\nTotal reads: {read_count}\n"
s3.put_object(
Bucket=result_bucket,
Key=result_key,
Body=result_content.encode('utf-8'),
)
return {
'statusCode': 200,
'body': json.dumps({'message': '处理完成', 'files': len(event['Records'])}),
}
def count_reads(fastq_path: str) -> int:
"""统计 FASTQ 文件中的读段数"""
count = 0
with open(fastq_path, 'r') as f:
for line in f:
if line.startswith('@'): # FASTQ 每4行一个读段,@ 开头是序列头
count += 1
return count
实战案例¶
# ── 本地调试(无需部署到云端)──
sam local invoke ProcessFastqFunction \
--event events/s3-event.json # 模拟 S3 触发事件
# events/s3-event.json(模拟事件)
cat > events/s3-event.json << 'EOF'
{
"Records": [{
"s3": {
"bucket": { "name": "my-raw-bucket" },
"object": { "key": "sample.fastq", "size": 1024 }
}
}]
}
EOF
# ── 启动本地 API 端点 ──
sam local start-api # 在本地模拟 API Gateway
# ── 部署到 AWS ──
sam build # 构建函数包
sam deploy --guided # 引导式部署(第一次)
sam deploy # 后续部署(用上次配置)
# ── 查看日志 ──
sam logs -n ProcessFastqFunction --stack-name my-lambda-app --tail # 实时日志
# ── 直接调用已部署的函数 ──
aws lambda invoke \
--function-name process-fastq \
--payload '{"test": true}' \ # 输入 JSON
/tmp/output.json # 输出保存到本地
cat /tmp/output.json # 查看返回结果
常见报错与解决¶
| 报错 | 原因 | 解决方法 |
|---|---|---|
Task timed out after 3.00 seconds | 默认超时3秒太短 | 在 template.yaml 中增加 Timeout |
Runtime.ImportModuleError | 依赖未打包 | 在 requirements.txt 加依赖,重新 sam build |
No space left on device | /tmp 空间(10GB)不足 | 处理完立即删除临时文件 |
| 冷启动慢 | 首次调用需初始化容器 | 用 ProvisionedConcurrency,或换 Go/Rust 减少启动时间 |
AccessDenied | IAM 角色没有 S3 权限 | 在 template.yaml 的 Policies 中添加 S3 权限 |
速查表¶
# SAM 命令
sam init # 初始化项目
sam build # 打包依赖
sam local invoke # 本地调用
sam local start-api # 本地 API 模拟
sam deploy # 部署到 AWS
sam logs # 查看日志
sam delete # 删除部署
# Lambda 限制(2025年)
最大运行时间: 15 分钟(900秒)
最大内存: 10 GB
/tmp 空间: 10 GB
部署包大小: 50 MB(压缩)/ 250 MB(解压)
请求并发: 1000(默认,可申请提高)
# 费用(按需计费)
前 100 万次调用/月免费
超出部分: $0.20/百万次
计算费用: $0.00001667/GB-秒
# 官方文档:https://docs.aws.amazon.com/lambda/
# SAM 文档:https://docs.aws.amazon.com/serverless-application-model/