Azure Storageコンテナー内のBLOBの数をカウントするための最も効率的な方法は何ですか?
今のところ、以下のコード以外の方法は考えられません。
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();
APIにはコンテナカウントメソッドまたはプロパティが含まれていないため、投稿したようなことを行う必要があります。ただし、返されるアイテムが5,000を超える場合(または、返される最大数を指定してリストがその数を超える場合)は、NextMarkerを処理する必要があります。次に、NextMarkerに基づいて追加の呼び出しを行い、カウントを追加します。
編集:smarxごと:SDKがNextMarkerを処理する必要があります。 APIレベルで作業している場合は、RESTを介して List Blobs を呼び出して、NextMarkerを処理する必要があります。
または、blobの挿入/削除を(たとえば、wcfサービスを介して)制御している場合は、blobコンテナーのメタデータ領域を使用して、挿入または削除ごとに計算するキャッシュコンテナー数を格納できます。コンテナへの書き込みの同時実行性を処理する必要があります。
ListBlobs()を使用してblobをカウントしてみましたが、約40万個のアイテムが含まれるコンテナーの場合、5分以上かかりました。
コンテナーを完全に制御できる場合(つまり、書き込みが発生するタイミングを制御できる場合)、サイズ情報をコンテナーメタデータにキャッシュし、アイテムが削除または挿入されるたびに更新できます。コンテナのBLOBカウントを返すコードは次のとおりです。
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を更新せずにコンテナーが変更された場合、これにより再カウントが強制されます)が、信頼性はありません。
コードを記述せずにコンテナー内のblobの数を知りたいだけの場合は、 Microsoft Azure Storage Explorerアプリケーション を使用できます。
PHP APIとgetNextMarkerを使用した例。
Azureコンテナー内のBLOBの総数をカウントします。時間がかかります。100000ブロブの場合は約30秒です。
(有効な$ 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;
仮想ディレクトリを使用していない場合、以下は以前に回答したとおりに機能します。
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs().Count();
ただし、仮想ディレクトリを使用している場合、上記のコードスニペットでは目的の数が得られない可能性があります。
たとえば、blobが次のように保存されている場合:/container/directory/filename.txtここで、blob name = directory/filename.txt the container.ListBlobs()。Count();あなたが持っている「/ directory」仮想ディレクトリの数だけを数えます。仮想ディレクトリに含まれるblobを一覧表示する場合は、ListBlobs()呼び出しでuseFlatBlobListing = trueを設定する必要があります。
CloudBlobContainer container = GetContainer("mycontainer");
var count = container.ListBlobs(null, true).Count();
注:useFlatBlobListing = trueを指定したListBlobs()呼び出しは、はるかにコストがかかる/遅い呼び出しです...
Azure StorageのPython APIを使用すると、次のようになります。
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