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

AWS Lambda从S3下载文件至/tmp目录时出现数据丢失(文件大小异常)的问题求助

解决AWS Lambda下载S3大文件时大小异常的问题

看起来你遇到的问题是Lambda下载S3文件后大小严重缩水,从230MB变成了330KB,这大概率是下载过程被中断或者代码细节没处理到位。我帮你梳理几个常见原因和对应的解决方案:

一、先排查最容易忽略的问题

1. Lambda超时时间太短

默认情况下Lambda的超时时间只有3秒,下载230MB的文件完全不够,中途就会被强制终止,导致文件只下载了一部分。

  • 解决方法:在Lambda控制台的函数配置里,把超时时间调整到60秒(甚至更长,根据你的网络情况)。

2. 确认/tmp目录空间(可能性较低,但可以验证)

Lambda现在默认给/tmp分配512MB空间,230MB是足够的,但可以在代码里加一行检查,排除空间不足的可能:

import shutil
disk_usage = shutil.disk_usage('/tmp')
print(f"/tmp可用空间: {disk_usage.free / (1024*1024):.2f} MB")

如果可用空间确实不足,可以在Lambda配置里调整/tmp的大小(最大支持10GB)。

3. 使用download_fileobj时未用二进制模式

如果你尝试过download_fileobj,一定要确保用wb模式打开文件——文本模式会损坏二进制文件(比如wav),直接导致大小异常:

with open(new_file_name, 'wb') as f:
    s3.download_fileobj(bucket_name, fileKey, f)

download_file方法内部已经处理了二进制模式,所以这个问题只针对download_fileobj。

二、添加调试和校验的修正代码

我给你修改了代码,加上了S3元数据校验、错误捕获和重试逻辑,方便你定位问题:

import os
import boto3
import shutil

def data_processor(event, context):
    print("EVENT:: ", event)
    bucket_name = 'asr-collection'
    fileKey = 'cc_continuous/testing/1645136763813.wav'
    path = '/tmp'
    output_path = os.path.join(path, 'mydir')
    
    # 检查/tmp可用空间
    disk_usage = shutil.disk_usage('/tmp')
    print(f"/tmp可用空间: {disk_usage.free / (1024*1024):.2f} MB")
    
    if not os.path.exists(output_path):
        os.makedirs(output_path)
    
    s3 = boto3.client("s3")
    new_file_name = os.path.join(output_path, os.path.basename(fileKey))
    
    # 先获取S3文件的真实大小,做对比基准
    try:
        obj_meta = s3.head_object(Bucket=bucket_name, Key=fileKey)
        s3_file_size = obj_meta['ContentLength']
        print(f"S3文件实际大小: {s3_file_size / (1024*1024):.2f} MB")
    except Exception as e:
        print(f"获取S3元数据失败: {str(e)}")
        return None
    
    try:
        # 下载文件
        s3.download_file(
            Bucket=bucket_name,
            Key=fileKey,
            Filename=new_file_name
        )
        
        local_size = os.path.getsize(new_file_name)
        print(f"本地文件大小: {local_size / (1024*1024):.2f} MB")
        
        # 校验大小,不匹配则重试一次
        if local_size != s3_file_size:
            print("⚠️ 文件大小不匹配,尝试重新下载...")
            os.remove(new_file_name)
            s3.download_file(bucket_name, fileKey, new_file_name)
            local_size_retry = os.path.getsize(new_file_name)
            print(f"重试后大小: {local_size_retry / (1024*1024):.2f} MB")
            if local_size_retry == s3_file_size:
                print("✅ 重试成功,文件下载完整")
            else:
                print("❌ 重试后仍不匹配,需要进一步排查")
        else:
            print("✅ 文件下载完整")
            
    except Exception as e:
        print(f"下载过程出错: {str(e)}")
        return None
    
    return None

三、其他可能的排查方向

  1. VPC网络限制:如果你的Lambda部署在VPC里,需要确保VPC能访问S3——要么配置NAT网关,要么创建S3的VPC端点,否则下载会因为网络不通而中断。
  2. boto3版本过旧:旧版本的boto3可能存在大文件下载的bug,你可以在代码里打印版本号print(boto3.__version__),如果版本低于1.20,建议升级到最新稳定版。
  3. S3版本控制:检查S3桶是否开启了版本控制,确认你下载的是最新版本的文件,而不是旧的小文件。
  4. 权限问题:虽然能下载部分文件,但如果权限有部分限制(比如只允许下载部分内容,这种情况比较少见),可以检查Lambda执行角色的权限,确保有s3:GetObject的完整权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:58:13