amazon-s3 - Amazon S3:如何安全地上传多个文件?
问题描述
我有两个使用 S3 来传达一些信息的客户端程序。该信息是文件列表。
让我们称客户端为“上传者”和“下载者”:
上传者做了这样的事情:
- 上传文件 A
- 上传文件 B
- 上传文件 C
- 上传 SUCCESS 标记文件
下载器做了一些谎言:
- 检查成功标记
- 如果找到,请下载 A、B、C。
- 否则,从其他地方获取数据
并且这两个程序都在定期运行。完成后,上传者将填充一个新目录,下载者将尝试获取可用的最新版本的 A、B、C。
希望意图很明确——我不希望下载者看到部分视图,而是获取所有 A、B、C 或跳过该目录。
但是,我认为这行不通,正如所写的那样。由于最终的一致性,上传者的 PUT 可以重新排序为:
- 上传文件 B
- 上传 SUCCESS 标记文件
- 上传文件 A
- ...
此时,下载器可能会运行,看到 SUCCESS 标记,并假设该目录已填充(事实并非如此)。
那么,正确的方法是什么?
一个想法是上传者先上传A,B,C,然后反复检查文件是否存储,只有在看到所有文件后,最后才写入SUCCESS标记。
那行得通吗?
解决方案
可以在 S3 中执行此单个副本。每个文件 (ABC) 都会在其前面添加一个唯一的哈希或版本代码 [例如,从所有三个文件的串联生成的 md5sum。]
此外,哈希值将被上传到存储桶以及单独的对象中。
消费文件时,首先读取哈希文件并与最后一次成功消费的哈希进行比较。如果更改,则读取文件并检查每个文件中的哈希值。如果它们都匹配,则数据有效并且可以使用。如果不是,则应丢弃下载的文件并再次下载(在适当的延迟后)..
这将捕获跨多个对象的写入和读取之间的偶然竞争条件。
这是有效的,因为哈希在所有对象中重复。哈希文件实际上是可选的,作为确定数据是否更新的低成本快速捷径。
推荐阅读
- c# - 如何在 .NET Core 应用程序中显示存储在虚拟目录中的图像?
- ios - SwiftUI Preview 因 stackoverflow 崩溃
- angular - 角度路由参数
- javascript - 一页上的两个按钮下的两个不同的js
- google-cloud-platform - GCP:我们可以在扳手中修改现有表的主键吗
- c# - 插值字符串上的 Ef Core vs Linq
- c# - 创建 lambda 表达式以查询数据
- javascript - Morgan 没有记录其余的 api 调用
- neo4j - 了解 Neo4j 的运算符
- java - 如何使用 JavaScript 在 selenium 中注入日期选择器的值?