Amazon S3,同步,修改日期与上载日期

时间:2013-07-31 15:07:05

标签: c# .net amazon-web-services amazon-s3

我们正在使用适用于.NET的AWS开发工具包,而我正试图查明我们的消费者应用程序似乎存在同步问题。基本上我们有一个推送服务,可以生成上传到S3的变更集文件,我们的消费者应用程序应该下载这些文件并应用它们以便同步到正确的状态,这是不会发生的。

对于表示正确日期戳的内容/位置存在一些矛盾的观点。我们的消费者编写了查看s3文件的“LastModified”字段来对下载的文件进行排序以进行处理,我不知道该字段代表什么。起初我认为它表示我们上传的文件的修改/创建日期,然后(如here所示)它实际上代表了文件上传时的新日期戳,同样在同一链接中它似乎意味着当下载文件时它会恢复到旧的日期戳(但我无法确认)。

我们正在使用此代码段来提取文件

// Get a list of the latest changesets since the last successful full update.
Amazon.S3.AmazonS3Client client = ...;

List<Amazon.S3.Model.S3Object> listObjects = client.GetFullObjectList(
    this.Settings.GetS3ListObjectsRequest(this.Settings.S3ChangesetSubBucket), 
    Amazon.S3.AmazonS3Client.DateComparisonType.GreaterThan, 
    lastModifiedDate, 
    Amazon.S3.AmazonS3Client.StringTokenComparisonType.MustContainAll, 
    this.Settings.RequiredChangesetPathTokens);

然后按S3Object的LastModified排序(我认为我们的假设是错误的)

foreach (Amazon.S3.Model.S3Object obj in listObjects)
{
    if (DateTime.Parse(obj.LastModified) > lastModifiedDate)
    {
        //it's a new file, so we use insertion sort to put this file in an ordered list
        //based on LastModified
    }
}

我是否正确地假设我们应该做更多工作以保留我们自己需要的日期戳,例如使用自定义标头/元数据对象将正确的日期戳放在我们需要的文件上,或者甚至将其放在文件名中本身?

修改

也许这个问题可以解决我的问题:如果我的服务有2个文件要上传到S3并经历了这样做的过程,我保证这些文件按照上传的顺序显示在S3 中< / strong>(通过LastModified)还是S3做了一些异步处理,可能导致我的文件出现在S3对象列表中?我担心的情况是,例如,我的服务上传文件A然后B,B首先出现在S3中,我的消费者得到+进程B,然后A出现,然后我的消费者可能会或可能不会得到A和错误地处理它认为它不是新的时候不是吗?

编辑2

正如我和下面的人所怀疑的那样,我们有一些竞争条件试图按顺序应用变更集,同时盲目地依赖S3的日期戳。作为附录,我们最终制定了2个修复程序来尝试解决问题,这也可能对其他人有用:

首先,为了解决我们的上传完成时间与S3报告的修改日期之间的竞争条件,我们决定让我们的所有查询从我们从拉出文件中读取的最后修改日期起查看过去1秒S3。在检查此修复时,我们看到S3中的另一个问题之前并不明显,即 S3在时间戳上不保留毫秒,而是将它们舍入到下一秒所有的时间戳。回顾过去1秒就绕过了这个。

其次,由于我们回顾过去,如果没有要下载的新变更集文件,我们会有多次下载同一文件的问题,所以我们为上次请求中看到的文件添加了文件名缓冲区,跳过我们已经看到的任何文件,并在看到新文件时刷新缓冲区。

希望这有帮助。

1 个答案:

答案 0 :(得分:3)

在S3存储桶中列出对象时,从S3收到的API响应将始终按字母顺序返回。

S3 API不允许您根据LastModified值过滤或排序对象。任何此类过滤或排序都仅在您用于连接S3的客户端库中完成。

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html

至于LastModified值的准确性,可以根据上传时间对对象列表进行排序,据我所知,LastModified值设置为上传完成(当服务器返回200 OK响应时)而不是上载开始的时间。

这意味着如果您开始上传A的大小为100MB,之后又开始上传B,其大小仅为1K,最后,A的最后修改时间戳将在B的最后修改时间戳之后。< / p>

如果您需要保留上传开始的时间,最好在原始PUT请求中使用自定义元数据标头。