Получение значения blob в контейнере Azure Storage

Каков наиболее эффективный способ подсчета количества блоков в контейнере Azure Storage?

Сейчас я не могу думать ни о чем другом, кроме кода ниже:

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

Ответ 1

API не содержит метод или свойство count контейнера, поэтому вам нужно сделать что-то вроде того, что вы разместили. Однако вам нужно будет иметь дело с NextMarker, если вы превысите 5000 возвращенных элементов (или если вы укажете max # для возврата, а список превысит этот номер). Затем вы будете создавать add'l-вызовы на основе NextMarker и добавлять счетчики.

РЕДАКТИРОВАТЬ: по smarx: SDK должен позаботиться о NextMarker для вас. Вам нужно будет иметь дело с NextMarker, если вы работаете на уровне API, вызывая List Blobs через REST.

В качестве альтернативы, если вы контролируете вставки/удаления blob (например, через службу wcf), вы можете использовать область метаданных контейнера blob для хранения кэшированного количества контейнеров, которое вы вычисляете с каждой вставкой или удалением. Вам просто нужно иметь дело с записью concurrency в контейнер.

Ответ 2

Я попробовал подсчет blobs с помощью ListBlobs(), а для контейнера с примерно 400 000 элементов мне потребовалось более 5 минут.

Если у вас есть полный контроль над контейнером (т.е. вы управляете при записи), вы можете кэшировать информацию о размере в метаданных контейнера и обновлять ее каждый раз, когда элемент будет удален или вставлен. Вот фрагмент кода, который вернет счетчик блоков:

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;
}

Это, конечно, предполагает, что вы обновляете ItemCount/CountUpdateTime каждый раз при изменении контейнера. CountUpdateTime - это эвристическая защита (если контейнер был изменен без кого-то, кто обновляет CountUpdateTime, это заставит повторный подсчет), но он не является надежным.

Ответ 3

Если вы просто хотите узнать, сколько BLOB-объектов находится в контейнере без написания кода, вы можете использовать приложение Microsoft Azure Storage Explorer.

  1. Откройте нужный BlobContainer enter image description here
  2. Щелкните значок "Статистика папки" enter image description here.
  3. Наблюдайте за количеством капель в окне Активности enter image description here

Ответ 4

Пример использования PHP API и getNextMarker.

Подсчитывает общее количество капель в контейнере Azure. Это займет много времени: около 30 секунд для 100000 капель.

(предполагается, что у нас есть допустимые $connectionString и $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;

Ответ 5

Если вы не используете виртуальные каталоги, следующее будет работать, как ранее было сказано.

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

Однако приведенный выше фрагмент кода может не иметь желаемого счета, если вы используете виртуальные каталоги.

Например, если ваши капли хранятся аналогично следующему:/container/directory/filename.txt, где blob name = directory/filename.txt container.ListBlobs(). Count(); будет только подсчитывать, сколько виртуальных каталогов "/directory" у вас есть. Если вы хотите перечислить blob, содержащиеся в виртуальных каталогах, вам нужно установить useFlatBlobListing = true в вызове ListBlobs().

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

Примечание: вызов ListBlobs() с использованиемFlatBlobListing = true является гораздо более дорогим/медленным вызовом...

Ответ 6

С API-интерфейсом Python для Azure Storage это похоже на:

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