计算桶文件夹中对象大小的有效方法

Efficient way of calculating size of the objects in folder of a bucket

我想以某种方式为用户获取文件夹的总大小。目前我正在获取内存中的所有对象,然后循环所有对象以添加大小。

let promises = []

// the format of Key is "storage/{USER ID}/docs"
for (const Key of keys) { 
      promises.push(new Promise(resolve => {
        engineS3.getObject({
          Bucket: process.env.ENGINE_AWS_BUCKET,
          Key
        }, (e, data) => {
          resolve(data)
        })

      }))
    }

let docs = await Promise.all(promises)

let usedSpace = docs.reduce((x, y) => x + y.ContentLength, 0) / (1024 * 1024 * 1024)

对于 2 3 个文档(每个文档的范围在 3mB 到 10mB 之间),它可以正常工作。但是随着用户和文档数量的增长,可能会因为资源不足而导致服务器崩溃。

遗憾的是,没有简单的方法可以实现这一点,但您可以使用 AWS CLI 命令

第一个解决方案

运行 根据您的代码执行命令。使用 child_process 或像 shelljs 这样的 npm 包。在这种情况下,您还需要对 CLI 进行身份验证。

aws s3 ls s3://yourBucket/storage/{USER ID}/docs --recursive --human-readable --summarize

这将 return 数据如下:

2013-09-02 21:37:53   10 Bytes a.txt
2013-09-02 21:37:53  2.9 MiB foo.zip
2013-09-02 21:32:57   23 Bytes foo/bar/.baz/a
2013-09-02 21:32:58   41 Bytes foo/bar/.baz/b
2013-09-02 21:32:57  281 Bytes foo/bar/.baz/c
2013-09-02 21:32:57   73 Bytes foo/bar/.baz/d
2013-09-02 21:32:57  452 Bytes foo/bar/.baz/e
2013-09-02 21:32:57  896 Bytes foo/bar/.baz/hooks/bar
2013-09-02 21:32:57  189 Bytes foo/bar/.baz/hooks/foo
2013-09-02 21:32:57  398 Bytes z.txt

Total Objects: 10
Total Size: 2.9 MiB

你可以从中解析总大小。

第二种解法

使用 Node AWS SDK 的 ListObjectsV2 方法。这里要注意的是,单次调用最多只有 returns 1000 个结果,并为下一页提供标记。您需要编写分页逻辑。

输出将是:

{
    Contents: [
        {
            Key: "example1.jpg",
            // ... Other details
            Size: 11,
        },
        {
            Key: "example2.mp4",
            // ... Other details
            Size: 784335,
        },
    ],
    NextMarker: "eyJNYXJrZXIiOiBudWxsLCAiYm90b190cnVuY2F0ZV9hbW91bnQiOiAyfQ=="
}

您只需添加所有尺寸。

第三个解决方案

如果文件是从您的平台上传的,那么最好将内容大小保存在数据库中的某个位置,然后 运行 查询以获取大小。