上傳 blob 或區塊內容失敗,Azure Blob 儲存體
本文討論如何使用 Microsoft Azure Blob 儲存體 搭配雲端應用程式來上傳 Blob 或區塊內容時,可能發生的失敗。
必要條件
- 下列其中一個記憶體服務的記憶體帳戶:
- Azure 儲存體 SDK
- Azure 儲存體總管
- PowerShell
徵兆
您會收到下列其中一個錯誤訊息。
錯誤碼 | 錯誤訊息 |
---|---|
BlockCountExceedsLimit |
「未認可的區塊計數不能超過100,000個區塊的最大限制。 |
InvalidBlobOrBlock |
「指定的 Blob 或區塊內容無效。」 |
InvalidBlock 或 InvalidBlockList |
「指定的區塊清單無效。」 |
原因 1:Put Block 呼叫中指定的區塊長度無效
在 Put Block URI 要求中指定的 區塊 長度無效,原因如下:
應用程式或用戶端指定不支援的區塊大小。
區塊的大小大於允許的區塊大小上限。 若要尋找不同 Blob 服務 REST API 版本的區塊大小限制,請參閱參考文章的<
備註>一節。 當您嘗試使用多個應用程式上傳數據區塊時,有未認可的區塊具有不一致的區塊長度。 這種情況發生的原因是不同的應用程式使用不同的長度來上傳數據,或因為先前的上傳失敗。
Blob 有太多未認可的區塊,因為先前的上傳作業已取消。 與 Blob 相關聯的未認可區塊數目上限為 100,000。
實作其中一個解決方案來移除未認可的區塊。
解決方案 1:等候垃圾收集以挑選未認可的數據
等候七天,讓未認可的封鎖清單由垃圾收集清除。
解決方案 2:使用虛擬 Blob 進行數據傳輸
使用 Azure 儲存體 SDK,透過虛擬 Blob 傳輸數據。 若要這樣做,請遵循下列步驟:
建立具有相同 Blob 名稱且位於相同容器中的虛擬 Blob。 此 Blob 的長度可以是零。
使用解除封鎖的傳輸來傳輸 Blob。
解決方案 3:使用 Azure 儲存體 SDK 認可未認可的封鎖清單
使用 Azure 儲存體 SDK 來認可未認可的區塊清單並清除 Blob。 若要這樣做,請遵循下列步驟:
下列 PowerShell 函式是如何擷取未認可的區塊清單,然後加以刪除的範例。 函式需要下列參數。
參數名稱 | 描述 |
---|---|
-StorageAccountName |
儲存體帳戶的名稱。 |
-SharedAccessSignature |
使用 URI 參數 <ss=b;srt=sco;sp=rwldc> 的共用存取簽章 (SAS) 令牌。 這些參數會在建構帳戶 SAS URI 中說明。 |
-ContainerName |
記憶體容器的名稱。 |
-BlobName |
Blob 的名稱。 |
[CmdletBinding()] Param(
[Parameter(Mandatory=$true, Position=1)] [string] $StorageAccountName,
[Parameter(Mandatory=$True, Position=1)] [string] $SharedAccessSignature,
[Parameter(Mandatory=$True, Position=1)] [string] $ContainerName,
[Parameter(Mandatory=$True, Position=1)] [string] $BlobName
)
# Build the URI strings in the REST API for GET and DELETE.
$uriDelete = (
"https://$StorageAccountName.blob.core.windows.net/",
"$ContainerName",
"/",
"$BlobName",
"$SharedAccessSignature"
) -Join ""
$uriGet = (
"$uriDelete",
"&comp=blocklist",
"&blocklisttype=uncommitted"
) -Join ""
Write-Host "The Delete URI is $uriDelete."
Write-Host "The Get URI is $uriGet."
# Make a REST API call to get the uncommitted block list.
$listFileURI = Invoke-WebRequest -Uri $uriGet -Method Get
$FileSystemName = $listFileURI.Content
$String = $FileSystemName -replace '' , ''
$String |
Select-Xml –XPath "/BlockList/UncommittedBlocks/Block" |
Select-Object -Expand Node
$Count = $String.Count
# Delete the blob and the uncommitted block.
if ($Count.Count -gt 0) {
$listFileURI1 = Invoke-WebRequest -Uri $uriDelete -Method Delete
$FileSystemName1 = $listFileURI1.StatusCode
Write-Host "The deletion was successful. The API returned status code $FileSystemName1."
}
Write-Host "Check whether the uncommitted blocks are still present."
Try {
$listFileURI2 = Invoke-WebRequest -Uri $uriGet -Method Get
} Catch {
# $err = $_.Exception
Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
}
Write-Host (
"In this error message, we can verify that the",
"uncommitted blocks and their respective blob have been deleted.",
"The name and size of the uncommitted blocks that have been deleted are shown."
)
原因 2:Blob 同時執行 PUT 作業
發生計時或並行問題。 這會導致單一 Blob 同時執行多個 PUT(Put Block) 作業。 Put Block List 作業會藉由指定組成 Blob 的區塊識別符清單來寫入 Blob。 若要寫入為 Blob 的一部分,區塊必須在先前 的 Put Block 作業中成功寫入伺服器。
注意
當您啟動上傳之後,但在認可之前,並行上傳認可期間可能會發生此錯誤。 在此情況下,上傳會失敗。 應用程式可以在發生錯誤時重試上傳,也可以嘗試以必要案例為基礎的另一個復原動作。
解決方案:使用租用
不要使用開放式並行存取,而是嘗試使用 Azure 儲存體 SDK 或 GUI 型工具來實作悲觀並行存取(租用),例如 Azure 儲存體 總管。 如需開放式和悲觀並行的詳細資訊,請參閱 管理 Blob 記憶體中的並行存取。
如果錯誤是由並行問題所造成,您可能也必須遵循原因 1 中的其中一個解決方案來清除未認可的區塊。
與我們連絡,以取得說明
如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以向 Azure 意見反應社群提交產品意見反應。