AWS

Ôn thi AWS DVA-C02 : AWS Lambda

Giới thiệu về AWS Lambda

AWS Lambda là một dịch vụ điện toán không cần máy chủ (serverless computing) được Amazon Web Services cung cấp. Dịch vụ này cho phép nhà phát triển chạy mã mà không cần phải quản lý hoặc cấu hình máy chủ. Lambda tự động xử lý tất cả các công việc cần thiết để chạy mã của bạn, bao gồm cung cấp tài nguyên điện toán, quản lý quy mô tự động, giám sát hiệu suất và duy trì cơ sở hạ tầng máy chủ.

Nguyên lý hoạt động của AWS Lambda

Mô hình thực thi

  1. Function-as-a-Service (FaaS): Lambda hoạt động theo mô hình FaaS, trong đó đơn vị cơ bản là một hàm (function).
  2. Event-driven: Lambda functions được kích hoạt bởi các sự kiện (events) từ các dịch vụ AWS khác hoặc từ các ứng dụng tùy chỉnh.
  3. Stateless: Mỗi lần gọi Lambda là độc lập, không duy trì trạng thái giữa các lần gọi.

Vòng đời của một Lambda function

  1. Upload code: Nhà phát triển tải mã nguồn lên AWS Lambda
  2. Configure trigger: Cấu hình sự kiện kích hoạt function
  3. Event occurrence: Khi sự kiện xảy ra, Lambda khởi tạo một môi trường thực thi
  4. Function execution: Mã được thực thi trong môi trường này
  5. Result return: Kết quả được trả về và môi trường có thể được tái sử dụng hoặc hủy

Cold Start và Warm Start

  • Cold Start: Khi một Lambda function được gọi lần đầu hoặc sau một thời gian không hoạt động, AWS cần khởi tạo một môi trường mới, dẫn đến độ trễ cao hơn.
  • Warm Start: Nếu một function đã được gọi gần đây, AWS có thể tái sử dụng môi trường đã khởi tạo, giảm độ trễ.

Cold start có thể kéo dài từ vài trăm mili giây đến vài giây tùy thuộc vào:

  • Ngôn ngữ lập trình sử dụng
  • Kích thước của package function
  • Số lượng dependencies
  • VPC (Virtual Private Cloud) configuration

Cấu trúc của một Lambda Function

Handler function

Handler là điểm vào của mã Lambda, định dạng chung là:

filename.function_name

Ví dụ với Node.js:

exports.handler = async (event, context) => {
    // Mã của bạn ở đây
    return {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!')
    };
};

Parameters

Lambda function nhận các tham số chính:

  1. event: Chứa dữ liệu được chuyển từ dịch vụ gọi Lambda
  2. context: Cung cấp thông tin về môi trường thực thi hiện tại
  3. callback (tùy chọn): Phương thức để trả về kết quả trong các function không sử dụng async/await hoặc Promise

Các thành phần của một Lambda deployment package

  • Function code: Mã thực thi chính
  • Dependencies: Các thư viện được sử dụng
  • Layer (tùy chọn): Các thư viện và components được chia sẻ giữa nhiều function
  • Configuration: Cấu hình memory, timeout, environment variables…

Ngôn ngữ lập trình được hỗ trợ

AWS Lambda hỗ trợ nhiều ngôn ngữ lập trình phổ biến:

  • Node.js (JavaScript)
  • Python
  • Java
  • C# (.NET Core)
  • Go
  • Ruby
  • PowerShell
  • Custom Runtime thông qua Runtime API

Lambda cũng hỗ trợ các framework phổ biến như Serverless Framework, AWS SAM, và các công cụ khác để giúp phát triển, kiểm thử và triển khai Lambda functions dễ dàng hơn.

Cấu hình Lambda Function

Memory và CPU

  • Memory: Từ 128MB đến 10GB (cập nhật tới 2023)
  • CPU: Được cấp phát tỷ lệ thuận với memory
    • 1,769 vCPU cho mỗi 1GB RAM

Timeout

  • Thời gian thực thi tối đa: 15 phút (900 giây)
  • Mặc định: 3 giây

