如何用Python/PySpark上传超5GB的Pandas DataFrame至S3?
解决5GB以上DataFrame上传S3的EntityTooLarge错误
错误原因
你碰到的EntityTooLarge错误,是因为S3的UploadPart操作单个分片最大限制为5GB。当前代码把整个大文件一次性加载到内存后写入,导致单个分片大小超限;同时用Pandas读取超大文件到单节点内存,还容易触发内存溢出。
推荐方案:用PySpark处理(适配Glue环境)
Glue Job基于PySpark,应该利用其分布式能力,避免单节点加载大文件。Spark会自动处理S3分片上传,原生支持KMS加密配置,效率更高。
代码示例
# 直接使用Glue自带的SparkSession df = glueContext.spark_session.read.csv( "s3://your-input-bucket/csv-files-path/*.csv", sep=",", header=True, inferSchema=False, nullValue="" ) # 写入S3,配置KMS加密 # 若需要单个文件,添加repartition(1)(超大文件不建议,可能引发单节点内存压力) df.write.mode("overwrite") \ .option("header", "true") \ .option("sep", ",") \ .option("serverSideEncryption", "aws:kms") \ .option("sseKmsKeyId", kms_key) \ .csv("s3://your-output-bucket/target-path/")
备选方案:优化Pandas+smart_open分片上传
如果必须用Pandas处理,需要分块读取文件,并调整分片大小确保不超过S3的5GB限制,同时避免一次性加载全量数据到内存。
代码示例
import pandas as pd from smart_open import open chunk_size = 100000 # 根据内存情况调整块大小 client_kwargs = { 'S3.Client.create_multipart_upload': {'ServerSideEncryption': 'aws:kms', 'SSEKMSKeyId': kms_key}, 'S3.Client.put_object': {'ServerSideEncryption': 'aws:kms', 'SSEKMSKeyId': kms_key} } # 设置分片大小为4GB(小于S3的5GB上限) with open(url, 'w', transport_params={ 'client_kwargs': client_kwargs, 'client': s3_client, 'multipart_upload_kwargs': {'part_size': 4 * 1024**3} }) as f: header_written = False # 分块读取并写入 for chunk in pd.read_csv( obj["Body"], delimiter=",", keep_default_na=False, low_memory=False, dtype=str, chunksize=chunk_size ): chunk.to_csv(f, sep=",", index=False, header=not header_written) header_written = True
关键注意事项
- 分块读取避免内存溢出
- 分片大小必须小于5GB,建议设为4GB留有余量
内容的提问来源于stack exchange,提问作者Pal1989
相关产品推荐
相关产品推荐

