【问题标题】:Set cache-control for entire S3 bucket automatically (using bucket policies?)自动为整个 S3 存储桶设置缓存控制(使用存储桶策略?)
【发布时间】:2012-05-13 04:50:11
【问题描述】:

我需要为整个 s3 存储桶设置缓存控制标头,包括现有文件和未来文件,并希望在存储桶策略中执行此操作。 我知道我可以编辑现有的,如果我自己上传它们,我知道如何在 put 上指定它们,但不幸的是,上传它们的应用程序无法设置标题,因为它使用 s3fs 将文件复制到那里。

【问题讨论】:

    标签: amazon-s3 s3fs


    【解决方案1】:

    我认为您不能在存储桶级别指定此内容,但有一些解决方法可供您使用。

    1. 将对象复制到自身在 S3 上为复制操作设置适当的 cache-control 标头。

    2. 在文件的 url 中指定响应标头。您需要使用预签名的 url 才能工作,但您可以在查询字符串中指定某些响应标头,包括 cache-controlexpires。有关可用选项的完整列表,请参阅:http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html?r=5225

    【讨论】:

    【解决方案2】:

    现在有 3 种方法可以完成此操作:通过 AWS 控制台通过命令行通过 s3cmd 命令行工具 >.


    AWS 控制台说明

    这是现在推荐的解决方案。这很简单,但可能需要一些时间。

    • 登录 AWS 管理控制台
    • 进入 S3 存储桶
    • 按路径选择所有文件
    • 从菜单中选择“更多”
    • 选择“更改元数据”
    • 在“Key”字段中,从下拉菜单中选择“Cache-Control” max-age=604800 输入(7 天)作为值
    • 按“保存”按钮

    (thanks to @biplob - please give him some love below)


    AWS 命令​​行解决方案

    最初,当我创建这个存储桶策略时是不行的,所以我想出了如何使用 aws-cli 来完成它,而且它非常巧妙。在研究时,我在野外找不到任何例子,所以我想我会发布一些我的解决方案来帮助有需要的人。

    注意:默认情况下,aws-cli 仅复制文件的当前元数据,即使您指定了新元数据。

    要使用在命令行中指定的元数据,您需要添加“--metadata-directive REPLACE”标志。下面是一些例子。

    对于单个文件

    aws s3 cp s3://mybucket/file.txt s3://mybucket/file.txt --metadata-directive REPLACE \
    --expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=2592000,public
    

    对于整个存储桶(注意 --recursive 标志):

    aws s3 cp s3://mybucket/ s3://mybucket/ --recursive --metadata-directive REPLACE \
    --expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=2592000,public
    

    我发现了一个小问题,如果您只想将其应用于特定文件类型,则需要排除所有文件,然后包含您想要的文件。

    只有 jpg 和 png:

    aws s3 cp s3://mybucket/ s3://mybucket/ --exclude "*" --include "*.jpg" --include "*.png" \
    --recursive --metadata-directive REPLACE --expires 2034-01-01T00:00:00Z --acl public-read \
    --cache-control max-age=2592000,public
    

    如果您需要更多信息,这里是手册的一些链接:

    已知问题:

    "Unknown options: --metadata-directive, REPLACE"
    

    这可能是由过时的 awscli 引起的 - 请参阅 @eliotRosewater's answer below


    S3cmd 工具

    S3cmd 是“用于管理 Amazon S3 和 CloudFront 服务的命令行工具”。虽然此解决方案需要 git pull,但它可能是一个更简单、更全面的解决方案。

    如需完整说明,请see @ashishyadaveee11's post below


    希望对你有帮助!

    【讨论】:

    • 感谢您提供具体操作的实际示例。仅仅阅读文档,我就很难发现什么是可能的。
    • 我在运行上述任何命令时收到“未知选项:--metadata-directive, REPLACE”。请帮助我。
    • 注意,现在有一种更简单的方法。您现在可以通过 AWS 控制台更改存储桶中所有文件的元数据。请参阅下面的 CoderBoy 的回答:stackoverflow.com/a/47072736/2538952
    • 请注意,使用 --meta-directive REPLACE 将覆盖任何先前未在命令中复制的元数据!例如,当没有显式添加到 cp 命令时,“content-encoding gzip”将被删除。
    • cp 是否下载并重新上传所有内容?
    【解决方案3】:

    步骤

    1. git clone https://github.com/s3tools/s3cmd
    2. 运行s3cmd --configure (您将被要求提供两个密钥 - 从您的 确认电子邮件或来自您的亚马逊帐户页面。时要小心 复制他们!它们区分大小写,必须准确输入 否则您将不断收到有关无效签名或类似内容的错误。 请记住为密钥添加s3:ListAllMyBuckets 权限,否则您将在测试访问时收到AccessDenied 错误。)
    3. ./s3cmd --recursive modify --add-header="Cache-Control:public ,max-age= 31536000" s3://your_bucket_name/

    【讨论】:

    • 超级答案。谢谢!有没有办法只更新那些还没有这个标题设置的人?
    • 有人有类似的解决方案来使用window的S3Express吗?
    【解决方案4】:

    致那些试图使用丹的答案并得到错误的人:

    “未知选项:--metadata-directive, REPLACE”

    我遇到了这个问题,问题是我使用

    安装了 awscli

    sudo apt-get install awscli

    这安装了缺少 --metadata-directive 命令的旧版本 awscli。所以我使用 sudo apt-get remove awscli 来删除它。

    然后按照亚马逊的步骤重新安装: http://docs.aws.amazon.com/streams/latest/dev/kinesis-tutorial-cli-installation.html

    唯一的区别是我必须使用 sudo -H 因为其他人也可能遇到的权限问题。

    【讨论】:

      【解决方案5】:

      您始终可以在 S3 上的 PUTOBJECT 上配置带有触发器的 lambda,该 lambda 将简单地更改刚刚放置的特定对象的标头。

      然后你可以最后一次运行上面提到的复制命令,所有的新对象都会被 lambda 修复。

      更新:

      这是一个很好的起点:https://www.aaronfagan.ca/blog/2017/how-to-configure-aws-lambda-to-automatically-set-cache-control-headers-on-s3-objects/

      【讨论】:

      • 你能提供更多关于如何制作这个lamba的细节吗?听起来是个不错的解决方案。
      • @Wouter 当然,我为您找到了一个实际上可以帮助您轻松到达那里的链接,aaronfagan.ca/blog/2017/… 如果您需要任何帮助或支持,我将非常乐意提供帮助。
      • 我知道这是旧的但是我发现这个资源对我正在寻找的东西很有用。这次真是万分感谢。为你投票,我的伙计!
      【解决方案6】:

      现在,可以从 AWS 控制台轻松更改。

      • 登录 AWS 管理控制台
      • 进入 S3 存储桶
      • 按路径选择所有文件
      • 从菜单中选择“更多”
      • 选择“更改元数据”
      • 在“Key”字段中,从下拉菜单中选择“Cache-Control”
      • max-age=604800 输入(7 天)作为值
      • 按“保存”按钮

      执行所需时间取决于您的存储桶文件。 如果您不小心关闭了浏览器,请从头开始重做。

      【讨论】:

      • “按路由选择所有文件”是什么意思?
      • 从您要设置元的目录中选择所有/部分文件
      • 这是替换以前的元数据还是添加到它? (我不想丢失我所有的内容类型!)
      • max-age=604800Enter (7 days) for Value 这是什么意思??
      • @Chris 它确实重置了我所有的内容类型(内容类型:二进制/八位字节流)UGH
      【解决方案7】:

      如果我的声誉得分 > 50,我会发表评论。但这还不是(还)所以这里有另一个完整的答案。


      一段时间以来,我一直在努力解决这个问题。直到我找到并阅读了文档。在这里分享,以防它帮助其他人:

      最终对我可靠工作的是这个命令。我选择了 1 秒的过期时间进行测试以验证预期结果:

      aws s3 cp \
        --metadata-directive REPLACE \
        --cache-control max-age=1,s-maxage=1 \
        s3://bucket/path/file \
        s3://bucket/path/file
      
      • 当“cp”在 S3 中修改现有文件的元数据时需要--metadata-directive REPLACE
      • max-age 设置浏览器缓存时间,以秒为单位
      • s-maxage 设置 CloudFront 缓存,以秒为单位

      同样,如果在上传到 S3 时在文件上设置这些 Cache-Control 标头值,则命令如下所示:

      aws s3 cp \
        --cache-control max-age=1,s-maxage=1 \
        /local/path/file \
        s3://bucket/path/file
      

      【讨论】:

        【解决方案8】:

        存储桶策略是授予存储桶和存储在其中的对象的权限,因此这条路不会产生您正在寻找的结果。其他答案使用自动方式修改对象元数据,但如果您愿意将存储桶移到 CloudFront 后面,也可以使用 Lambda@Edge。

        借助 Lambda@Edge,您可以为每个客户端请求运行任意代码,它可以更改从源(本例中为 S3 存储桶)返回的标头。它需要更多的配置并且需要一些钱,但这里有一个解决方案的蓝图:

        • 创建 CloudFront 分配
        • 添加 S3 存储桶作为源
        • 创建一个修改响应标头的 lambda 函数
        • 使用 CloudFront 分配的 URL 访问文件

        AWS 文档中有 an example 如何修改响应标头。如果你碰巧使用 Terraform 来管理我写过的基础设施 an article 怎么做。

        【讨论】:

          【解决方案9】:

          以前的答案要么与问题不相符,要么产生成本 (Lambda)。

          您应该在上传文件(PutObject 或 MultiPartUpload)时设置“cache-control”标头。

          根据您的语言,可能会有所不同。文档不是很清楚(大概是 AWS 希望您使用其他解决方案支付费用)。

          PHP 示例:

          $uploader = new MultipartUploader ($s3,$filename,[
              ...,
              'before_initiate' => function(\Aws\Command $command){
                  $command['CacheControl'] = 'max-age=31536000,public';
              },
          ...
          ]);
          

          Go 的另一个例子:

          cc := "max-age=31536000,public"
          input := &s3.PutObjectInput{
              ...,
              CacheControl: &cc,
          }
          

          【讨论】:

            【解决方案10】:

            我想我会分享我的用法,因为以前的答案误导了我。 AWS CLI 只有两个命令:

            aws s3 cp s3://bucketname/ s3://bucketname/ --cache-control max-age=12345 --recursive
            

            已经存在的东西就是这样,使用cp。像这样设置--cache-control 是一个有效的选项。

            如果你要上传你也可以sync,命令是:

            aws s3 sync z:\source\folder s3://bucketname/folder --delete --cache-control max-age=12345 --acl public-read
            

            请注意,我根本不使用--metadata-directive,因为使用它会丢失您猜到的内容类型,这会使图像等内容无法在浏览器中显示,但会立即下载。我的解决方案保留了猜测的值,并允许使用同步进行猜测。

            【讨论】:

              猜你喜欢
              • 2023-03-31
              • 2021-01-19
              • 2021-08-04
              • 2012-12-12
              • 2021-08-14
              • 2011-09-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多