如何删除或清除 S3 上的旧文件?

Posted

技术标签:

【中文标题】如何删除或清除 S3 上的旧文件?【英文标题】:How to delete or purge old files on S3? 【发布时间】:2012-02-17 13:34:29 【问题描述】:

是否存在删除任何超过 x 天的文件的现有解决方案?

【问题讨论】:

现在我将使用这个解决方案:s3cmd ls s3://mybucket/mypath/ |ruby -rdate -ne 'date, time, size, uri = $_.split; days = (Time.now - Date.parse(date).to_time) / 60/60/24; puts uri if days > 2' |xargs s3cmd del 【参考方案1】:

亚马逊最近推出了object expiration。

Amazon S3 宣布对象过期

Amazon S3 宣布了一个新的 功能,对象过期,允许您安排删除 您的对象在预定义的时间段后。使用对象过期 安排定期清除对象消除了对您的需要 识别要删除的对象并向亚马逊提交删除请求 S3.

您可以为一组对象定义对象过期规则 你的桶。每个对象过期规则允许您指定一个 前缀和以天为单位的到期期限。前缀字段(例如 logs/) 标识受到期规则约束的对象,并且 有效期指定从创建日期算起的天数 (即年龄)之后应该删除对象。一旦对象 已超过其到期日期,它们将排队等待删除。你 将不收取存储在其上或之后的对象的费用 到期日期。

【讨论】:

这是亚马逊提供的一个相当生硬的工具;它做它在锡上说的!如果您需要更好地控制删除的完成方式,则必须使用旧的 DELETE 方法。其他选项是拥有多达 1000 个不同的对象过期规则(和 1000 个不同的前缀);仍然限制在 1000 个。 这不会删除“旧的已经存在的文件”。它从您创建之时起生效。 这个规则可以为整个bucket设置,但不能为bucket中的单个文件夹设置? @Harshdeep - 所以不是真的。 “添加对象过期规则后,该规则将应用于存储桶中已存在的对象以及创建规则后添加到存储桶中的任何新对象。” aws.amazon.com/blogs/aws/amazon-s3-object-expiration @Slawomir 新的过期规则需要多长时间才能对存储桶中的现有对象生效?【参考方案2】:

这里有一些关于如何做的信息......

http://docs.amazonwebservices.com/AmazonS3/latest/dev/ObjectExpiration.html

希望这会有所帮助。

【讨论】:

仅链接的答案不是很好 他们应该包括一些有关该链接提供的信息的相关信息。如果链接失效,这个答案将变得毫无用处。看到这个帖子meta.stackexchange.com/a/8259/286322【参考方案3】:

您可以使用 AWS S3 生命周期规则使文件过期并删除它们。您所要做的就是选择存储桶,单击“添加生命周期规则”按钮并进行配置,AWS 将为您处理它们。

您可以参考以下 Joe 的博客文章,了解分步说明。其实很简单:

https://www.joe0.com/2017/05/24/amazon-s3-how-to-delete-files-older-than-x-days/

希望对你有帮助!

【讨论】:

【参考方案4】:

以下是如何使用 CloudFormation 模板实现它:

  JenkinsArtifactsBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub "jenkins-artifacts"
      LifecycleConfiguration:
        Rules:
          - Id: "remove-old-artifacts"
            ExpirationInDays: 3
            NoncurrentVersionExpirationInDays: 3
            Status: Enabled

这会创建一个生命周期规则,如 @Ravi Bhatt 所述

阅读更多内容: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-lifecycleconfig-rule.html

对象生命周期管理的工作原理: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html

【讨论】:

【参考方案5】:

您可以使用以下 Powershell 脚本删除在x days 之后过期的对象。

[CmdletBinding()]
Param(  
  [Parameter(Mandatory=$True)]
  [string]$BUCKET_NAME,             #Name of the Bucket

  [Parameter(Mandatory=$True)]
  [string]$OBJ_PATH,                #Key prefix of s3 object (directory path)

  [Parameter(Mandatory=$True)]
  [string]$EXPIRY_DAYS             #Number of days to expire
)

$CURRENT_DATE = Get-Date
$OBJECTS = Get-S3Object $BUCKET_NAME -KeyPrefix $OBJ_PATH
Foreach($OBJ in $OBJECTS)
    IF($OBJ.key -ne $OBJ_PATH)
        IF(($CURRENT_DATE - $OBJ.LastModified).Days -le $EXPIRY_DAYS)
            Write-Host "Deleting Object= " $OBJ.key
            Remove-S3Object -BucketName $BUCKET_NAME -Key $OBJ.Key -Force
        
    

