¿Cómo puedo obtener el tamaño de un cubo de Amazon S3?

289

Me gustaría graficar el tamaño (en bytes y # de elementos) de un bucket de Amazon S3 y estoy buscando una forma eficiente de obtener los datos.

Las herramientas s3cmd proporcionan una forma de obtener el tamaño total del archivo s3cmd du s3://bucket_name, pero me preocupa su capacidad de escalar, ya que parece que obtiene datos sobre cada archivo y calcula su propia suma. Dado que Amazon cobra a los usuarios en GB-Months, parece extraño que no expongan este valor directamente.

Aunque la API REST de Amazon devuelve la cantidad de elementos en un cubo, s3cmd no parece exponerlo. Podría hacerlo, s3cmd ls -r s3://bucket_name | wc -lpero eso parece un truco.

La biblioteca Ruby AWS :: S3 parecía prometedora, pero solo proporciona el número de elementos del depósito, no el tamaño total del depósito.

¿Alguien conoce alguna otra herramienta de línea de comandos o bibliotecas (prefiera Perl, PHP, Python o Ruby) que proporcionen formas de obtener estos datos?

Garret Heaton
fuente
Escribí una herramienta para analizar el tamaño del cubo: github.com/EverythingMe/ncdu-s3
omribahumi
20
Me sorprende que Amazon cobre por el espacio, pero no proporcione el tamaño total ocupado por un cubo S3 simplemente a través del panel S3.
Lucas
Para mí, la mayoría de las respuestas a continuación tomaron bastante tiempo para recuperar el tamaño del cubo, sin embargo, este script de Python fue mucho más rápido que la mayoría de las respuestas: slsmk.com/getting-the-size-of-an-s3-bucket-using -boto3-for-aws
Vaulstein

Respuestas:

169

La AWS CLI ahora admite el --queryparámetro que toma expresiones JMESPath .

Esto significa que puede sumar los valores de tamaño dados list-objectsusando sum(Contents[].Size)y contar como length(Contents[]).

Esto se puede ejecutar utilizando la AWS CLI oficial como se muestra a continuación y se introdujo en febrero de 2014

 aws s3api list-objects --bucket BUCKETNAME --output json --query "[sum(Contents[].Size), length(Contents[])]"
Christopher Hackett
fuente
21
Para cubos grandes (grandes # archivos), esto es insoportablemente lento. La utilidad Python s4cmd "du" es increíblemente rápida:s4cmd du s3://bucket-name
Brent Faust
Eso es extraño. ¿Cuál es el perfil general de su cubo (poco profundo y gordo / profundo y delgado)? Parece que s3cmddebería tener los mismos gastos generales que AWS CLI. En el código que muestra, s3cmd haga una solicitud para cada directorio en un depósito.
Christopher Hackett
22
para obtenerlo en formato legible para humanos: 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
Ahora que AWS Cloudwatch ofrece una métrica "BucketSizeBytes" por cubo, esta ya no es la solución correcta. Vea la respuesta de Toukakoukan a continuación.
cce
2
s4cmd dues maravilloso, gracias @Brent Faust! pequeña nota (para los interesados) que debe agregar -rpara obtener también los tamaños de los subdirectorios.
Greg Sadetsky
330

Esto ahora se puede hacer trivialmente solo con el cliente oficial de línea de comandos de AWS:

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

Documentación oficial

Esto también acepta prefijos de ruta si no desea contar el depósito completo:

aws s3 ls --summarize --human-readable --recursive s3://bucket-name/directory
philwills
fuente
23
Esta es la mejor y más actualizada respuesta
Tim
2
De acuerdo, esta es la mejor respuesta.
Luis Artola
25
Esto es muy lento para los cubos con muchos archivos, ya que básicamente enumera todos los objetos en el cubo antes de mostrar el resumen, y en eso no es significativamente más rápido que la respuesta de @Christopher Hackett, excepto que este es mucho más ruidoso.
Guss
Ejecutar en una instancia EC2 con la misma región del depósito para mejorar la latencia
juanmirocks
1
Esto mostrará el tamaño de TODOS los archivos individuales en el árbol de directorios. ¿Qué sucede si solo quiero el tamaño total del directorio?
Chris F
130

Consola de AWS:

A partir del 28 de julio de 2015 , puede obtener esta información a través de CloudWatch . Si desea una GUI, vaya a la consola de CloudWatch : (Elija Región>) Métricas> S3

Comando de la CLI de AWS:

Esto es mucho más rápido que algunos de los otros comandos publicados aquí, ya que no consulta el tamaño de cada archivo individualmente para calcular la suma.

 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

Importante : debe especificar StorageType y BucketName en el argumento de dimensiones; de lo contrario, no obtendrá resultados. Todo lo que tiene que cambiar es el --start-date, --end-timey Value=toukakoukan.com.


Aquí hay un script bash que puede usar para evitar tener que especificar --start-datey --end-timemanualmente.

#!/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
Sam Martin
fuente
25
O en la consola de CloudWatch : (Elija Región>) Métricas> S3
Halil Özgür
3
Esta es, con mucho, la solución más fácil y rápida. Lamentablemente, la respuesta sigue siendo solo en el cuarto lugar.
luk2302
Esto funcionó para mi cubo con más de 10 millones de objetos. Pero el script bash no devolvió nada, tuvo que ir a la GUI).
Petah
1
También debe tenerse en cuenta que también tendrá que cambiar la región
majikman
mayo 2018: los errores de script conInvalid value ('1525354418') for param timestamp:StartTime of type timestamp
anneb
106

s3cmd puede hacer esto:

s3cmd du s3://bucket-name

Stefan Ticu
fuente
Gracias. Aquí hay un momento. En un depósito que contiene un sistema de archivos deduplicado s3ql con aproximadamente un millón de archivos que utilizan aproximadamente 33 GB de datos no duplicados y aproximadamente 93000 objetos s3, s3cmd du tardó aproximadamente 4 minutos en calcular la respuesta. Tengo curiosidad por saber cómo se compara con otros enfoques como el php descrito en otro lugar aquí.
nealmcb
1
Es lento porque la llamada API S3 ListObjects devuelve objetos en páginas de 1000 objetos. Como la E / S es, con mucho, el factor limitante, creo que cualquier solución será relativamente lenta sobre 93000 objetos.
David Snabel-Caunt
11
s4cmd también puede hacer lo mismo, con el beneficio adicional de multiprocesar las solicitudes a la API de S3 para calcular el resultado más rápido. La herramienta no se ha actualizado recientemente, pero el transeúnte de Internet puede encontrarla útil.
Nick Chammas
s4cmd solo devuelve 0 para mí y devuelve BotoClientError: Bucket names cannot contain upper-case characters when using either the sub-domain or virtual hosting calling format.para cubos con caracteres en mayúscula.
Lakitu
22

Si descarga un informe de uso , puede representar gráficamente los valores diarios del TimedStorage-ByteHrscampo.

Si desea ese número en GiB, simplemente divídalo entre 1024 * 1024 * 1024 * 24(eso es GiB-horas para un ciclo de 24 horas). Si desea el número en bytes, simplemente divídalo entre 24 y grafique.

Christopher Schultz
fuente
19

Usando las herramientas oficiales de línea de comandos de AWS s3:

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

Este es un comando mejor, simplemente agregue los siguientes 3 parámetros --summarize --human-readable --recursivedespués aws s3 ls. --summarizeaunque no es obligatorio, le da un buen toque al tamaño total.

aws s3 ls s3://bucket/folder --summarize --human-readable --recursive
dyltini
fuente
1
Proporcione el enlace a donde Amazon realmente dice esto, por favor. No puedo encontrarlo
lobi
1
docs.aws.amazon.com/cli/latest/reference/s3/ls.html es un mejor enlace
Ian Bamforth
44
Esta respuesta funcionó mejor y más rápido para mí.
Miro
2
¡La mejor y más rápida respuesta!
PlagTag
11

s4cmd es la forma más rápida que he encontrado (una utilidad de línea de comandos escrita en Python):

pip install s4cmd

Ahora para calcular el tamaño completo del cubo con múltiples hilos:

s4cmd du -r s3://bucket-name
Brent Fausto
fuente
66
No, s4cmd du s3://123123drinkno devolverá simplemente el tamaño del cubo. Para obtener el tamaño del cubo, agregue el recursivo -r, de esta manera: s4cmd du -r s3: // 123123drink
George Chalhoub
1
Sí, buen punto @BukLau (agregado -ral ejemplo anterior para evitar confusiones cuando las personas usan carpetas simuladas en S3).
Brent Faust
6

He utilizado la API S3 REST / Curl enumerados anteriormente en este hilo y hice esto:

<?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';
?>
Vic
fuente
6

Puede usar la utilidad s3cmd, por ejemplo:

s3cmd du -H s3://Mybucket
97G      s3://Mybucket/
usuario319660
fuente
5

Entonces, al navegar por la API y reproducir algunas consultas, S3 producirá todo el contenido de un depósito en una solicitud y no es necesario que descienda a los directorios. Los resultados solo requieren sumar a través de los diversos elementos XML, y no llamadas repetidas. No tengo un cubo de muestra que tenga miles de artículos, así que no sé qué tan bien se escalará, pero parece razonablemente simple.

Jim Zajkowski
fuente
Esta parece ser la mejor opción. Actualizaré esta publicación en el futuro si se escala mal y necesito hacer otra cosa. La biblioteca que terminó proporcionando un fácil acceso a los resultados de API sin procesar fue esta PHP: undesigned.org.za/2007/10/22/amazon-s3-php-class
Garret Heaton el
¿No se limita solo a los primeros 1000 artículos?
Charlie Schliesser
4

... Un poco tarde, pero la mejor manera que encontré fue usando los informes en el portal de AWS. Hice una clase de PHP para descargar y analizar los informes. Con él, puede obtener el número total de objetos para cada depósito, el tamaño total en GB o horas de byte y más.

Compruébalo y avísame si fue útil

AmazonTools


fuente
Esta es una solución interesante, aunque un poco hack. Me preocupa que se rompa si / cuando Amazon cambia su sitio, pero es posible que tenga que probar esto una vez que tenga suficientes objetos para que la otra manera se vuelva demasiado lenta. Otro beneficio de este enfoque es que no se le cobra por ninguna llamada API.
Garret Heaton
. . . es una suposición, pero si Amazon cambia el aspecto de su sitio, dudo que cambien mucho el back-end, lo que significa que las consultas GET y POST actuales deberían funcionar. Mantendré la clase en caso de que se rompa de todos modos, ya que la uso a menudo.
3

Recomiendo usar el Informe de uso S3 para grandes depósitos , consulte mi Cómo para obtenerlo. Básicamente, debe descargar el Informe de uso para el servicio S3 durante el último día con Almacenamiento temporizado - Byte Hrs y analizarlo para obtener el uso del disco.

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

La documentación de AWS le dice cómo hacerlo:

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

Este es el resultado que obtienes:

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
奉 太郎 折 木
fuente
2

Para un enfoque realmente de baja tecnología: use un cliente S3 que pueda calcular el tamaño por usted. Estoy usando la transmisión de pánico, haga clic en un cubo, haga "Obtener información" y haga clic en el botón "Calcular". No estoy seguro de cuán rápido o preciso es en relación con otros métodos, pero parece devolver el tamaño que esperaba que fuera.

zmippie
fuente
2

Como hay tantas respuestas, pensé que me ayudaría con las mías. Escribí mi implementación en C # usando LINQPad. Copie, pegue e ingrese la clave de acceso, la clave secreta, el punto final de la región y el nombre del depósito que desea consultar. Además, asegúrese de agregar el paquete nuget AWSSDK.

Probando contra uno de mis cubos, me dio una cuenta de 128075 y un tamaño de 70.6GB. Sé que es 99.9999% de precisión, así que estoy bien con el resultado.

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]);
    }
}
Gup3rSuR4c
fuente
2

