Comment obtenir la taille d'un compartiment Amazon S3?


290

J'aimerais représenter graphiquement la taille (en octets et nombre d'éléments) d'un compartiment Amazon S3 et je recherche un moyen efficace d'obtenir les données.

Les outils s3cmd fournissent un moyen d'obtenir la taille totale du fichier s3cmd du s3://bucket_name, mais je suis inquiet quant à sa capacité à évoluer, car il semblerait qu'il récupère les données de chaque fichier et calcule sa propre somme. Étant donné qu'Amazon facture ses utilisateurs en Go-Mois, il semble étrange qu'ils n'exposent pas cette valeur directement.

Bien que l'API REST d'Amazon renvoie le nombre d'éléments dans un compartiment , s3cmd ne semble pas l'exposer. Je pourrais le faire, s3cmd ls -r s3://bucket_name | wc -lmais cela semble être un bidouillage.

La bibliothèque Ruby AWS :: S3 semblait prometteuse, mais ne fournit que le nombre d'éléments de compartiment, pas la taille totale du compartiment.

Est-ce que quelqu'un connaît d'autres outils ou bibliothèques en ligne de commande (préférez Perl, PHP, Python ou Ruby) qui fournissent des moyens d'obtenir ces données?


J'ai écrit un outil pour analyser la taille d'un seau: github.com/EverythingMe/ncdu-s3
omribahumi

20
Je suis étonné que Amazon facture pour l'espace, mais ne fournit pas la taille totale occupée par un compartiment S3 simplement via le panneau S3.
Luc

Pour moi, la plupart des réponses ci-dessous ont mis du temps à récupérer la taille du compartiment
Vaulstein

Réponses:


169

AWS CLI prend désormais en charge le --queryparamètre qui prend une expression JMESPath .

Cela signifie que vous pouvez additionner les valeurs de taille données en list-objectsutilisant sum(Contents[].Size)et compter comme length(Contents[]).

Ceci peut être exécuté à l'aide de l'AWS CLI officiel, comme ci-dessous, et a été introduit en février 2014.

 aws s3api list-objects --bucket BUCKETNAME --output json --query "[sum(Contents[].Size), length(Contents[])]"

21
Pour les grands seaux (gros fichiers), cela est extrêmement lent. L'utilitaire Python s4cmd "du" est ultra-rapide:s4cmd du s3://bucket-name
Brent Faust

C'est étrange. Quel est le profil général de votre seau (peu profond et épais / profond et mince)? Il semble que s3cmddevrait avoir les mêmes frais généraux que AWS CLI. Dans le code, il montre s3cmd faire une demande pour chaque répertoire dans un compartiment.
Christopher Hackett

22
pour l'obtenir dans un format lisible par l'homme: aws s3api --profile PROFILE_NAME list-objects --bucket BUCKET_NAME --output json --query "[sum(Contents[].Size), length(Contents[])]" | awk 'NR!=2 {print $0;next} NR==2 {print $0/1024/1024/1024" GB"}'
Sandeep

21
Maintenant qu'AWS Cloudwatch propose une métrique «BucketSizeBytes» par compartiment, ce n'est plus la bonne solution. Voir la réponse de Toukakoukan ci-dessous.
cce

2
s4cmd duest merveilleux, merci @Brent Faust! petite note (pour les personnes concernées) que vous devez ajouter -rpour obtenir également la taille des sous-répertoires.
Greg Sadetsky

331

Cela peut maintenant être fait de manière triviale avec seulement le client de ligne de commande AWS officiel:

aws s3 ls --summarize --human-readable --recursive s3://bucket-name/

Documentation officielle

Cela accepte également les préfixes de chemin si vous ne voulez pas compter le compartiment entier:

aws s3 ls --summarize --human-readable --recursive s3://bucket-name/directory

23
C’est la meilleure réponse, et la plus récente
Tim

2
D'accord, c'est la meilleure réponse.
Luis Artola

25
Cette procédure est très lente pour les compartiments contenant de nombreux fichiers car elle répertorie tous les objets du compartiment avant d'afficher le résumé. En outre, elle n'est pas beaucoup plus rapide que la réponse de @Christopher Hackett - à l'exception de celle-ci qui est beaucoup plus bruyante.
Guss

