Получение значения 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.
- Откройте нужный BlobContainer
![enter image description here]()
- Щелкните значок "Статистика папки"
. - Наблюдайте за количеством капель в окне Активности
![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