You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda返回长JSON字符串时触发超时问题排查

AWS Lambda返回JSON字符串超时问题排查

问题背景

我编写了一个AWS Lambda函数作为应用视图,用于读取S3桶中的Parquet数据并返回JSON结果。函数代码如下:

import json
import time
t = time.time()
print('This ')

import os
import urllib.parse
import boto3
import pandas as pd
import awswrangler as wr

print('Imports complete: ', time.time() - t)


s3 = boto3.client('s3')

def lambda_handler(event, context):
    bucket = os.environ['S3_BUCKET']
    try:
        print('wrangling df')
        df = wr.s3.read_parquet(bucket, dataset=True)
        print('df loaded: ',time.time() - t)
        response = df.to_json()
        print('response type: ', type(response))
        print('df to json: ',time.time() - t)
        return response
    except Exception as e:
        print('exception caught: ',time.time() - t)
        print(e)
        print('Error getting object from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(bucket))
        raise e

函数使用us-west-2区域的托管Python层:arn:aws:lambda:eu-west-2:336392948345:layer:AWSSDKPandas-Python312:13,配置60秒超时测试后返回错误:

{"errorType": "Sandbox.Timedout", "errorMessage": "RequestId: 24b0f94f-a78e-40e4-9573-0e49ac3eeef3 Error: Task timed out after 60.00 seconds"}

日志显示所有处理步骤(包括DataFrame转JSON)均在10秒内完成,但返回JSON字符串时触发超时;若将return response替换为return 'some text',函数可立即返回。请问为何几KB的字符串会使返回时间增加50秒以上?


问题原因与解决办法

核心原因

Lambda函数返回值的序列化与传输过程未被日志捕获,这一步在处理结构复杂的JSON字符串时会产生额外开销:

  • Pandas默认生成的JSON字符串可能包含大量嵌套结构、重复字段,Lambda运行时在将返回值序列化并传输到调用端时,需要对这些内容进行校验、编码,耗时远超预期。
  • 即使字符串体积仅几KB,复杂的层级结构会让Lambda的序列化逻辑耗时剧增,最终触发超时。

可行解决方案

  • 优化JSON输出结构:使用Pandasto_json()的orient参数简化JSON格式,比如orient='records'生成扁平化的数组结构,减少序列化复杂度:
    response = df.to_json(orient='records')
    
  • 压缩返回内容:将JSON字符串压缩后返回,降低传输体积和序列化开销:
    import gzip
    import base64
    
    json_str = df.to_json(orient='records')
    compressed_data = gzip.compress(json_str.encode('utf-8'))
    return base64.b64encode(compressed_data).decode('utf-8')
    
  • 改用S3中转:将生成的JSON文件写入S3,返回S3预签名URL让客户端自行下载,彻底规避Lambda返回值的限制:
    # 写入JSON到S3
    s3_key = f"temp/{context.aws_request_id}.json"
    wr.s3.to_json(df, f"s3://{bucket}/{s3_key}")
    # 生成预签名URL
    url = s3.generate_presigned_url('get_object', Params={'Bucket': bucket, 'Key': s3_key}, ExpiresIn=300)
    return {'presigned_url': url}
    
  • 提升函数资源配置:Lambda的内存配置直接关联CPU和网络带宽,适当提高内存配额可加速序列化和传输过程。

内容的提问来源于stack exchange,提问作者Jamie Marshall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:47:31