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

Differentiate between S3 object creation events vs object metadata updates

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

这是我的红移 table 的样子:

只要每行包含一个时间戳和当时文件的大小,并且从您的屏幕截图中看起来确实如此,您应该可以使用 LAST_VALUEFIRST_VALUE window 函数。

像这样

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 table 中每一行的一行的关系(我正在为 table,将其替换为您的),但 filesize 列将具有最新更新的值,而不是每次更新的 filesize。这听起来可能有点奇怪,但是单独尝试查询的这一部分并尝试使用参数,您可能会明白我的意思。

魔法就在 LAST_VALUE window 函数中。 Window 函数适用于当前行和所有其他行的子集。在这种情况下,我将 window 定义为具有相同 bucketnamekeyname 的所有其他行,按 lastupdated 排序。这意味着每个对象的最新更新将在 window 的最后一行,LAST_VALUE 为我选择了它。我本可以使用 FIRST_VALUE 获取第一个更新(或订购 DESC)。

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