【问题标题】:Move files from one s3 bucket to another in AWS using AWS lambda使用 AWS lambda 将文件从一个 s3 存储桶移动到 AWS 中的另一个存储桶
【发布时间】:2020-09-15 10:06:45
【问题描述】:

我正在尝试使用 python boto3 AWS lambda 函数将超过一小时的文件从一个 s3 存储桶移动到另一个 s3 存储桶,但情况如下:

  1. 两个存储桶可以在同一个帐户和不同的地区。
  2. 两个存储桶可以位于不同的帐户和不同的区域。
  3. 两个存储桶可以位于不同的帐户和同一区域。

我在使用@John Rotenstein 提到的 python 代码移动文件方面得到了一些帮助

import boto3
from datetime import datetime, timedelta

SOURCE_BUCKET = 'bucket-a'
DESTINATION_BUCKET = 'bucket-b'

s3_client = boto3.client('s3')

# Create a reusable Paginator
paginator = s3_client.get_paginator('list_objects_v2')

# Create a PageIterator from the Paginator
page_iterator = paginator.paginate(Bucket=SOURCE_BUCKET)

# Loop through each object, looking for ones older than a given time period
for page in page_iterator:
    for object in page['Contents']:
        if object['LastModified'] < datetime.now().astimezone() - timedelta(hours=1):   # <-- Change time period here
            print(f"Moving {object['Key']}")

            # Copy object
            s3_client.copy_object(
                Bucket=DESTINATION_BUCKET,
                Key=object['Key'],
                CopySource={'Bucket':SOURCE_BUCKET, 'Key':object['Key']}
            )

            # Delete original object
            s3_client.delete_object(Bucket=SOURCE_BUCKET, Key=object['Key'])

如何修改以满足需求

【问题讨论】:

    标签: python amazon-web-services amazon-s3 boto3


    【解决方案1】:

    另一种方法是使用Amazon S3 Replication,它可以复制存储桶内容:

    • 在同一区域内,或在区域之间
    • 在同一个 AWS 账户内,或在不同账户之间

    当组织需要在不同区域复制其数据的另一个副本时,或仅出于备份目的时,经常使用复制。例如,可以将关键公司信息复制到普通用户无法访问的另一个 AWS 账户。这样,如果某些数据被删除,其他地方就会有另一个副本。

    复制需要在源存储桶和目标存储桶上都激活版本控制。如果您需要加密,请使用标准Amazon S3 encryption options。数据在传输过程中也会被加密。

    您配置源存储桶和目标存储桶,然后通过提供前缀或标签来指定要复制的对象。仅在激活复制后才会复制对象。现有对象将不会被复制。有意复制删除以避免恶意操作。见:What Does Amazon S3 Replicate?

    S3 复制没有“额外”成本,但您仍需支付在区域之间移动对象时的任何数据传输费用,以及 API 请求(这些费用很少),当然还有存储费用。

    【讨论】:

    • 听起来很完美。
    • 我可以将复制时间从 15 分钟增加到 1 小时吗?
    • “复制时间”是自动的。在需要对复制时间进行额外控制的情况下,可以使用复制时间控制功能。见:S3 Replication Update: Replication SLA, Metrics, and Events | AWS News Blog
    • 我找不到是否可以控制复制频率。我也提出了支持请求,他们说这是不可能的。你能帮帮我吗
    • 复制是自动且连续的。不是频率,更像是“在排队,需要几分钟”。
    【解决方案2】:

    区域间移动

    这不是问题。您只需在存储桶之间复制对象,Amazon S3 就会解决这个问题。

    在帐户之间移动

    这有点困难,因为代码将使用一组凭据,必须具有对源存储桶的 ListBucketGetObject 访问权限,以及对目标存储桶的 PutObject 权限。

    此外,如果从源帐户使用凭据,则必须使用ACL='bucket-owner-full-control' 执行复制,否则目标帐户将无权访问该对象。当使用来自目标帐户的凭据执行复制时,这不是必需的。

    假设 Lambda 代码在 Account-A 中运行,并将一个对象复制到 Account-B。 IAM 角色 (Role-A) 已分配给 Lambda 函数。让Role-A 访问Account-A 中的存储桶非常容易。但是,Lambda 函数将需要 Account-B 中的存储桶 (Bucket-B) 中的 PutObject 的权限。因此,您需要将存储桶策略添加到 Bucket-B,以允许 Role-APutObject 进入存储桶。这样,Role-A 就拥有从 Bucket-A 读取和写入 Bucket-B 的权限。

    所以,把它们放在一起:

    • 为 Lambda 函数创建一个 IAM 角色 (Role-A)
    • 根据需要为角色授予相同帐户中存储桶的读/写访问权限
    • 对于其他账户中的存储桶,添加一个存储桶策略,授予 IAM 角色必要的访问权限 (Role-A)
    • copy_object() 命令中,包含ACL='bucket-owner-full-control'(这是唯一需要更改的编码)
    • 不用担心跨区域做任何事情,它应该会自动工作

    【讨论】:

    • 我也在查看stackoverflow.com/questions/43577746/aws-lambda-task-timed-out/… 的帖子,您提到超时值最多可以为 15 分钟。但是在我的情况下,存储桶对象超过 5 GB,那么这里的 AWS fargate 更好的解决方案是什么?
    • 嘿@John Rotenstein 你能告诉我这个查询吗?
    • 如果复制操作耗时超过 15 分钟,则 Lambda 不合适。区域之间的复制也会使操作花费更长的时间。要推荐一种方法,我需要了解更多信息:文件多久到达一次(或每小时或每天多少次)?您需要快速复制它们,还是可以每天复制一次?程序如何确定将文件复制到哪里? (如果它是基于目录的,那么 S3 Replication 可以自动为您完成。)
    • 嘿 @John Rotenstein 所以 s3 存储桶将包含包含文件的文件夹,这些文件夹的内容应复制到其他区域的存储桶中的文件夹。所以你有什么建议?复制适合吗?这里有什么优点和缺点。文件每分钟都会出现,假设 1 分钟 1 个文件,或者每小时可以有 1000 个文件,每个文件将是 300 MB,在这种情况下最好的解决方案是什么。我还可以使用 s3 复制删除已复制到其他存储桶的内容吗?需要加密,版本和复制每 15 分钟会产生费用吗?
    • 不知道!您必须在该区域添加一些调试语句才能查看它在做什么。当page not 包含名为Contents 的元素时,可能会发生这种情况。这可能会在最后发生(这就是事情被移动的原因),但此时它仍然不应该失败。您可以将if 'Contents' in page then: 放在该行之前以避免这种情况。
    猜你喜欢
    • 2020-05-29
    • 1970-01-01
    • 2017-07-21
    • 2018-11-22
    • 2023-02-01
    • 2020-12-27
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多