如何解决使用python将S3 gzip源对象的解压缩流传输到S3目标对象?
给定S3中一个大的gzip
对象,python3 / boto3中一种有效的内存有效(例如流式传输)方法来解压缩数据并将结果存储回另一个S3对象中?
以前有一个similar question。但是,所有答案都使用一种方法,其中首先将gzip文件的内容读到内存中(例如ByteIO
)。这些解决方案不适用于太大而无法放入主内存的对象。
对于大型S3对象,需要读取内容,“即时”解压缩,然后以某种分块方式将其写入另一个S3对象。
预先感谢您的考虑和答复。
解决方法
您可以将流方法与 boto / s3 一起使用,但必须定义自己的类似文件的对象AFAIK。
幸运的是,有smart_open可以为您解决这个问题;它还支持 GCS,Azure,HDFS,SFTP 等。
这是使用大量sample销售数据的示例:
import boto3
from smart_open import open
session = boto3.Session() # you need to set auth credentials here if you don't have them set in your environment
chunk_size = 1024 * 1024 # 1 MB
f_in = open("s3://mybucket/2m_sales_records.csv.gz",transport_params=dict(session=session),encoding="utf-8")
f_out = open("s3://mybucket/2m_sales_records.csv","w",transport_params=dict(session=session))
byte_count = 0
while True:
data = f_in.read(chunk_size)
if not data:
break
f_out.write(data)
byte_count += len(data)
print(f"wrote {byte_count} bytes so far")
f_in.close()
f_out.close()
该示例文件有 200万行,已压缩 75 MB ,未压缩 238 MB 。
我将压缩文件上传到mybucket
,然后运行下载文件的代码,提取了内存中的内容,然后将未压缩的数据上传回S3。
在我的计算机上,该过程耗时约 78秒(在很大程度上取决于Internet连接速度),并且从未使用过超过 95 MB 的内存;我认为您可以通过覆盖 smart_open 中S3分段上传的部分大小来降低内存需求。
DEFAULT_MIN_PART_SIZE = 50 * 1024**2
"""Default minimum part size for S3 multipart uploads"""
MIN_MIN_PART_SIZE = 5 * 1024 ** 2
"""The absolute minimum permitted by Amazon."""
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。