区分 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_VALUE
或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_VALUE
窗口函数。窗口函数适用于当前行和所有其他行的子集。在这种情况下,我将窗口定义为具有相同bucketname
和keyname
的所有其他行,按lastupdated
排序。这意味着每个对象的最新更新将在窗口的最后一行,LAST_VALUE
为我挑选。我本可以使用FIRST_VALUE
获得第一次更新(或订购DESC
)。
如果能够在与窗口函数相同的查询中按 bucketname
和 keyname
进行分组,那就太好了,但我不知道如何让 Redshift 做到这一点。相反,我添加了第二部分来进行分组。我使用MAX
来获取大小,但MIN
也可以,我实际上只需要某行的值,因为它们都具有相同的值。想一想SELECT DISTINCT bucketname, keyname, filesize FROM latest_sizes
应该也可以。
【讨论】:
谢谢 .. 这行得通!我最初的问题更简单,因为我想找出文件的数量。我自己想出了这部分,但是您的答案解决了我接下来会遇到的问题,即如果文件大小已更新,则存储桶的大小(以字节为单位)。感谢 LAST_VALUE 的提示。 你是不是也用窗口函数来解文件数?我认为应该可以通过在operation
列上使用LAST_VALUE
来解决它,然后在第二步中过滤掉operation = DELETE
所在的行。
文件数量我没有使用窗口函数。我计算了具有操作为“插入”的不同文件的计数减去具有操作为“删除”的不同文件的计数。这会起作用,因为在 S3 中没有重命名文件这样的事情吗?
听起来好像可以获取存储桶的总数。以上是关于区分 S3 对象创建事件与对象元数据更新的主要内容,如果未能解决你的问题,请参考以下文章