Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services S3中文件的并发上传——防止上传冲突_Amazon Web Services_Amazon S3 - Fatal编程技术网

Amazon web services S3中文件的并发上传——防止上传冲突

Amazon web services S3中文件的并发上传——防止上传冲突,amazon-web-services,amazon-s3,Amazon Web Services,Amazon S3,有没有办法将文件上传到S3并强制在操作中创建对象,而不进行更新?(例如,模拟打开(O_创建| O_排除)) i、 如果文件已经存在,我希望我的PUT对象失败。S3确实提供了强大的“创建后读取”一致性,所以希望有办法利用这一点 抽象地说,我希望实现一个操作create\u s3\u对象(s3\u key,data),任何s3客户端都可以调用该操作,将数据写入s3\u key指定的新s3对象。在发出调用之前,数据和密钥是已知的 如果所有客户端都合作并使用create\u s3\u object(s3

有没有办法将文件上传到S3并强制在操作中创建对象,而不进行更新?(例如,模拟
打开(O_创建| O_排除)

i、 如果文件已经存在,我希望我的PUT对象失败。S3确实提供了强大的“创建后读取”一致性,所以希望有办法利用这一点

抽象地说,我希望实现一个操作
create\u s3\u对象(s3\u key,data)
,任何s3客户端都可以调用该操作,将
数据
写入
s3\u key
指定的新s3对象。在发出调用之前,数据和密钥是已知的

如果所有客户端都合作并使用
create\u s3\u object(s3\u key,data)
创建对象
s3\u key
,则调用应提供以下保证:

  • 如果文件
    s3_键
    不存在,则创建文件
    s3_键
    ,并将数据
    data
    作为其内容,调用成功

  • 如果file
    s3\u key
    已存在,则调用失败,并且现有文件未被调用修改。(我可以通过容忍文件
    s3_key
    的存在来放宽这一要求,如果且仅当它包含确切的
    数据

  • 如果文件
    s3\u key
    不存在,并且使用不同的数据从不同的客户端(和/或同一客户端)同时发出多个调用:即
    create\u s3\u对象(s3\u key,data1)
    create\u s3\u对象(s3\u key,data2)
    ,…
    create\u s3\u对象(s3\u key,dataN)
    ,然后,这些调用中最多有一个将成功,并且
    s3_key
    的数据将与成功的一个调用提供的数据匹配

  • 原子性。假设文件是通过
    create\u s3\u object(s3\u key,data)
    创建的,并且在创建后从未更新,如果任何客户端在任何时间点(创建之前、期间或之后)执行
    s3\u key
    的GET,则客户端将收到404错误(创建之前)或数据
    数据,但该文件没有其他版本(例如,
    s3\u键的某些瞬态)

  • 其他详情:

    • 我正在使用boto3(python)
    • 发出潜在冲突请求的一组客户端包括:在ECS容器(与bucket相同的区域)上运行、在lambda函数中运行(与bucket相同的区域)以及在aws外部公共internet上的桌面上运行的一个或两个进程

    我不知道,但您可能会使用bucket版本控制来检测您的上传不是第一个版本,然后处理这种情况。根据上传的来源,您可以使用DynamoDBLockClient“锁定”在bucket+对象上,一次只能对S3对象路径进行一次上载。如果您提供有关您的用例的更多详细信息,您的问题可能会有一个简单的解决方案(即使它不是您最初询问的条件PUT)。或者可能只是一个表示DynamoDB中S3对象键的项的条件PUT(不存在属性_)。@jarmod这很有意义。我最初认为有一种方法可以在S3上用If Not Match和//或If Match PUT/PUTCOPY操作组合某种形式的信号量。但是依赖另一个具有更强保证的服务似乎更容易。另一种选择是:不允许客户端直接访问S3 bucket,而是要求它们与您构建的小型API(Lambda和API网关)交互。Lambda函数基本上是一个预签名URL的供应商,用于上传到S3中的唯一密钥。它可以为所讨论的对象生成UUID,并将客户端上载到该UUID。如果UUID作为密钥对您来说是有问题的,因为文件名在某种程度上是重要的,那么您还可以构建一个小功能来处理这个问题(例如,将UUID文件从目标存储桶或DynamoDB密钥/值映射中的存储桶移动到文件名),但您可能会使用bucket版本控制来检测您的上载不是第一个版本,然后处理这种情况。根据上载的来源,您可以使用DynamoDBLockClient“锁定”bucket+对象,以便一次只能对S3对象路径进行一次上载。如果您提供有关您的用例的更多详细信息,您的问题可能会有一个简单的解决方案(即使它不是您最初询问的条件PUT)。或者可能只是一个表示DynamoDB中S3对象键的项的条件PUT(不存在属性_)。@jarmod这很有意义。我最初认为有一种方法可以在S3上用If Not Match和//或If Match PUT/PUTCOPY操作组合某种形式的信号量。但是依赖另一个具有更强保证的服务似乎更容易。另一种选择是:不允许客户端直接访问S3 bucket,而是要求它们与您构建的小型API(Lambda和API网关)交互。Lambda函数基本上是一个预签名URL的供应商,用于上传到S3中的唯一密钥。它可以为所讨论的对象生成UUID,并将客户端上载到该UUID。如果UUID作为密钥对您来说是有问题的,因为文件名在某种程度上是重要的,那么您还可以构建一个小功能来处理这个问题(例如,将UUID文件从目标bucket或DynamoDB密钥/值映射中的存储桶移动到文件名)。