2011-07-28 18 views

Respuesta

10

La API no contiene un método de conteo contenedor o propiedad, por lo que había necesidad de hacer algo parecido a lo publicaste Sin embargo, deberá tratar con NextMarker si supera los 5.000 elementos devueltos (o si especifica max # para devolver y la lista excede ese número). Luego, realizará llamadas adicionales basadas en NextMarker y agregará los conteos.

EDITAR: Por smarx: el SDK debe encargarse de NextMarker por usted. Tendrá que tratar con NextMarker si está trabajando en el nivel de la API, llamando al List Blobs a través de REST.

Alternativamente, si está controlando las inserciones/eliminaciones blob (a través de un servicio wcf, por ejemplo), puede usar el área de metadatos del contenedor blob para almacenar un recuento de contenedor en caché que calcule con cada inserción o eliminación. Solo tendrá que lidiar con la concurrencia de escritura en el contenedor.

+0

Estoy bastante seguro de ListBlobs seguirán automáticamente los tokens de continuación. (Así que no creo que deba hacer nada explícito con NextMarker para que esto funcione). – smarx

+0

¡Vaya! Estoy gastando demasiado tiempo en el nivel de API, parece ... :) –

8

Intenté contar blobs utilizando ListBlobs() y para un contenedor con aproximadamente 400,000 artículos, me llevó más de 5 minutos.

Si tiene control total sobre el contenedor (es decir, controla cuándo se producen las escrituras), podría almacenar en caché la información de tamaño en los metadatos del contenedor y actualizarla cada vez que se elimine o inserte un elemento. Aquí es una pieza de código que devolvería el recuento de burbuja envase:

static int CountBlobs(string storageAccount, string containerId) 
{ 
    CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(storageAccount); 
    CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient(); 
    CloudBlobContainer cloudBlobContainer = blobClient.GetContainerReference(containerId); 

    cloudBlobContainer.FetchAttributes(); 

    string count = cloudBlobContainer.Metadata["ItemCount"]; 
    string countUpdateTime = cloudBlobContainer.Metadata["CountUpdateTime"]; 

    bool recountNeeded = false; 

    if (String.IsNullOrEmpty(count) || String.IsNullOrEmpty(countUpdateTime)) 
    { 
     recountNeeded = true; 
    } 
    else 
    { 
     DateTime dateTime = new DateTime(long.Parse(countUpdateTime)); 

     // Are we close to the last modified time? 
     if (Math.Abs(dateTime.Subtract(cloudBlobContainer.Properties.LastModifiedUtc).TotalSeconds) > 5) { 
      recountNeeded = true; 
     } 
    } 

    int blobCount; 
    if (recountNeeded) 
    { 
     blobCount = 0; 
     BlobRequestOptions options = new BlobRequestOptions(); 
     options.BlobListingDetails = BlobListingDetails.Metadata; 

     foreach (IListBlobItem item in cloudBlobContainer.ListBlobs(options)) 
     { 
      blobCount++; 
     } 

     cloudBlobContainer.Metadata.Set("ItemCount", blobCount.ToString()); 
     cloudBlobContainer.Metadata.Set("CountUpdateTime", DateTime.Now.Ticks.ToString()); 
     cloudBlobContainer.SetMetadata(); 
    } 
    else 
    { 
     blobCount = int.Parse(count); 
    } 

    return blobCount; 
} 

Esto, por supuesto, asume que actualice ItemCount/CountUpdateTime cada vez que se modifica el contenedor. CountUpdateTime es una protección heurística (si el contenedor se modificó sin que alguien actualice CountUpdateTime, se forzará un recuento) pero no es confiable.

+1

Si este es el enfoque, se usa en un sistema donde las llamadas se pueden ejecutar en paralelo, p. una API web luego se encuentra con una condición de carrera en torno a la última actualización de valores. Otro enfoque podría ser almacenar los nombres de archivo en una tabla de Almacenamiento de Azure como un índice. –

+0

Ok, tal vez no tablas de almacenamiento porque no tiene un método de recuento nativo, solo "obtener todos los elementos". Tal vez una tabla DocumentDB o una tabla SQL relativamente más cara. –

+0

O, dado que los blobs y las entidades de tabla tienen ETags para detectar problemas de simultaneidad, puede tener 1 blob/entidad con el recuento o la lista de nombres de archivo. –

1

Ejemplo que utiliza PHP API y getNextMarker.

Cuenta el número total de blobs en un contenedor de Azure. Lleva mucho tiempo: unos 30 segundos para 100000 blobs.

(asume que tenemos un $ connectionString válida y un $ CONTAINER_NAME)

$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString); 
$opts = new ListBlobsOptions(); 
$nblobs = 0; 

while($cont) { 

    $blob_list = $blobRestProxy->listBlobs($container_name, $opts);  

    $nblobs += count($blob_list->getBlobs()); 

    $nextMarker = $blob_list->getNextMarker(); 

    if (!$nextMarker || strlen($nextMarker) == 0) $cont = false; 
    else $opts->setMarker($nextMarker); 
} 
echo $nblobs; 
0

Con Python API de Azure Storage es como:

from azure.storage import * 
blob_service = BlobService(account_name='myaccount', account_key='mykey') 
blobs = blob_service.list_blobs('mycontainer') 
len(blobs) #returns the number of blob in a container 
+2

Esto no es correcto. 'list_blobs' tiene un límite superior de 5,000 – Shane

2

Si no está utilizando directorios virtuales , lo siguiente funcionará como se respondió previamente.

CloudBlobContainer container = GetContainer("mycontainer"); 
var count = container.ListBlobs().Count(); 

Sin embargo, el fragmento de código anterior puede no tener el conteo deseado si está utilizando directorios virtuales.

Por ejemplo, si sus blobs se almacenan de forma similar a lo siguiente: /container/directory/filename.txt donde el nombre de blob = directorio/nombre de archivo.txt contenedor.ListBlobs(). Count(); solo contará cuántos directorios virtuales "/ directorio" tiene. Si desea listar blobs contenidos en directorios virtuales, debe establecer useFlatBlobListing = true en la llamada a ListBlobs().

CloudBlobContainer container = GetContainer("mycontainer"); 
var count = container.ListBlobs(null, true).Count(); 

Nota: los ListBlobs() con useFlatBlobListing = true es una llamada mucho más caro/lento ...

1

Si lo que desea es saber cuántos son gotas en un recipiente sin necesidad de escribir código que puede usar el Azure Storage Explorer application.

  1. Abra la BlobContainer deseada enter image description here
  2. Haga clic en el icono de estadísticas de la carpeta enter image description here
  3. Observe el recuento de manchas en la ventana Actividades enter image description here
Cuestiones relacionadas