Concurrency

  • Reserved Concurrency: Số lượng instances được đảm bảo cho function
  • Provisioned Concurrency: Số lượng instances được khởi tạo sẵn để tránh cold start
  • Account Concurrency Limit: Mặc định là 1,000 (có thể yêu cầu tăng)

Environment Variables

  • Lưu trữ cấu hình và secret
  • Được mã hóa khi lưu trữ
  • Có thể sử dụng AWS KMS để mã hóa

Triggering Lambda Functions

Lambda có thể được kích hoạt bởi nhiều nguồn sự kiện khác nhau:

AWS Services

  • S3: Khi có file mới được tải lên
  • DynamoDB/Kinesis: Khi có bản ghi mới
  • SQS: Xử lý tin nhắn từ hàng đợi
  • API Gateway: Tạo API endpoints
  • EventBridge (CloudWatch Events): Theo lịch hoặc sự kiện
  • SNS: Phản ứng với thông báo
  • Cognito: Trong quá trình xác thực
  • Và nhiều dịch vụ AWS khác

Custom Applications

  • Gọi trực tiếp thông qua AWS SDK
  • Thông qua HTTP endpoints với API Gateway
  • Thông qua các SDK tùy chỉnh

Lambda Layers

Lambda Layers là một tính năng cho phép chia sẻ mã, thư viện và runtime giữa các Lambda functions.

Lợi ích

  • Tái sử dụng mã: Chia sẻ dependencies giữa nhiều functions
  • Quản lý mã hiệu quả: Các thư viện phổ biến được quản lý tập trung
  • Giảm kích thước package: Deployment package nhỏ hơn, tải nhanh hơn

Cấu trúc

Layers được tổ chức theo đường dẫn cụ thể cho từng ngôn ngữ, ví dụ:

  • Node.js: /opt/nodejs/node_modules
  • Python: /opt/python/lib/python3.x/site-packages
  • Java: /opt/java/lib

Lambda và VPC

Lambda functions có thể được cấu hình để truy cập vào VPC (Virtual Private Cloud).

Khi nào cần VPC integration

  • Truy cập tài nguyên trong VPC (RDS, ElastiCache…)
  • Kết nối với các dịch vụ nội bộ
  • Yêu cầu về bảo mật và cô lập mạng

Cách hoạt động

  1. Lambda tạo Elastic Network Interface (ENI) trong VPC của bạn
  2. Liên kết ENI với môi trường thực thi Lambda
  3. Function có thể truy cập vào tài nguyên trong VPC

Lưu ý: VPC-connected Lambda có thể làm tăng thời gian cold start.

Kiểm soát phiên bản và Alias

Versions

  • $LATEST: Phiên bản mới nhất và có thể chỉnh sửa
  • Numbered versions: Phiên bản bất biến được publish từ $LATEST

Aliases

  • Pointers đến phiên bản cụ thể
  • Cho phép A/B testing và blue/green deployment
  • Ví dụ: dev, staging, prod

Traffic shifting

Lambda hỗ trợ weighted aliases để chuyển lưu lượng dần dần giữa các phiên bản:

prod: 80% version 1, 20% version 2

Lambda@Edge và Lambda Function URLs

Lambda@Edge

  • Chạy Lambda functions tại các edge locations của CloudFront
  • Xử lý gần người dùng hơn, giảm độ trễ
  • Phù hợp cho xử lý yêu cầu/phản hồi HTTP, chuyển đổi nội dung

Lambda Function URLs

  • HTTP(S) endpoint dành riêng cho Lambda function
  • Không cần API Gateway
  • Hỗ trợ xác thực AWS IAM hoặc không xác thực

Ứng dụng của AWS Lambda

Xử lý dữ liệu

  • Xử lý hình ảnh/video: Thay đổi kích thước, tối ưu hóa, biến đổi
  • ETL data processing: Chuyển đổi dữ liệu giữa các nguồn
  • Real-time file processing: Xử lý file khi được tải lên S3

Web Applications

  • Serverless APIs: Kết hợp với API Gateway
  • Webhooks: Xử lý sự kiện từ các dịch vụ bên ngoài
  • Authentication: Tùy chỉnh logic xác thực

Tự động hóa

  • Scheduled tasks: Chạy theo lịch thay thế cron jobs
  • ChatOps: Xử lý lệnh từ chat platforms
  • CI/CD tasks: Tự động hóa các bước trong quy trình phát triển