Si desea obtener el tamaño de la consola de AWS:

  1. Vaya a S3 y haga clic en el nombre del cubo
  2. Seleccione la pestaña "Administración"

ingrese la descripción de la imagen aquí

  1. Seleccione la pestaña Métricas

De forma predeterminada, debería ver Métrica de almacenamiento del depósito

Hooman Bahreini
fuente
1

Sé que esta es una pregunta anterior, pero aquí hay un ejemplo de PowerShell:

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

$A contiene el tamaño del depósito, y hay un parámetro de nombre de clave si solo desea el tamaño de una carpeta específica en un depósito.

DCJeff
fuente
Primero ejecute Get-object..line y luego ejecute $ A (para aquellos que no estén familiarizados con PowerShell)
Faiz
1

Para verificar el tamaño de todos los cubos, pruebe este 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
Giulio Roggero
fuente
Esto funcionó muy bien.
Mike Barlow - BarDev
Capturar la salida en una variable solo para que puedas recorrerlo es un antipatrón derrochador.
tripleee
1

Puedes usar s3cmd:

s3cmd du s3://Mybucket -H

o

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

Da los objetos totales y el tamaño del cubo en una forma muy legible.

bpathak
fuente
¿ duTraverse enumera todos los objetos o recupera los metadatos? Realmente me gustaría una versión api de la versión de informes o lo que se muestra en la consola aws ...
user67327
0

