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

77
有没有现有的解决方案可以删除任何超过x天的文件?

1
目前我将使用以下解决方案: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 - Erik
6个回答

95

亚马逊最近推出了对象到期功能。

亚马逊S3宣布对象过期

亚马逊S3宣布推出了一个新功能,即对象过期,它允许您在预定义的时间段后安排删除对象。使用对象到期定期删除对象可以省去您识别要删除的对象并向亚马逊S3提交删除请求的麻烦。

您可以为存储桶中一组对象定义对象到期规则。每个对象到期规则允许您指定前缀和一个以天为单位的过期期限。前缀字段(如 logs / )标识受到到期规则约束的对象,而到期期限指定从创建日期(即年龄)开始多少天后应删除对象。一旦对象过期,它们将被排队等待删除。过期后的对象不会再产生存储费用。


1
这是亚马逊提供的一种相当直接的工具;它做到了它所说的!如果你需要更精细地控制删除操作,你将不得不使用旧的DELETE方法。另一个选择是拥有多达1000个不同的对象过期规则(和1000个不同的前缀);但仍然受到1000的限制。 - ϹοδεMεδιϲ
13
这并不会删除“先前已存在的旧文件”。它从您创建文件的时间开始生效。 - Harshdeep
1
这个规则可以应用于整个存储桶,但不能应用于存储桶内的单个文件夹。 - Nihilarian
5
“Harshdeep - 所以并不完全如此。'添加对象过期规则后,该规则将适用于存储桶中已经存在的对象以及在创建规则后添加到存储桶的任何新对象。” https://aws.amazon.com/blogs/aws/amazon-s3-object-expiration/ - Slawomir
1
@Slawomir,新的过期规则对存储桶中现有对象生效需要多长时间? - Phoenix
显示剩余2条评论

5

8
仅提供链接的回答并不好。它们应该包含有关链接内容的相关信息。如果链接失效,这些答案将变得无用。请参阅此帖子: https://meta.stackexchange.com/a/8259/286322 - Novocaine
OP已经离开了这个地方:"最后一次出现是6年前" - undefined

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


2

1
以下是一份Python脚本,用于删除N天前的文件。
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 参数。

0
您可以使用以下 Powershell 脚本来删除 x 天 后过期的对象。
[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)... - CarlR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接