计算桶文件夹中对象大小的有效方法
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=="
}
您只需添加所有尺寸。
第三个解决方案
如果文件是从您的平台上传的,那么最好将内容大小保存在数据库中的某个位置,然后 运行 查询以获取大小。
我想以某种方式为用户获取文件夹的总大小。目前我正在获取内存中的所有对象,然后循环所有对象以添加大小。
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=="
}
您只需添加所有尺寸。
第三个解决方案
如果文件是从您的平台上传的,那么最好将内容大小保存在数据库中的某个位置,然后 运行 查询以获取大小。