Calculate the total billing size of a blob container
Ez a szkript kiszámítja egy tároló méretét az Azure Blob Storage-ban a számlázási költségek becslése céljából. A szkript a tárolóban lévő blobok méretét összegozza.
Fontos
Előfordulhat, hogy a cikkben megadott mintaszkript nem számítja ki pontosan a blob pillanatképeinek számlázási méretét.
Ehhez a mintához az Azure PowerShell szükséges. A verzió azonosításához futtassa a következőt: Get-Module -ListAvailable Az
.
Ha telepíteni vagy frissíteni szeretne, olvassa el az Azure PowerShell-modul telepítését ismertető cikket.
Futtassa az Csatlakozás-AzAccount parancsmagot az Azure-hoz való csatlakozáshoz.
If you don't have an Azure subscription, create an Azure free account before you begin.
Megjegyzés:
Ez a PowerShell-szkript kiszámítja a tároló méretét számlázási célokra. Ha más célokra számítja ki a tároló méretét, tekintse meg a Blob Storage-tároló teljes méretének kiszámítását egy egyszerűbb, becslést biztosító szkripthez.
A blobtároló méretének meghatározása
A blobtároló teljes mérete magában foglalja a tároló méretét és a tároló alatti összes blob méretét.
A következő szakaszok a blobtárolók és blobok tárolási kapacitásának kiszámítását ismertetik. A következő szakaszban a Len(X) a sztringben szereplő karakterek számát jelenti.
Blobtárolók
Az alábbi számítás bemutatja, hogyan becsülhető meg a blobtárolónként felhasznált tárterület mennyisége:
48 bytes + Len(ContainerName) * 2 bytes +
For-Each Metadata[3 bytes + Len(MetadataName) + Len(Value)] +
For-Each Signed Identifier[512 bytes]
Az alábbiakban a részletezés szerepel:
Az egyes tárolók 48 bájtnyi többletterhelése tartalmazza az utolsó módosítás időpontját, az engedélyeket, a nyilvános Gépház és néhány rendszer metaadatait.
A tároló neve Unicode formátumban van tárolva, ezért vegye fel a karakterek számát, és szorozza meg kettővel.
A blobtároló metaadatainak minden egyes blokkjához tároljuk a név (ASCII) hosszát és a sztringérték hosszát.
Az aláírt azonosítónkénti 512 bájt tartalmazza az aláírt azonosító nevét, a kezdési időpontot, a lejárati időt és az engedélyeket.
Blobok
Az alábbi számítások bemutatják, hogyan becsülhető meg a blobonként felhasznált tárterület mennyisége.
Blokkblob (alapblob vagy pillanatkép):
124 bytes + Len(BlobName) * 2 bytes + For-Each Metadata[3 bytes + Len(MetadataName) + Len(Value)] + 8 bytes + number of committed and uncommitted blocks * Block ID Size in bytes + SizeInBytes(data in unique committed data blocks stored) + SizeInBytes(data in uncommitted data blocks)
Lapblob (alapblob vagy pillanatkép):
124 bytes + Len(BlobName) * 2 bytes + For-Each Metadata[3 bytes + Len(MetadataName) + Len(Value)] + number of nonconsecutive page ranges with data * 12 bytes + SizeInBytes(data in unique pages stored)
Az alábbiakban a részletezés szerepel:
124 bájtnyi többletterhelés a blob esetében, amely a következőket tartalmazza:
- Utolsó módosítás időpontja
- Méret
- Gyorsítótár-vezérlés
- Content-Type
- Tartalomnyelv
- Tartalomkódolás
- Content-MD5
- Permissions
- Pillanatkép adatai
- Bérleti
- Néhány rendszer metaadatai
A blob neve Unicode formátumban van tárolva, ezért vegye fel a karakterek számát, és szorozza meg kettővel.
Minden tárolt metaadat-blokkhoz adja hozzá a név hosszát (ASCII-ként tárolva), valamint a sztringérték hosszát.
Blokkblobok esetén:
8 bájt a blokklistához.
A blokkok száma bájtban megadva megszorozza a blokkazonosító méretét.
Az adatok mérete az összes véglegesített és nem véglegesített blokkban.
Megjegyzés:
Pillanatképek használata esetén ez a méret csak az alap vagy a pillanatkép-blob egyedi adatait tartalmazza. Ha a nem véglegesített blokkokat egy hét után nem használják, a rendszer szemetet gyűjt. Ezután nem számítanak bele a számlázásba.
Lapblobok esetén:
A nem biztonságos oldaltartományok száma 12 bájt adatidővel. Ez a GetPageRanges API meghívásakor megjelenő egyedi oldaltartományok száma.
Az adatok mérete bájtban az összes tárolt oldalhoz.
Megjegyzés:
Pillanatképek használata esetén ez a méret csak az alapblob vagy a megszámlált pillanatkép-blob egyedi lapjait tartalmazza.
Példaszkript
# this script will show how to get the total size of the blobs in a container
# before running this, you need to create a storage account, create a container,
# and upload some blobs into the container
# note: this retrieves all of the blobs in the container in one command.
# connect Azure with Login-AzAccount before you run the script.
# requests sent as part of this tool will incur transactional costs.
# command line usage: script.ps1 -ResourceGroup {YourResourceGroupName} -StorageAccountName {YourAccountName} -ContainerName {YourContainerName}
#
param(
[Parameter(Mandatory=$true)]
[string]$ResourceGroup,
[Parameter(Mandatory=$true)]
[string]$StorageAccountName,
[Parameter(Mandatory=$true)]
[string]$ContainerName
)
#Set-StrictMode will cause Get-AzStorageBlob returns result in different data types when there is only one blob
#Set-StrictMode -Version 2
$VerbosePreference = "Continue"
if((Get-Module -ListAvailable Az.Storage) -eq $null)
{
throw "Azure Powershell not found! Please install from https://docs.microsoft.com/en-us/powershell/azure/install-Az-ps"
}
# function Retry-OnRequest
function Retry-OnRequest
{
param(
[Parameter(Mandatory=$true)]
$Action)
# It could encounter various of temporary errors, like network errors, or storage server busy errors.
# Should retry the request on transient errors
# Retry on storage server timeout errors
$clientTimeOut = New-TimeSpan -Minutes 15
$retryPolicy = New-Object -TypeName Microsoft.Azure.Storage.RetryPolicies.ExponentialRetry -ArgumentList @($clientTimeOut, 10)
$requestOption = @{}
$requestOption.RetryPolicy = $retryPolicy
# Retry on temporary network errors
$shouldRetryOnException = $false
$maxRetryCountOnException = 3
do
{
try
{
return $Action.Invoke($requestOption)
}
catch
{
if ($_.Exception.InnerException -ne $null -And $_.Exception.InnerException.GetType() -Eq [System.TimeoutException] -And $maxRetryCountOnException -gt 0)
{
$shouldRetryOnException = $true
$maxRetryCountOnException--
}
else
{
$shouldRetryOnException = $false
throw
}
}
}
while ($shouldRetryOnException)
}
# function Get-BlobBytes
function Get-BlobBytes
{
param(
[Parameter(Mandatory=$true)]
$Blob,
[Parameter(Mandatory=$false)]
[bool]$IsPremiumAccount = $false)
# Base + blobname
$blobSizeInBytes = 124 + $Blob.Name.Length * 2
# Get size of metadata
$metadataEnumerator=$Blob.ICloudBlob.Metadata.GetEnumerator()
while($metadataEnumerator.MoveNext())
{
$blobSizeInBytes += 3 + $metadataEnumerator.Current.Key.Length + $metadataEnumerator.Current.Value.Length
}
if (!$IsPremiumAccount)
{
if($Blob.BlobType -eq [Microsoft.Azure.Storage.Blob.BlobType]::BlockBlob)
{
$blobSizeInBytes += 8
# Default is Microsoft.Azure.Storage.Blob.BlockListingFilter.Committed. Need All
$action = { param($requestOption) return $Blob.ICloudBlob.DownloadBlockList([Microsoft.Azure.Storage.Blob.BlockListingFilter]::All, $null, $requestOption) }
$blocks=Retry-OnRequest $action
if ($null -eq $blocks)
{
$blobSizeInBytes += $Blob.ICloudBlob.Properties.Length
}
else
{
$blocks | ForEach-Object { $blobSizeInBytes += $_.Length + $_.Name.Length }
}
}
elseif($Blob.BlobType -eq [Microsoft.Azure.Storage.Blob.BlobType]::PageBlob)
{
# It could cause server time out issue when trying to get page ranges of highly fragmented page blob
# Get page ranges in segment can mitigate chance of meeting such kind of server time out issue
# See https://blogs.msdn.microsoft.com/windowsazurestorage/2012/03/26/getting-the-page-ranges-of-a-large-page-blob-in-segments/ for details.
$pageRangesSegSize = 148 * 1024 * 1024L
$totalSize = $Blob.ICloudBlob.Properties.Length
$pageRangeSegOffset = 0
$pageRangesTemp = New-Object System.Collections.ArrayList
while ($pageRangeSegOffset -lt $totalSize)
{
$action = {param($requestOption) return $Blob.ICloudBlob.GetPageRanges($pageRangeSegOffset, $pageRangesSegSize, $null, $requestOption) }
Retry-OnRequest $action | ForEach-Object { $pageRangesTemp.Add($_) } | Out-Null
$pageRangeSegOffset += $pageRangesSegSize
}
$pageRanges = New-Object System.Collections.ArrayList
foreach ($pageRange in $pageRangesTemp)
{
if($lastRange -eq $Null)
{
$lastRange = New-Object PageRange
$lastRange.StartOffset = $pageRange.StartOffset
$lastRange.EndOffset = $pageRange.EndOffset
}
else
{
if (($lastRange.EndOffset + 1) -eq $pageRange.StartOffset)
{
$lastRange.EndOffset = $pageRange.EndOffset
}
else
{
$pageRanges.Add($lastRange) | Out-Null
$lastRange = New-Object PageRange
$lastRange.StartOffset = $pageRange.StartOffset
$lastRange.EndOffset = $pageRange.EndOffset
}
}
}
$pageRanges.Add($lastRange) | Out-Null
$pageRanges | ForEach-Object {
$blobSizeInBytes += 12 + $_.EndOffset - $_.StartOffset
}
}
else
{
$blobSizeInBytes += $Blob.ICloudBlob.Properties.Length
}
return $blobSizeInBytes
}
else
{
$blobSizeInBytes += $Blob.ICloudBlob.Properties.Length
}
return $blobSizeInBytes
}
# function Get-ContainerBytes
function Get-ContainerBytes
{
param(
[Parameter(Mandatory=$true)]
[Microsoft.Azure.Storage.Blob.CloudBlobContainer]$Container,
[Parameter(Mandatory=$false)]
[bool]$IsPremiumAccount = $false)
# Base + name of container
$containerSizeInBytes = 48 + $Container.Name.Length*2
# Get size of metadata
$metadataEnumerator = $Container.Metadata.GetEnumerator()
while($metadataEnumerator.MoveNext())
{
$containerSizeInBytes += 3 + $metadataEnumerator.Current.Key.Length + $metadataEnumerator.Current.Value.Length
}
# Get size for SharedAccessPolicies
$containerSizeInBytes += $Container.GetPermissions().SharedAccessPolicies.Count * 512
# Calculate size of all blobs.
$blobCount = 0
$Token = $Null
$MaxReturn = 5000
do {
$Blobs = Get-AzStorageBlob -Context $storageContext -Container $Container.Name -MaxCount $MaxReturn -ContinuationToken $Token
if($Blobs -eq $Null) { break }
#Set-StrictMode will cause Get-AzStorageBlob returns result in different data types when there is only one blob
if($Blobs.GetType().Name -eq "AzureStorageBlob")
{
$Token = $Null
}
else
{
$Token = $Blobs[$Blobs.Count - 1].ContinuationToken;
}
$Blobs | ForEach-Object {
$blobSize = Get-BlobBytes $_ $IsPremiumAccount
$containerSizeInBytes += $blobSize
$blobCount++
if(($blobCount % 1000) -eq 0)
{
Write-Verbose("Counting {0} Sizing {1} " -f $blobCount, $containerSizeInBytes)
}
}
}
While ($Token -ne $Null)
return @{ "containerSize" = $containerSizeInBytes; "blobCount" = $blobCount }
}
#Login-AzAccount
$storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccountName -ErrorAction SilentlyContinue
if($storageAccount -eq $null)
{
throw "The storage account specified does not exist in this subscription."
}
$storageContext = $storageAccount.Context
if (-not ([System.Management.Automation.PSTypeName]'PageRange').Type)
{
$Source = "
public class PageRange
{
public long StartOffset;
public long EndOffset;
}"
Add-Type -TypeDefinition $Source
}
$containers = New-Object System.Collections.ArrayList
if($ContainerName.Length -ne 0)
{
$container = Get-AzStorageContainer -Context $storageContext -Name $ContainerName -ErrorAction SilentlyContinue |
ForEach-Object { $containers.Add($_) } | Out-Null
}
else
{
Get-AzStorageContainer -Context $storageContext | ForEach-Object { $containers.Add($_) } | Out-Null
}
$sizeInBytes = 0
$IsPremiumAccount = ($storageAccount.Sku.Tier -eq "Premium")
if($containers.Count -gt 0)
{
$containers | ForEach-Object {
Write-Output("Calculating container {0} ..." -f $_.CloudBlobContainer.Name)
$result = Get-ContainerBytes $_.CloudBlobContainer $IsPremiumAccount
$sizeInBytes += $result.containerSize
Write-Output("Container '{0}' with {1} blobs has a sizeof {2:F2} MB." -f $_.CloudBlobContainer.Name,$result.blobCount,($result.containerSize/1MB))
}
}
else
{
Write-Warning "No containers found to process in storage account '$StorageAccountName'."
}
Következő lépések
A Blob Storage-tároló teljes méretének kiszámítása egy egyszerű szkripthez, amely a tároló méretének becslését adja meg.
További információ az Azure Storage számlázásáról: A Windows Azure Storage számlázásának ismertetése.
Az Azure PowerShell-modullal kapcsolatos további információkért tekintse meg az Azure PowerShell dokumentációját.
Az Azure Storage PowerShell-mintáiban további PowerShell-példaszkripteket is találhat.