如何在API网关中添加分页/计数器来控制Lambda Python的输出

问题描述 投票:0回答:1

我有一个 lambda 函数,它通过 API Gateway 作为 Rest API 端点公开。 lambda 函数通过 python 从 S3 读取多个文件,并根据 python 代码中的某些条件通过 APIGW 发送响应。在输出响应中,我将所有响应附加到一个通用 JSON 中。

现在,由于组合 JSON 的大小最终可能会非常大,这可能会导致性能问题,我希望在 API 网关上有一些分页选项,例如偏移/光标,以便通过公开的 REST API 任何人都可以控制 lambda 函数他们希望在一次调用中遍历 S3 存储桶中的文件数量,并且下次 API 可以从第一个 API 结束的下一个文件恢复。

请告诉我实现这一期望的有效方法。

python-3.x amazon-web-services amazon-s3 aws-lambda aws-api-gateway
1个回答
0
投票

要在通过 API Gateway 作为 REST API 公开的 AWS Lambda 函数中实现高效分页,请遵循以下细化步骤以获得最佳性能和可维护性:

解决方案概要:

  1. 定义分页查询参数: • 参数:引入API Gateway 中的limit 和cursor 查询参数。 • limit 指定单次调用中要处理的最大文件数,它控制每个响应的大小。 • 光标充当书签,指示从何处开始从S3 读取文件以供后续调用。 • API 调用示例:https://api.example.com/your-lambda?limit=10&cursor=2023-11-01T12:00:00
  2. 用光标维护状态: • 游标用于存储S3 中最后处理的文件的位置。这使得 API 能够从中断处恢复,这对于大型数据集特别有用。 • 游标可以是每个文件中的时间戳、文件名或其他唯一可识别的元数据,允许 Lambda 跟踪并从每个请求中最后处理的文件开始。
  3. 在 Lambda 中实现分页逻辑: • 您的 Lambda 应该: • 从API 请求中读取限制和光标。 • 从指定光标开始从S3 获取文件,并仅处理最多限制数量的文件。 • 返回响应中的下一个光标,允许客户端通过发出另一个请求来检索下一批文件。
  4. 使用光标返回分页响应: • 每个回复应包括: • 已处理的数据:在此调用中读取和处理的文件。 • 下一个光标:指示下一个请求的起点的字段。 • 有更多:可选,一个布尔标志,指示是否有更多文件要处理。 • 响应示例: { "data": [...], // 本批次处理的数据 "next_cursor": "2023-11-01T12:05:00", // 下一批的光标 "has_more": true // 指示是否有更多数据可用 }

示例 Lambda 代码:

此代码提供了一个清晰的结构,用于处理带有限制和光标的分页。

import boto3
import json

s3_client = boto3.client('s3')
BUCKET_NAME = 'your-s3-bucket-name'

def list_files_from_s3(cursor, limit):
    # List files from S3 starting from a cursor, limited by `limit`
    s3_response = s3_client.list_objects_v2(
        Bucket=BUCKET_NAME,
        StartAfter=cursor,
        MaxKeys=limit
    )
    files = s3_response.get('Contents', [])
    next_cursor = files[-1]['Key'] if len(files) == limit else None
    return files, next_cursor

def lambda_handler(event, context):
    # Get query parameters
    limit = int(event['queryStringParameters'].get('limit', 10))
    cursor = event['queryStringParameters'].get('cursor', '')

    # Fetch files from S3 with offset and limit
    files, next_cursor = list_files_from_s3(cursor, limit)
    processed_data = process_files(files)  # Replace with your actual processing logic

    response_body = {
        "data": processed_data,
        "next_cursor": next_cursor,
        "has_more": bool(next_cursor)  # Indicates if more files are available
    }

    return {
        "statusCode": 200,
        "body": json.dumps(response_body)
    }

def process_files(files):
    # Implement the actual logic for processing each file
    processed_results = []
    for file in files:
        # Add your file processing code here
        processed_results.append({"file_key": file['Key'], "data": "processed_data"})
    return processed_results

扩展和效率的最佳实践:

  1. 利用异步处理:

• 使用AWS Step Functions 将复杂、长时间运行的任务拆分为更小的步骤。这减少了 Lambda 执行时间并支持更复杂的状态管理,这在处理数千个文件时特别有用。

  1. 优化S3列表:

• 基于前缀的列表或索引可以帮助减少检索特定文件所需的时间。例如,如果您知道要搜索的大致范围,则按日期前缀(例如年/月/日/文件名)组织文件可以加快列表速度。

  1. 错误处理和重试逻辑:

• 确保错误处理以重试失败的请求,并防止由于 Lambda 超时或 S3 访问问题导致数据丢失。

  1. 响应大小限制:

• 将每个分页响应保持在 6MB 以下,以避免 Lambda 和 API 网关负载限制。如果数据量很大,可以考虑使用S3来存储响应JSON并仅返回预签名的URL以供客户端访问。

  1. 缓存重复请求的结果: • 对于多个客户端经常访问的大型数据集,使用 Amazon CloudFront 或 API Gateway 缓存进行缓存可以缩短响应时间并减少 Lambda 调用。

用法示例:

以下是您的客户如何使用此分页 API: 1.第一个请求:https://api.example.com/your-lambda?limit=10 • 回应:

{
    "data": [...],
    "next_cursor": "2023-11-01T12:00:00",
    "has_more": true
}
  1. 后续请求:https://api.example.com/your-lambda?limit=10&cursor=2023-11-01T12:00:00 • 此请求将继续从上次处理的文件中获取。

此设置为客户端提供了一种干净、受控的方式来有效地管理分页,同时保持 API 响应的可管理性,从而能够顺利处理大型数据集。

© www.soinside.com 2019 - 2024. All rights reserved.