Amazon S3:如何安全上传多个文件?

时间:2018-05-15 15:54:37

标签: amazon-s3 eventual-consistency

我有两个客户端程序正在使用S3来传递一些信息。该信息是文件列表。

让我们称客户为“上传者”和“下载者”:

上传程序执行以下操作:

  • 上传文件A
  • 上传文件B
  • 上传文件C
  • 上传SUCCESS标记文件

下载程序可以解决这个问题:

  • 检查SUCCESS标记
    • 如果找到,请下载A,B,C。
    • 其他,从其他地方获取数据

这两个程序都在定期运行。上传程序将在完成后填充新目录,下载程序将尝试获取最新版本的A,B,C。

希望意图明确 - 我不希望下载者看到部分视图,而是获取所有A,B,C或跳过该目录。

然而,我认为这不符合要求。由于最终的一致性,上传者的PUT可以重新排序为:

  • 上传文件B
  • 上传SUCCESS标记文件
  • 上传文件A
  • ...

此时,下载程序可能会运行,请参阅SUCCESS标记,并假设该目录已填充(不是)。

那么什么是正确的方法,在这里?

一个想法是上传者首先上传A,B,C,然后反复检查文件是否存储,并且只有在看到所有文件之后,才最后写入SUCCESS标记。

那会有用吗?

2 个答案:

答案 0 :(得分:0)

在我的项目中偶然发现类似问题。 如果要保证跨文件的一致性(在文件A,B,C之间),则唯一可行的解​​决方案(仅在s3内)是:

1)将它们作为新对象

2)不要在放置之前使用HEAD或GET请求明确检查是否存在。

要完全一致地执行写入后读取行为(https://aws.amazon.com/about-aws/whats-new/2015/08/amazon-s3-introduces-new-usability-enhancements/),需要上述两个约束条件

每次更新文件时,都需要生成一个唯一的前缀(文件夹)名称,然后将此名称放入要更新的标记文件(清单)中。

清单将具有稳定的名称,但最终将保持一致。一些客户端可能会获得旧版本,而某些可能会获得新版本。 旧清单将指向旧“文件夹”,而新清单将指向新“文件夹”。这样,每个客户端将仅读取旧文件或仅读取新文件,但从不读取,因此可以实现跨文件的一致性。仍然不同的客户端可能最终具有不同的版本。如果客户不断拉动清单并及时更新更改,他们最终也将变得一致。

客户端不一致的可能解决方案是将清单元数据从s3移到一致的数据库(例如dynamo db)中

使用纯s3方法的一些明显警告:

1)要求每次都上传完整的文件集(无法进行增量更新)

2)最终需要清除旧的过时文件夹

3)客户需要不断提取清单以进行更新

4)客户端之间可能会不一致

答案 1 :(得分:0)

可以在 S3 中执行此单份副本。每个文件(A B C)都将预先添加一个唯一的哈希或版本代码[例如md5sum 由所有三个文件的串联生成。]

此外,哈希值也将上传到存储桶以及一个单独的对象中。

在消费文件时,首先读取哈希文件并与上次成功消费的哈希进行比较。如果更改,则读取文件并检查每个文件中的哈希值。如果它们都匹配,则数据有效并可使用。如果没有,则应丢弃已下载的文件并再次下载(适当延迟后)。

这将捕获跨多个对象的写入和读取之间的偶然竞争条件。

这是有效的,因为散列在所有对象中都是重复的。哈希文件实际上是可选的,作为判断数据是否更新的低成本快速捷径。