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

时间:2015-10-28 11:02:03

标签: amazon-web-services amazon-s3 lambda amazon-redshift

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

以下是我的红移表:

enter image description here

1 个答案:

答案 0 :(得分:2)

只要每行包含时间戳和当时文件的大小,并且它看起来就像是从屏幕截图中看到的那样,您应该可以使用LAST_VALUE或{{1}执行此操作窗函数。

像这样的东西

FIRST_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_VALUEbucketname的所有其他行,按keyname排序。这意味着每个对象的最新更新将位于窗口的最后一行,lastupdated为我选择。我本可以使用LAST_VALUE来获取第一次更新(或订购FIRST_VALUE)。

能够在与窗口函数相同的查询中按DESCbucketname进行分组会很不错,但我无法弄清楚如何让Redshift这样做。相反,我添加了第二部分进行分组。我使用keyname来获取大小,但MAX也可以正常工作,我实际上只需要来自某行的值,因为它们都具有相同的值。来想一想MIN也应该有效。