为了账号安全,请及时绑定邮箱和手机立即绑定

使用 python 将 S3 gzip 源对象流式解压缩到 S3 目标对象?

使用 python 将 S3 gzip 源对象流式解压缩到 S3 目标对象?

弑天下 2023-12-09 15:59:49
给定 S3 中的一个大gzip对象,python3/boto3 中的内存高效(例如流式传输)方法是什么来解压缩数据并将结果存储回另一个 S3 对象?之前也有人问过类似的问题。然而,所有答案都使用一种方法,其中首先将 gzip 文件的内容读入内存(例如ByteIO)。这些解决方案对于太大而无法放入主内存的对象来说是不可行的。对于大型 S3 对象,需要读取内容,“即时”解压缩,然后以某种分块方式写入不同的 S3 对象。预先感谢您的考虑和回复。
查看完整描述

1 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

您可以将流方法与boto / s3一起使用,但您必须定义自己的类文件对象 AFAIK。
幸运的是,有smart_open可以帮你处理这个问题;它还支持GCS、Azure、HDFS、SFTP等。以下是使用大量销售数据样本
的 示例:

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 秒(高度依赖于互联网连接速度),并且从未使用超过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."""


查看完整回答
反对 回复 2023-12-09
  • 1 回答
  • 0 关注
  • 48 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信