You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过C# API实现AWS S3对象按创建时间精准留存1年?

问题

我们每天都会有对象存入AWS S3,希望无论对象处于哪个存储桶(目前仅使用一个),都能精准留存1年。我了解可设置存储桶级留存,也可为单个对象添加带留存期的Object Lock,但未找到明确说明该需求实现方式的文档。现有文档显示桶级留存到期时会删除桶内所有对象,且若对象的留存日期与桶不同,会修改桶的留存日期。当前桶内对象创建日期各不相同,请问如何通过C# API实现每个对象按创建时间留存恰好1年?

我已编写一段设置桶级留存的代码:

private void AddRetentionToBucket(string bucket) { 
    var retentionRequest = new PutObjectRetentionRequest() { 
        BucketName = bucket, 
        Retention = new ObjectLockRetention() { 
            RetainUntilDate = DateTime.Now.AddYears(_retentionYears) 
        } 
    }; 
    _client.PutObjectRetentionAsync(retentionRequest); 
}

下一步计划开展POC验证对象是否按留存日期正确留存或删除。欢迎各位提供建议。

补充说明:我们将有大量对象存入该存储,希望到期后彻底删除对象以节省存储空间。


解决方案

首先得明确:桶级的默认留存策略完全不适合你的场景——它会给所有对象设置统一的到期时间,而你需要每个对象按自身创建时间计算1年留存期,所以必须用对象级的Object Lock留存,配合正确的存储桶配置来实现。

第一步:确保存储桶开启Object Lock

使用对象级留存的前提是存储桶已启用Object Lock,而开启它必须先开启版本控制。如果是现有桶,按以下步骤配置(新桶可在创建时直接启用):

// 先启用版本控制
var versioningRequest = new PutBucketVersioningRequest
{
    BucketName = bucketName,
    VersioningConfig = new VersioningConfig { Status = VersionStatus.Enabled }
};
await _client.PutBucketVersioningAsync(versioningRequest);

// 再启用Object Lock(若创建桶时未开启,现有桶需确保支持该功能,否则可能需要重建)
var lockConfigRequest = new PutObjectLockConfigurationRequest
{
    BucketName = bucketName,
    ObjectLockConfiguration = new ObjectLockConfiguration
    {
        ObjectLockEnabled = "Enabled",
        // 这里可以设置默认规则,但我们后续会在对象上传时单独覆盖
        Rule = new ObjectLockRule
        {
            DefaultRetention = new DefaultRetention
            {
                Mode = ObjectLockRetentionMode.Governance, // 或Compliance,按需选择
                Days = 365
            }
        }
    }
};
await _client.PutObjectLockConfigurationAsync(lockConfigRequest);

第二步:上传新对象时设置专属留存期

每次上传对象时,直接给该对象设置RetainUntilDate为对象创建时间+1年。建议用UTC时间避免时区误差,比如以上传代码执行的UTC时间作为创建基准:

public async Task UploadObjectWithRetention(string bucketName, string key, Stream contentStream)
{
    var uploadRequest = new PutObjectRequest
    {
        BucketName = bucketName,
        Key = key,
        InputStream = contentStream,
        // 设置对象专属的Object Lock留存规则
        ObjectLockRetention = new ObjectLockRetention
        {
            Mode = ObjectLockRetentionMode.Governance, 
            // 用UTC时间计算,避免时区差异导致留存期偏差
            RetainUntilDate = DateTime.UtcNow.AddYears(1) 
        }
    };

    await _client.PutObjectAsync(uploadRequest);
}

第三步:批量更新已有对象的留存期

针对桶内已创建的旧对象,需要批量遍历并设置对应留存期。通过列出对象获取其LastModified时间,计算RetainUntilDate = LastModified.AddYears(1)后更新:

public async Task BatchUpdateExistingObjectsRetention(string bucketName)
{
    var listRequest = new ListObjectsV2Request
    {
        BucketName = bucketName,
        MaxKeys = 1000 // 分页查询,避免单次返回数据量过大
    };

    do
    {
        var listResponse = await _client.ListObjectsV2Async(listRequest);

        foreach (var s3Obj in listResponse.S3Objects)
        {
            var retentionRequest = new PutObjectRetentionRequest
            {
                BucketName = bucketName,
                Key = s3Obj.Key,
                VersionId = s3Obj.VersionId, // 开启版本控制后必须指定版本ID
                Retention = new ObjectLockRetention
                {
                    Mode = ObjectLockRetentionMode.Governance,
                    RetainUntilDate = s3Obj.LastModified.AddYears(1)
                }
            };

            await _client.PutObjectRetentionAsync(retentionRequest);
        }

        listRequest.ContinuationToken = listResponse.NextContinuationToken;
    } while (listRequest.ContinuationToken != null);
}

POC验证建议

  • 小批量时间测试:上传几个测试对象,分别设置1天、3天的短留存期,到期后检查是否被自动删除(注意S3删除可能有轻微延迟,不要刚到时间就急着验证)。
  • 权限模式验证:如果用Governance模式,测试带s3:BypassGovernanceRetention权限的用户能否提前删除;如果用Compliance模式,验证是否无法提前删除。
  • 版本控制清理测试:开启版本控制后,对象到期会删除当前版本,可配合生命周期规则清理非当前版本,测试存储空间是否被及时释放。
  • 生命周期规则补充:添加生命周期规则,确保对象留存到期后自动清理所有版本,进一步节省空间:
var lifecycleRequest = new PutLifecycleConfigurationRequest
{
    BucketName = bucketName,
    Configuration = new LifecycleConfiguration
    {
        Rules = new List<LifecycleRule>
        {
            new LifecycleRule
            {
                Id = "CleanupExpiredObjects",
                Status = LifecycleRuleStatus.Enabled,
                Expiration = new LifecycleRuleExpiration { Days = 0 }, // 留存到期后立即删除当前版本
                NoncurrentVersionExpiration = new LifecycleRuleNoncurrentVersionExpiration { Days = 7 } // 7天后清理非当前版本
            }
        }
    }
};
await _client.PutLifecycleConfigurationAsync(lifecycleRequest);

关键注意事项

  • 时区统一:所有时间计算尽量用UTC,避免不同时区导致的留存期偏差。
  • 版本管理:启用Object Lock必须开启版本控制,要注意清理无用版本,避免占用额外空间。
  • 模式选择:Compliance模式适合绝对不能提前删除的场景,Governance模式更灵活,允许授权用户提前删除,根据业务需求选择。

内容的提问来源于stack exchange,提问作者Optum56

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:22:42