Hola, hay una herramienta de búsqueda de metadatos para AWS S3 en https://s3search.p3-labs.com/ . Esta herramienta proporciona estadísticas sobre objetos en un cubo con búsqueda en metadatos.

Pyth
fuente
0

También Hanzo S3 Tools hace esto. Una vez instalado, puede hacer:

s3ls -s -H bucketname

Pero creo que esto también se resume en el lado del cliente y no se recupera a través de la API de AWS.

Ville
fuente
0

Mediante el programa Cloudberry también es posible enumerar el tamaño del depósito, la cantidad de carpetas y el total de archivos, haciendo clic en "propiedades" en la parte superior del depósito.

KiKo
fuente
0

Si no desea utilizar la línea de comandos, en Windows y OSX, hay una aplicación de administración remota de archivos de propósito general llamada Cyberduck . Inicie sesión en S3 con su par de claves de acceso / secreto, haga clic derecho en el directorio, haga clic Calculate.

jpillora
fuente
0

Escribí un script Bash, s3-du.sh que enumerará los archivos en un cubo con s3ls, e imprimirá el recuento de archivos y tamaños como

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

Guión completo:

#!/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    

Lo hace el tamaño del subdirectorio, ya que Amazon devuelve el nombre del directorio y el tamaño de todos sus contenidos.

Jon Zobrist
fuente
0

CloudWatch tiene ahora un panel de servicio de S3 predeterminado que lo enumera en un gráfico llamado "Promedio de bytes de tamaño de depósito". Creo que este enlace funcionará para cualquier persona que ya haya iniciado sesión en la consola de AWS:

flickerfly
fuente
-1

La siguiente forma utiliza AWS PHP SDK para obtener el tamaño total del depósito.

// 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;
Shriganesh Shintre
fuente
-1

Esto funciona para mi ...

aws s3 ls s3://bucket/folder/ --recursive | awk '{sz+=$3} END {print sz/1024/1024 "MB"}'
GrantO
fuente
3
¿Puedes agregar algunos detalles más?
Pierre.Vriens
1
Esta es esencialmente la misma solución que otra respuesta publicada aproximadamente un año antes.
Louis