IoT

  • Device data ingestion: Xử lý dữ liệu từ thiết bị IoT
  • Real-time analytics: Phân tích dữ liệu từ cảm biến
  • Command and control: Gửi lệnh đến thiết bị

Giám sát và Debug

CloudWatch Logs

  • Logs tự động được gửi đến CloudWatch
  • Cung cấp cái nhìn toàn diện về việc thực thi
  • Có thể tìm kiếm và phân tích logs

CloudWatch Metrics

Các metrics chính:

  • Invocations: Số lần gọi function
  • Duration: Thời gian thực thi
  • Errors: Số lỗi
  • Throttles: Số lần bị giới hạn
  • ConcurrentExecutions: Số thực thi đồng thời
  • Iterator age: Cho Stream-based invocations

X-Ray Integration

  • Theo dõi chi tiết request
  • Phân tích hiệu suất
  • Xác định nút thắt cổ chai

Bảo mật

IAM Roles

  • Mỗi Lambda function được gán một IAM role
  • Role quyết định quyền truy cập đến các dịch vụ AWS khác
  • Nên tuân theo nguyên tắc quyền tối thiểu

Environment Variables và KMS

  • Các biến môi trường có thể được mã hóa bằng KMS
  • Secrets nên được lưu trữ trong AWS Secrets Manager hoặc Parameter Store

Resource-based Policies

  • Kiểm soát ai có thể gọi Lambda function
  • Hữu ích cho cross-account access

Chi phí và tối ưu hóa

Mô hình tính phí

AWS Lambda tính phí dựa trên:

  1. Số lượng request: $0.20 per 1 million requests
  2. Thời gian thực thi: $0.0000166667 per GB-second
    • Ví dụ: Function 512MB chạy trong 1 giây = 0.5GB * 1s = 0.5GB-second

Free tier

AWS cung cấp free tier hàng tháng:

  • 1 triệu requests miễn phí
  • 400,000 GB-seconds compute time

Tối ưu chi phí

  • Tối ưu memory: Chọn cấu hình memory phù hợp
  • Tối ưu mã: Giảm thời gian thực thi
  • Tránh dependencies không cần thiết: Package size nhỏ hơn, cold start nhanh hơn
  • Sử dụng Provisioned Concurrency: Hiệu quả cho workloads có thể dự đoán

Thực hành tốt nhất

Performance

  • Keep functions warm: Sử dụng scheduled events để tránh cold starts
  • Tái sử dụng connections: Khởi tạo clients bên ngoài handler function
  • Tận dụng /tmp directory: Lưu trữ tạm thời (tối đa 512MB)
  • Lazy loading: Chỉ tải dependencies khi cần thiết

Development

  • Local testing: Sử dụng AWS SAM CLI hoặc LocalStack
  • Unit testing: Mock AWS services
  • Deploy incrementally: Sử dụng versions và aliases

Monitoring

  • Set alarms: Cảnh báo cho errors và throttling
  • Log effectively: Cân bằng giữa thông tin và hiệu suất
  • Use structured logging: Dễ phân tích và tìm kiếm

Ví dụ thực tế

Ví dụ Node.js: Xử lý hình ảnh khi upload lên S3

const AWS = require('aws-sdk');
const sharp = require('sharp');
const s3 = new AWS.S3();

exports.handler = async (event) => {
    // Lấy thông tin bucket và key từ event
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    
    // Chỉ xử lý image files
    if (!key.match(/\.(jpg|jpeg|png|gif)$/i)) {
        return;
    }
    
    try {
        // Tải hình ảnh từ S3
        const image = await s3.getObject({ Bucket: bucket, Key: key }).promise();
        
        // Tạo thumbnail sử dụng sharp
        const thumbnail = await sharp(image.Body)
            .resize(200, 200, { fit: 'inside' })
            .toBuffer();
        
        // Tạo tên file thumbnail
        const thumbnailKey = `thumbnails/${key.split('/').pop()}`;
        
        // Upload thumbnail lên S3
        await s3.putObject({
            Bucket: bucket,
            Key: thumbnailKey,
            Body: thumbnail,
            ContentType: 'image/jpeg'
        }).promise();
        
        return {
            statusCode: 200,
            body: JSON.stringify({
                message: 'Thumbnail đã được tạo thành công',
                thumbnail: thumbnailKey
            })
        };
    } catch (error) {
        console.error('Lỗi:', error);
        return {
            statusCode: 500,
            body: JSON.stringify({
                message: 'Đã xảy ra lỗi khi xử lý hình ảnh',
                error: error.message
            })
        };
    }
};