【讨论】:

此脚本不适用于我想要删除超过指定时间的对象的场景。 IF(($CURRENT_DATE - $OBJ.LastModified).Days -le $EXPIRY_DAYS)... 行实际上应该是 IF(($CURRENT_DATE - $OBJ.LastModified).Days -ge $EXPIRY_DAYS)...【参考方案6】:

这是一个删除 N 天旧文件的 Python 脚本

from boto3 import client, Session
from botocore.exceptions import ClientError
from datetime import datetime, timezone
import argparse

if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    
    parser.add_argument('--access_key_id', required=True)
    parser.add_argument('--secret_access_key', required=True)
    parser.add_argument('--delete_after_retention_days', required=False, default=15)
    parser.add_argument('--bucket', required=True)
    parser.add_argument('--prefix', required=False, default="")
    parser.add_argument('--endpoint', required=True)

    args = parser.parse_args()

    access_key_id = args.access_key_id
    secret_access_key = args.secret_access_key
    delete_after_retention_days = int(args.delete_after_retention_days)
    bucket = args.bucket
    prefix = args.prefix
    endpoint = args.endpoint

    # get current date
    today = datetime.now(timezone.utc)

    try:
        # create a connection to Wasabi
        s3_client = client(
            's3',
            endpoint_url=endpoint,
            access_key_id=access_key_id,
            secret_access_key=secret_access_key)
    except Exception as e:
        raise e

    try:
        # list all the buckets under the account
        list_buckets = s3_client.list_buckets()
    except ClientError:
        # invalid access keys
        raise Exception("Invalid Access or Secret key")

    # create a paginator for all objects.
    object_response_paginator = s3_client.get_paginator('list_object_versions')
    if len(prefix) > 0:
        operation_parameters = 'Bucket': bucket,
                                'Prefix': prefix
    else:
        operation_parameters = 'Bucket': bucket

    # instantiate temp variables.
    delete_list = []
    count_current = 0
    count_non_current = 0

    print("$ Paginating bucket " + bucket)
    for object_response_itr in object_response_paginator.paginate(**operation_parameters):
        for version in object_response_itr['Versions']:
            if version["IsLatest"] is True:
                count_current += 1
            elif version["IsLatest"] is False:
                count_non_current += 1
            if (today - version['LastModified']).days > delete_after_retention_days:
                delete_list.append('Key': version['Key'], 'VersionId': version['VersionId'])

    # print objects count
    print("-" * 20)
    print("$ Before deleting objects")
    print("$ current objects: " + str(count_current))
    print("$ non-current objects: " + str(count_non_current))
    print("-" * 20)

    # delete objects 1000 at a time
    print("$ Deleting objects from bucket " + bucket)
    for i in range(0, len(delete_list), 1000):
        response = s3_client.delete_objects(
            Bucket=bucket,
            Delete=
                'Objects': delete_list[i:i + 1000],
                'Quiet': True
            
        )
        print(response)

    # reset counts
    count_current = 0
    count_non_current = 0

    # paginate and recount
    print("$ Paginating bucket " + bucket)
    for object_response_itr in object_response_paginator.paginate(Bucket=bucket):
        if 'Versions' in object_response_itr:
            for version in object_response_itr['Versions']:
                if version["IsLatest"] is True:
                    count_current += 1
                elif version["IsLatest"] is False:
                    count_non_current += 1

    # print objects count
    print("-" * 20)
    print("$ After deleting objects")
    print("$ current objects: " + str(count_current))
    print("$ non-current objects: " + str(count_non_current))
    print("-" * 20)
    print("$ task complete")

这就是我的运行方式

python s3_cleanup.py --aws_access_key_id="access-key" --aws_secret_access_key="secret-key-here" --endpoint="https://s3.us-west-1.wasabisys.com" --bucket="ondemand-downloads" --prefix="" --delete_after_retention_days=5

如果您只想从特定文件夹中删除文件,请使用prefix 参数

【讨论】:

以上是关于如何删除或清除 S3 上的旧文件?的主要内容,如果未能解决你的问题,请参考以下文章

s3cmd 复制删除元数据,你如何维护?

使用Python批量删除windows下特定目录的N天前的旧文件实战:Windows下批量删除旧文件清除缓存文件解救C盘拒绝C盘爆炸

如何从亚马逊 s3 存储桶中删除文件?

如何使用 Spring Cloud AWS 从 S3 中删除文件?

如何找到并清除所有Android设备上的SQLite数据库文件呢?

如何完全清除 git 存储库,而不删除它