区分 S3 对象创建事件与对象元数据更新

Posted

技术标签:

【中文标题】区分 S3 对象创建事件与对象元数据更新【英文标题】:Differentiate between S3 object creation events vs object metadata updates 【发布时间】:2015-10-28 11:02:02 【问题描述】:

我将 S3 事件插入到 Redshift 表中,我打算从中找出文件总数以及存储桶的总大小。我正在使用 Lambda 函数来捕获 PUT、POST 和 DELETE 事件,并将这些事件写入 kinesis firehose,然后将这些事件直接推送到 Redshift 表。问题是在我的 lambda 函数中,我无法知道事件是 s3 对象的创建事件还是更新事件(例如,当您更改冗余设置或服务器端加密时)。现在我在同一个文件的表中有一堆事件,因此很难计算存储桶的实际大小。你会建议我做什么?谢谢。

这是我的红移表的样子:

【问题讨论】:

【参考方案1】:

只要每一行都包含一个时间戳和当时文件的大小,并且看起来与您的屏幕截图一样,您应该可以使用LAST_VALUEFIRST_VALUE 窗口函数来执行此操作。

类似的东西

WITH latest_sizes AS (
  SELECT
    bucketname,
    keyname,
    LAST_VALUE(filesize) OVER (
      PARTITION BY bucketname, keyname
      ORDER BY lastupdated
      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    ) AS filesize
  FROM s3_events
)
SELECT
  bucketname,
  keyname,
  MAX(filesize) AS filesize
FROM latest_sizes
GROUP BY 1, 2

应该给你最后报告的每个桶和键的大小,如果你想要每个桶的总大小,你可以用

替换最后一部分
SELECT
  bucketname,
  MAX(filesize) AS total_size
FROM latest_sizes
GROUP BY 1

查询的工作方式如下:latest_sizes 将导致与s3_events 表中每一行的行相关(我正在编一个表的名称,用它代替你的),但不是每个更新的filesize filesize 列将具有最新更新的值。这听起来可能有点奇怪,但是单独尝试查询的这一部分并使用参数,您可能会明白我的意思。

神奇之处在于LAST_VALUE 窗口函数。窗口函数适用于当前行和所有其他行的子集。在这种情况下,我将窗口定义为具有相同bucketnamekeyname 的所有其他行,按lastupdated 排序。这意味着每个对象的最新更新将在窗口的最后一行,LAST_VALUE 为我挑选。我本可以使用FIRST_VALUE 获得第一次更新(或订购DESC)。

如果能够在与窗口函数相同的查询中按 bucketnamekeyname 进行分组,那就太好了,但我不知道如何让 Redshift 做到这一点。相反,我添加了第二部分来进行分组。我使用MAX 来获取大小,但MIN 也可以,我实际上只需要某行的值,因为它们都具有相同的值。想一想SELECT DISTINCT bucketname, keyname, filesize FROM latest_sizes 应该也可以。

【讨论】:

谢谢 .. 这行得通!我最初的问题更简单,因为我想找出文件的数量。我自己想出了这部分,但是您的答案解决了我接下来会遇到的问题,即如果文件大小已更新,则存储桶的大小(以字节为单位)。感谢 LAST_VALUE 的提示。 你是不是也用窗口函数来解文件数?我认为应该可以通过在operation 列上使用LAST_VALUE 来解决它,然后在第二步中过滤掉operation = DELETE 所在的行。 文件数量我没有使用窗口函数。我计算了具有操作为“插入”的不同文件的计数减去具有操作为“删除”的不同文件的计数。这会起作用,因为在 S3 中没有重命名文件这样的事情吗? 听起来好像可以获取存储桶的总数。

以上是关于区分 S3 对象创建事件与对象元数据更新的主要内容,如果未能解决你的问题,请参考以下文章

使用 lambda 更新 amazon s3 对象元数据而不执行对象复制?

Boto3 S3 更新现有对象的元数据

AWS S3 大文件分片上传

快速获取AWS S3对象元数据

在单个 S3 对象上传事件上触发多个 lambda

使用 AWS Java 开发工具包为现有 S3 对象设置 Expires 标头