Serverless-обробка файлів: Lambda + S3 trigger під ключ
При завантаженні зображень в S3 потрібно автоматично генерувати thumbnails, але Lambda не справляється з великими файлами. Потрібна відмовостійка архітектура з чергами та моніторингом. Ми — команда з досвідом serverless-розробки — побудували десятки таких систем. У цій статті розберемо типову архітектуру, обробку помилок та підводні камені.
Lambda + S3 trigger — класичний serverless патерн для обробки файлів. Файл завантажується в S3, подія автоматично запускає Lambda, яка обробляє файл і зберігає результат. Не потрібен постійно працюючий сервер, масштабування автоматичне. Однак без правильної схеми з чергами ви ризикуєте втратити події. Економія на інфраструктурі може досягати 70% порівняно з виділеним сервером, а вартість обробки одного файлу знижується в 3-5 разів. Розглянемо, як побудувати production-grade обробку з чергами, DLQ та моніторингом.
Які завдання вирішує Lambda + S3 та базова архітектура
Типові завдання: генерація thumbnail при завантаженні зображення, конвертація відео в різні формати та роздільну здатність, обробка CSV/Excel файлів з імпортом даних в БД, PDF-генерація з шаблонів, антивірусне сканування завантажуваних файлів, OCR та вилучення тексту з документів, трансформація даних (XML → JSON, нормалізація).
| Тип файлу | Приклади | Рекомендований підхід |
|---|---|---|
| Зображення | JPG, PNG, WebP | Lambda + Pillow |
| Документи | PDF, DOCX | Lambda + pdfminer, python-docx |
| Відео | MP4, AVI | AWS MediaConvert |
| Таблиці | CSV, XLSX | Lambda + pandas (стрімінг) |
| Архіви | ZIP, RAR | Lambda + zipfile (стрімінг) |
Базова архітектура:
[Користувач] → S3 upload → [S3 Event Notification]
↓
[Lambda Function]
↓
[Оброблений файл → S3 Output]
[Метадані → DynamoDB]
[Нотифікація → SQS/SNS]
# S3 bucket для вхідних файлів
resource "aws_s3_bucket" "uploads" {
bucket = "myapp-uploads"
}
# S3 bucket для оброблених файлів
resource "aws_s3_bucket" "processed" {
bucket = "myapp-processed"
}
# Об'єднана конфігурація: S3 → SNS → SQS
resource "aws_s3_bucket_notification" "upload_trigger" {
bucket = aws_s3_bucket.uploads.id
topic {
topic_arn = aws_sns_topic.file_events.arn
events = ["s3:ObjectCreated:*"]
}
}
resource "aws_sns_topic_subscription" "to_sqs" {
topic_arn = aws_sns_topic.file_events.arn
protocol = "sqs"
endpoint = aws_sqs_queue.file_processing.arn
}
Як масштабувати обробку при пікових навантаженнях?
Lambda масштабується автоматично, але при різкому сплеску завантажень може виникнути троттлінг. Ми використовуємо SQS-чергу для буферизації: S3 → SNS → SQS → Lambda. Це гарантує, що жодна подія не загубиться. При перевищенні ліміту concurrent executions черга накопичує повідомлення, і Lambda обробляє їх у міру звільнення. Для критичних завдань налаштовуємо Reserved Concurrency.
Обробник Lambda та великі файли
import boto3
import json
import os
from urllib.parse import unquote_plus
from PIL import Image
import io
s3 = boto3.client('s3')
def handler(event, context):
results = []
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = unquote_plus(record['s3']['object']['key'])
try:
result = process_image(bucket, key)
results.append({'key': key, 'status': 'success', **result})
except Exception as e:
print(f"Error processing {key}: {e}")
results.append({'key': key, 'status': 'error', 'error': str(e)})
return results
def process_image(bucket: str, key: str) -> dict:
# Завантажити оригінал
obj = s3.get_object(Bucket=bucket, Key=key)
image_data = obj['Body'].read()
image = Image.open(io.BytesIO(image_data))
thumbnails = {}
for size_name, (width, height) in [('sm', (150, 150)), ('md', (400, 400)), ('lg', (800, 800))]:
thumb = image.copy()
thumb.thumbnail((width, height), Image.LANCZOS)
buffer = io.BytesIO()
thumb.save(buffer, format=image.format or 'JPEG', quality=85)
buffer.seek(0)
output_key = key.replace('images/', f'thumbnails/{size_name}/')
s3.put_object(
Bucket=os.environ['OUTPUT_BUCKET'],
Key=output_key,
Body=buffer,
ContentType=f'image/{(image.format or "JPEG").lower()}'
)
thumbnails[size_name] = output_key
return {'thumbnails': thumbnails, 'original_size': image.size}
Lambda має обмеження: /tmp до 10 ГБ, timeout до 15 хвилин, пам'ять до 10 ГБ. Для файлів >100 МБ застосовуємо стрімінг, обробляючи дані частинами без завантаження в пам'ять цілком.
Чому SNS+SQS надійніше прямого виклику Lambda?
S3 event notifications не підтримують DLQ напряму. Якщо Lambda завершиться помилкою, подія втрачається. Схема з SNS та SQS гарантує доставку: невдалі виклики після N спроб потрапляють в DLQ. Ви зможете проаналізувати та перезапустити обробку. Це відповідає best practices AWS для продакшену.
Докладніше про конфігурацію DLQ
Для SQS-черги налаштовується redrive policy: після, наприклад, 5 невдалих спроб повідомлення переміщується в DLQ. Це дозволяє не втрачати події та аналізувати помилки.
Lambda vs ECS: що обрати?
| Критерій | Lambda | ECS Fargate |
|---|---|---|
| Макс. час виконання | 15 хв | Не обмежено |
| Макс. пам'ять | 10 ГБ | 30 ГБ |
| Вартість | За мілісекунди | За vCPU/год |
| Масштабування | Миттєве | 30–60 сек |
| Оптимально для | Короткі задачі (<15 хв) | Довгі задачі, high memory |
Для обробки зображень та документів Lambda простіше і дешевше. Для відео-транскодингу використовуємо MediaConvert.
Конфігурація Lambda для обробки файлів
resource "aws_lambda_function" "processor" {
filename = "processor.zip"
function_name = "file-processor"
role = aws_iam_role.processor.arn
handler = "handler.handler"
runtime = "python3.12"
timeout = 300
memory_size = 1024
ephemeral_storage {
size = 2048
}
environment {
variables = {
OUTPUT_BUCKET = aws_s3_bucket.processed.bucket
}
}
}
Моніторинг та метрики
- Кількість оброблених файлів на годину
- Середній час обробки за типом файлу
- Error rate + вміст DLQ
- Lambda duration distribution
CloudWatch Dashboard з цими метриками + алерт при зростанні DLQ.
Що входить в роботу та орієнтовні терміни
- Розробка Lambda-функції на Python (або Node.js/Go) під ваш тип файлів
- Інфраструктура Terraform / Pulumi з S3, SNS, SQS, DLQ
- Налаштування моніторингу CloudWatch + алерти
- Код-рев'ю та тестування на навантаження до 1000 файлів/хв
- Документація архітектури та інструкція з деплою
- Навчання команди замовника (1-2 години)
- Підтримка 2 тижні після здачі
Орієнтовні терміни:
- Аналіз вимог та прототип — 2-3 дні
- Повний pipeline з DLQ, моніторингом — 4-6 днів
- Інтеграція з вашим додатком (API Gateway, Cognito — опціонально) — 2-5 днів
Реальні терміни залежать від складності обробки. Зв'яжіться з нами — оцінимо ваш проєкт за 1 день. Замовте консультацію та отримайте попередню оцінку без зобов'язань.