Ví dụ Python: API endpoint với event từ API Gateway

import json
import boto3
import os
from datetime import datetime

# Khởi tạo DynamoDB client
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ['USERS_TABLE'])

def lambda_handler(event, context):
    # Lấy HTTP method và path từ event
    http_method = event['httpMethod']
    path = event['path']
    
    # Xử lý route GET /users
    if http_method == 'GET' and path == '/users':
        try:
            # Lấy danh sách users từ DynamoDB
            response = table.scan()
            users = response['Items']
            
            return {
                'statusCode': 200,
                'headers': {
                    'Content-Type': 'application/json'
                },
                'body': json.dumps(users)
            }
        except Exception as e:
            return {
                'statusCode': 500,
                'body': json.dumps({
                    'message': 'Lỗi khi lấy dữ liệu users',
                    'error': str(e)
                })
            }
    
    # Xử lý route POST /users
    elif http_method == 'POST' and path == '/users':
        try:
            # Parse request body
            body = json.loads(event['body'])
            
            # Validate input
            if 'username' not in body or 'email' not in body:
                return {
                    'statusCode': 400,
                    'body': json.dumps({
                        'message': 'Thiếu thông tin username hoặc email'
                    })
                }
            
            # Tạo item mới
            timestamp = datetime.utcnow().isoformat()
            item = {
                'userId': body.get('username'),
                'email': body.get('email'),
                'createdAt': timestamp,
                'updatedAt': timestamp
            }
            
            # Lưu vào DynamoDB
            table.put_item(Item=item)
            
            return {
                'statusCode': 201,
                'headers': {
                    'Content-Type': 'application/json'
                },
                'body': json.dumps(item)
            }
        except Exception as e:
            return {
                'statusCode': 500,
                'body': json.dumps({
                    'message': 'Lỗi khi tạo user mới',
                    'error': str(e)
                })
            }
    
    # Xử lý route không được hỗ trợ
    else:
        return {
            'statusCode': 404,
            'body': json.dumps({
                'message': 'Route không được hỗ trợ'
            })
        }

AWS Lambda vs. Các giải pháp khác

So với EC2

LambdaEC2
Không cần quản lý máy chủKiểm soát hoàn toàn máy chủ
Tự động mở rộng theo requestMở rộng thủ công hoặc qua Auto Scaling
Giới hạn về thời gian thực thi (15 phút)Không giới hạn thời gian chạy
Trả phí theo sử dụng thực tếTrả phí theo thời gian instance chạy
Phù hợp cho workload không liên tụcPhù hợp cho ứng dụng chạy liên tục

So với Container (ECS/EKS)

LambdaContainers
Không cần quản lý containerQuản lý container và orchestration
Khởi động nhanh hơnKhởi động chậm hơn
Tự động mở rộng theo số lượng requestMở rộng theo các metrics định nghĩa trước
Giới hạn về tài nguyên và thời gianLinh hoạt hơn về tài nguyên
Phù hợp cho microservices đơn giảnPhù hợp cho microservices phức tạp

Kết luận

AWS Lambda là một dịch vụ serverless mạnh mẽ, cho phép nhà phát triển tập trung vào code thay vì quản lý cơ sở hạ tầng. Với khả năng tự động mở rộng, mô hình tính phí theo sử dụng thực tế, và tích hợp sâu với hệ sinh thái AWS, Lambda đã trở thành công cụ quan trọng trong kiến trúc hiện đại, đặc biệt là trong các ứng dụng microservices và event-driven.

Tuy nhiên, Lambda cũng có những hạn chế và không phải là giải pháp phù hợp cho mọi trường hợp sử dụng. Việc hiểu rõ ưu điểm, nhược điểm và các thực hành tốt nhất sẽ giúp bạn sử dụng Lambda hiệu quả trong các dự án của mình.

11 Views

Leave a Reply

Your email address will not be published. Required fields are marked *