快速查找S3“文件夹”的大小

17
我们有数百万个文件的S3“文件夹”(存储桶下带有前缀的对象),我们想要确定这些文件夹的大小。编写我自己的.NET应用程序以获取S3对象列表很容易,但每个请求的最大键数为1000,所以需要很长时间。使用S3Browser查看“文件夹”属性也需要很长时间。因为同样的原因,我猜测了一下。我已经运行了这个.NET应用程序一个星期,我需要一个更好的解决方案。有更快的方法吗?

每个请求的最大键数是1000吗?我对这项技术不是很熟悉,这些文件夹是远程的吗? - Jeffrey Eldredge
是的。http://aws.amazon.com/s3/ - b15
你需要精确的计数还是大致的估算?对象名称中是否有任何结构,例如,能否找出在日期A和日期B之间添加了多少文件,然后将其推广到整个生命周期? - DNA
大概数值可以使用,但必须相当准确。这些位置放置的对象数量和大小会随时间而变化。我们有两年的物品存量。我需要随时间取多个样本并使用它们。 - b15
5个回答

30

AWS CLIls命令可以做到这一点:aws s3 ls --summarize --human-readable --recursive s3://$BUCKETNAME/$PREFIX --region $REGION


获取所有存储桶信息 https://gist.github.com/jorgetovar/1f5e52ec4732d597e6d2bc432ee0745c - Jorge Tovar

13
似乎AWS添加了一个菜单项,可以查看大小:

S3文件夹的大小


有没有针对此的boto3 API和S3 CLI命令?非常需要。我知道我们可以围绕它编写代码,但我希望从AWS中获取,直到您发布此内容之前还没有。但我看不到任何关于此的文档。 - Aakash Basu
Foolish Brilliance 给出了一个关于 CLI 的答案,但我还没有尝试过:aws s3 ls --summarize --human-readable --recursive s3://$BUCKETNAME/$PREFIX --region $REGION。 - Filippo Loddo
有没有相应的boto3版本?奇怪的是AWS提供了控制台和CLI解决方案,但没有针对boto3/SDK的东西。 - Aakash Basu

10

我更喜欢使用AWSCLI。我发现当有太多对象时,Web控制台经常超时。

  • 将s3://bucket/替换为您要开始的位置。
  • 依赖于awscli、awk、tail和一些类似于bash的shell。
start=s3://bucket/ && \
for prefix in `aws s3 ls $start | awk '{print $2}'`; do
  echo ">>> $prefix <<<"
  aws s3 ls $start$prefix --recursive --summarize | tail -n2
done

或以一行形式表示:

start=s3://bucket/ && for prefix in `aws s3 ls $start | awk '{print $2}'`; do echo ">>> $prefix <<<"; aws s3 ls $start$prefix --recursive --summarize | tail -n2; done

输出结果类似:

$ start=s3://bucket/ && for prefix in `aws s3 ls $start | awk '{print $2}'`; do echo ">>> $prefix <<<"; aws s3 ls $start$prefix --recursive --summarize | tail -n2; done
>>> extracts/ <<<
Total Objects: 23
   Total Size: 10633858646
>>> hackathon/ <<<
Total Objects: 2
   Total Size: 10004
>>> home/ <<<
Total Objects: 102
   Total Size: 1421736087

这个没有给出被删除对象的大小? - SwapSays
谢谢 @debugme!我用了一行版本。你救了我的一天! - Tharaka

5
我认为没有理想的解决方案。但我提供了一些您可以进一步发展的想法:
  1. 应用程序是否是将文件写入S3的唯一方式?如果是,您可以在数据库、文件或其他地方存储文件大小,并在必要时进行求和。
  2. 同时调用LIST API。
  3. 您是否可以从基于文件夹的组织切换到基于存储桶的组织?如果是,您可以查询计费API(是的,计费),并从成本中计算出大小(或近似值)...

#1 不适用。不幸的是,我们在那里有太多内容,并且已经达到了使用#3的存储桶限制。#2 是我一直在考虑的选项,但它仍然需要像最大的“文件夹”所需的时间那样长,大约需要3-4小时。 - b15
在#2中:我正在考虑针对单个文件夹的并发调用。通过使用“前缀”参数,您可以拥有例如列出以“a”开头的对象的调用,一个为“b”等的调用... - MatteoSp

1
如果他们每个请求只允许你使用1000个密钥,我不确定PowerShell如何帮助你,但是如果你想要计算一堆文件夹的大小,可以尝试以下代码:
请将以下代码保存到名为Get-FolderSize.ps1的文件中:
param
(
    [Parameter(Position=0, ValueFromPipeline=$True, Mandatory=$True)]
    [ValidateNotNullOrEmpty()]
    [System.String]
    $Path
)

function Get-FolderSize ($_ = (get-item .))  {
  Process {
    $ErrorActionPreference = "SilentlyContinue"
    #? { $_.FullName -notmatch "\\email\\?" }  <-- Exlcude folders.
    $length = (Get-ChildItem $_.fullname -recurse | Measure-Object -property length -sum).sum
    $obj = New-Object PSObject
    $obj | Add-Member NoteProperty Folder ($_.FullName)
    $obj | Add-Member NoteProperty Length ($length)
     Write-Output $obj
  }
}

Function Class-Size($size)
{

    IF($size -ge 1GB)
    {
        "{0:n2}" -f  ($size / 1GB) + " GB"
    }
    ELSEIF($size -ge 1MB)
    {
        "{0:n2}" -f  ($size / 1MB) + " MB"
    }
    ELSE
    {
        "{0:n2}" -f  ($size / 1KB) + " KB"
    }
}

Get-ChildItem $Path | Get-FolderSize | Sort-Object -Property Length -Descending | Select-Object -Property Folder, Length | Format-Table -Property Folder, @{ Label="Size of Folder" ; Expression = {Class-Size($_.Length)} }

使用方法:.\Get-FolderSize.ps1 -Path \path\to\your\folders


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接