Exécuter sur une instance EC2 avec la même région que le
compartiment

1
Cela montrera la taille de TOUS les fichiers individuels dans l’arborescence. Que faire si je veux juste que la taille totale du répertoire soit totale?
Chris F

130

AWS Console:

En date du 28 de Juillet ici à 2015 , vous pouvez obtenir ces informations via CloudWatch . Si vous souhaitez une interface graphique, accédez à la console CloudWatch : (Choisissez une région>)> Métriques> S3

Commande AWS CLI:

Ceci est beaucoup plus rapide que certaines des autres commandes publiées ici, car il ne demande pas la taille de chaque fichier individuellement pour calculer la somme.

 aws cloudwatch get-metric-statistics --namespace AWS/S3 --start-time 2015-07-15T10:00:00 --end-time 2015-07-31T01:00:00 --period 86400 --statistics Average --region eu-west-1 --metric-name BucketSizeBytes --dimensions Name=BucketName,Value=toukakoukan.com Name=StorageType,Value=StandardStorage

Important : Vous devez spécifier StorageType et BucketName dans l'argument de dimensions, sinon vous n'obtiendrez aucun résultat. Tout ce que vous devez changer est la --start-date, --end-timeet Value=toukakoukan.com.


Voici un script bash que vous pouvez utiliser pour éviter de devoir spécifier --start-dateet --end-timemanuellement.

#!/bin/bash
bucket=$1
region=$2
now=$(date +%s)
aws cloudwatch get-metric-statistics --namespace AWS/S3 --start-time "$(echo "$now - 86400" | bc)" --end-time "$now" --period 86400 --statistics Average --region $region --metric-name BucketSizeBytes --dimensions Name=BucketName,Value="$bucket" Name=StorageType,Value=StandardStorage

25
Ou dans la console CloudWatch : (Choisissez une région>), paramètres> S3
Halil Özgür

3
C'est de loin la solution la plus simple et la plus rapide. Malheureusement, la réponse n’est encore qu’à la quatrième place.
luk2302

Cela a fonctionné pour mon seau avec 10 millions + objets. Mais le script bash n'a rien retourné, il a fallu aller à l'interface graphique).
Petah

1
Il convient également de noter que vous devrez également changer de région
majikman

mai 2018: les erreurs de script avecInvalid value ('1525354418') for param timestamp:StartTime of type timestamp
anneb

106

s3cmd peut faire ceci:

s3cmd du s3://bucket-name


Merci. Voici un moment. Sur un compartiment qui contient un système de fichiers dédupliqué s3ql avec environ un million de fichiers utilisant environ 33 Go de données non dupliquées et environ 93 000 objets s3, s3cmd du a pris environ 4 minutes pour calculer la réponse. Je suis curieux de savoir comment cela se compare à d'autres approches comme celle décrite ici ailleurs.
nealmcb

1
Il est lent car l' appel de l'API S3 ListObjects renvoie des objets dans des pages de 1 000 objets. Comme les E / S sont de loin le facteur limitant, je pense que toute solution sera relativement lente sur 93 000 objets.
David Snabel-Caunt

11
s4cmd peut également faire la même chose, avec l'avantage supplémentaire de gérer plusieurs requêtes en même temps que les requêtes adressées à l'API de S3 afin de calculer le résultat plus rapidement. L'outil n'a pas été mis à jour récemment, mais il peut être utile pour les passants Internet.
Nick Chammas

s4cmd ne fait que renvoyer 0 pour moi, et BotoClientError: Bucket names cannot contain upper-case characters when using either the sub-domain or virtual hosting calling format.pour les compartiments avec des caractères majuscules.
Lakitu

22

Si vous téléchargez un rapport d'utilisation , vous pouvez représenter graphiquement les valeurs quotidiennes du TimedStorage-ByteHrschamp.

Si vous voulez ce nombre en Gio, divisez simplement par 1024 * 1024 * 1024 * 24(c'est Gio-heure pour un cycle de 24 heures). Si vous voulez le nombre en octets, il suffit de diviser par 24 et de tracer le graphique.


19

Utilisation des outils de ligne de commande AWS s3 officiels:

aws s3 ls s3://bucket/folder --recursive | awk 'BEGIN {total=0}{total+=$3}END{print total/1024/1024" MB"}'

C'est une meilleure commande, il suffit d'ajouter les 3 paramètres suivants --summarize --human-readable --recursiveaprès aws s3 ls. --summarizen'est pas obligatoire, mais donne une bonne idée de la taille totale.

aws s3 ls s3://bucket/folder --summarize --human-readable --recursive

1
Fournissez le lien vers l'endroit où amazon l'indique réellement, s'il vous plaît. Je ne peux pas le trouver.
Lobi



4
Cette réponse a fonctionné le mieux et le plus rapide pour moi.
Miro

2
réponse la meilleure et la plus rapide!
PlagTag

11

s4cmd est le moyen le plus rapide que j'ai trouvé (un utilitaire de ligne de commande écrit en Python):

pip install s4cmd

Maintenant, calculons la taille totale du compartiment en utilisant plusieurs threads:

s4cmd du -r s3://bucket-name

6
Non, s4cmd du s3://123123drinkje ne retournerai pas simplement la taille du seau. Pour obtenir la taille du seau, vous devez ajouter un -rélément récursif , comme ceci: s4cmd du -r s3: // 123123drink
George Chalhoub

1
Oui, bon point @BukLau (ajouté -rà l'exemple ci-dessus pour éviter toute confusion lorsque des personnes utilisent des dossiers simulés sur S3).
Brent Faust

6

J'ai utilisé l' API S3 REST / Curl répertoriée plus haut dans ce fil de discussion:

<?php
if (!class_exists('S3')) require_once 'S3.php';

// Instantiate the class
$s3 = new S3('accessKeyId', 'secretAccessKey');
S3::$useSSL = false;

// List your buckets:
echo "S3::listBuckets(): ";
echo '<pre>' . print_r($s3->listBuckets(), 1). '</pre>';

$totalSize = 0;
$objects = $s3->getBucket('name-of-your-bucket');
foreach ($objects as $name => $val) {
    // If you want to get the size of a particular directory, you can do
    // only that.
    // if (strpos($name, 'directory/sub-directory') !== false)
    $totalSize += $val['size'];
}

echo ($totalSize / 1024 / 1024 / 1024) . ' GB';
?>

6

Vous pouvez utiliser l'utilitaire s3cmd, par exemple:

s3cmd du -H s3://Mybucket
97G      s3://Mybucket/

5

Alors, parcourant l'API et jouant à plusieurs requêtes identiques, S3 produira le contenu complet d'un compartiment en une seule requête et il n'aura pas besoin de descendre dans des répertoires. Les résultats nécessitent alors simplement de faire la somme des différents éléments XML et non des appels répétés. Je n'ai pas d'échantillons contenant des milliers d'articles, alors je ne sais pas dans quelle mesure il va évoluer, mais cela semble assez simple.


Cela semble être la meilleure option. Mettra à jour ce message à l'avenir s'il évolue mal et que je dois faire autre chose. La bibliothèque qui a fini par fournir un accès facile aux résultats bruts de l'API était celle-ci PHP: undesigned.org.za/2007/10/22/amazon-s3-php-class
Garret Heaton

N'est-ce pas limité aux 1000 premiers articles?
Charlie Schliesser

4

... Un peu tard, mais le meilleur moyen que j'ai trouvé est d'utiliser les rapports du portail AWS. J'ai créé une classe PHP pour le téléchargement et l'analyse des rapports. Avec cela, vous pouvez obtenir le nombre total d'objets pour chaque compartiment, la taille totale en Go ou en octets et plus.

Check it out et laissez-moi savoir si était utile

AmazonTools


C'est une solution intéressante, bien qu'un peu féroce. Inquiet que cela se produise si Amazon change son site, mais il se peut que je doive essayer ceci une fois que j’ai assez d’objets pour que l’inverse devienne trop lent. Un autre avantage de cette approche est que vous ne recevez aucun frais pour les appels d'API.
Garret Heaton

. . . C’est une hypothèse, mais si Amazon change l’aspect de son site, je doute qu’il modifierait beaucoup le back-end, ce qui signifie que les requêtes GET et POST actuelles devraient fonctionner. Je maintiendrai le cours dans le cas où il se casserait quand même car je l'utilise souvent.

3

Je recommande d'utiliser le rapport d'utilisation S3 pour les grands compartiments. Pour plus d'informations , reportez- vous à la section Comment l' obtenir. Vous devez essentiellement télécharger le rapport d'utilisation du service S3 pour le dernier jour avec Stockage synchronisé - Octets heures et l'analyser pour obtenir l'utilisation du disque.

cat report.csv | awk -F, '{printf "%.2f GB %s %s \n", $7/(1024**3 )/24, $4, $2}' | sort -n

3

La documentation AWS vous explique comment procéder:

aws s3 ls s3://bucketnanme --recursive --human-readable --summarize

Voici le résultat obtenu:

2016-05-17 00:28:14    0 Bytes folder/
2016-05-17 00:30:57    4.7 KiB folder/file.jpg
2016-05-17 00:31:00  108.9 KiB folder/file.png
2016-05-17 00:31:03   43.2 KiB folder/file.jpg
2016-05-17 00:31:08  158.6 KiB folder/file.jpg
2016-05-17 00:31:12   70.6 KiB folder/file.png
2016-05-17 00:43:50   64.1 KiB folder/folder/folder/folder/file.jpg

Total Objects: 7

   Total Size: 450.1 KiB

2

Pour une approche vraiment low-tech: utilisez un client S3 capable de calculer la taille pour vous. J'utilise Panic's Transmit, cliquez sur un seau, faites "Obtenir des informations" et cliquez sur le bouton "Calculer". Je ne suis pas sûr de sa rapidité ni de sa précision par rapport à d'autres méthodes, mais cela semble redonner la taille à laquelle je m'attendais.


2

Puisqu'il y a tant de réponses, j'ai pensé que j'allais ajouter les miennes. J'ai écrit mon implémentation en C # en utilisant LINQPad. Copiez, collez et entrez la clé d'accès, la clé secrète, le point de terminaison de la région et le nom du compartiment que vous souhaitez interroger. Assurez-vous également d'ajouter le package de nuget AWSSDK.

En testant contre un de mes seaux, il m'a donné un compte de 128075 et une taille de 70,6 Go. Je sais que la précision est de 99,9999%, alors je suis bon avec le résultat.

void Main() {
    var s3Client = new AmazonS3Client("accessKey", "secretKey", RegionEndpoint.???);
    var stop = false;
    var objectsCount = 0;
    var objectsSize = 0L;
    var nextMarker = string.Empty;

    while (!stop) {
        var response = s3Client.ListObjects(new ListObjectsRequest {
            BucketName = "",
            Marker = nextMarker
        });

        objectsCount += response.S3Objects.Count;
        objectsSize += response.S3Objects.Sum(
            o =>
                o.Size);
        nextMarker = response.NextMarker;
        stop = response.S3Objects.Count < 1000;
    }

    new {
        Count = objectsCount,
        Size = objectsSize.BytesToString()
    }.Dump();
}

static class Int64Extensions {
    public static string BytesToString(
        this long byteCount) {
        if (byteCount == 0) {
            return "0B";
        }

        var suffix = new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
        var longBytes = Math.Abs(byteCount);
        var place = Convert.ToInt32(Math.Floor(Math.Log(longBytes, 1024)));
        var number = Math.Round(longBytes / Math.Pow(1024, place), 1);

        return string.Format("{0}{1}", Math.Sign(byteCount) * number, suffix[place]);
    }
}

2

Si vous souhaitez obtenir la taille de la console AWS:

  1. Allez à S3 et cliquez sur le nom du seau
  2. Sélectionnez l'onglet "Management"

entrez la description de l'image ici

  1. Sélectionnez l' onglet Métriques

Par défaut, vous devriez voir la métrique de stockage du compartiment.


1

Je sais que c'est une question plus ancienne, mais voici un exemple de PowerShell:

Get-S3Object -BucketName <buckename> | select key, size | foreach {$A += $_.size}

$A contient la taille du compartiment, et il existe un paramètre keyname si vous souhaitez uniquement la taille d'un dossier spécifique dans un compartiment.


Commencez par exécuter la ligne Get-object..et ensuite $ $ A (pour ceux qui ne connaissent pas PowerShell)
Faiz

1

Pour vérifier toutes les tailles de seaux, essayez ce script bash

s3list=`aws s3 ls | awk  '{print $3}'`
for s3dir in $s3list
do
    echo $s3dir
    aws s3 ls "s3://$s3dir"  --recursive --human-readable --summarize | grep "Total Size"
done

Cela a très bien fonctionné.
Mike Barlow - BarDev

Capturer la sortie dans une variable juste pour pouvoir y faire une boucle est un anti-modèle inutile.
Tripleee

1

Vous pouvez utiliser s3cmd:

s3cmd du s3://Mybucket -H

ou

s3cmd du s3://Mybucket --human-readable

Il donne le nombre total d'objets et la taille du seau sous une forme très lisible.


Traverse-t-il la duliste de tous les objets ou récupère-t-il les métadonnées? Voudrais vraiment une version api de la version des rapports ou de ce qui est affiché dans la console aws ...
user67327


0

C'est également ce que fait Hanzo S3 Tools . Une fois installé, vous pouvez faire:

s3ls -s -H bucketname

Mais je pense que cela est également résumé du côté client et n'est pas récupéré via l'API AWS.


0

Par Cloudberry , il est également possible de lister la taille du compartiment, le nombre de dossiers et le nombre total de fichiers, en cliquant sur "propriétés" juste en haut du compartiment.


0

Si vous ne souhaitez pas utiliser la ligne de commande, sous Windows et OSX, il existe une application de gestion de fichiers à distance polyvalente appelée Cyberduck . Connectez-vous à S3 avec votre paire clé d'accès / clé secrète, cliquez avec le bouton droit sur le répertoire, cliquez sur Calculate.


0

J'ai écrit un script Bash, s3-du.sh, qui répertorie les fichiers dans un compartiment avec s3ls et affiche le nombre de fichiers et les tailles telles que

s3-du.sh testbucket.jonzobrist.com
149 files in bucket testbucket.jonzobrist.com
11760850920 B
11485205 KB
11216 MB
10 GB

Script complet:

#!/bin/bash

if [ “${1}” ]
then
NUM=0
COUNT=0
for N in `s3ls ${1} | awk ‘{print $11}’ | grep [0-9]`
do
NUM=`expr $NUM + $N`
((COUNT++))
done
KB=`expr ${NUM} / 1024`
MB=`expr ${NUM} / 1048576`
GB=`expr ${NUM} / 1073741824`
echo “${COUNT} files in bucket ${1}”
echo “${NUM} B”
echo “${KB} KB”
echo “${MB} MB”
echo “${GB} GB”
else
echo “Usage : ${0} s3-bucket”
exit 1
fi    

Il fait la taille du sous-répertoire, car Amazon renvoie le nom du répertoire et la taille de tout son contenu.


0

CloudWatch a maintenant un tableau de bord de service S3 par défaut qui le répertorie dans un graphique appelé "Bucket Size Bytes Average". Je pense que ce lien fonctionnera pour toute personne déjà connectée à AWS Console:


-1

La méthode suivante utilise AWS PHP SDK pour obtenir la taille totale du compartiment.

// make sure that you are using correct region (where the bucket is) to get new Amazon S3 client
$client = \Aws\S3\S3Client::factory(array('region' => $region));

// check if bucket exists
if (!$client->doesBucketExist($bucket, $accept403 = true)) {
    return false;
}
// get bucket objects
$objects = $client->getBucket(array('Bucket' => $bucket));

$total_size_bytes = 0;
$contents = $objects['Contents'];

// iterate through all contents to get total size
foreach ($contents as $key => $value) {
   $total_bytes += $value['Size'];
}
$total_size_gb = $total_size_bytes / 1024 / 1024 / 1024;

-1

Cela fonctionne pour moi ..

aws s3 ls s3://bucket/folder/ --recursive | awk '{sz+=$3} END {print sz/1024/1024 "MB"}'

3
Pouvez-vous ajouter quelques détails supplémentaires?
Pierre.Vriens

1
C'est essentiellement la même solution qu'une autre réponse postée environ un an plus tôt.
Louis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.