使用 .NET 進行上傳和下載的效能微調

當應用程式使用適用於 .NET 的 Azure 儲存體用戶端程式庫傳輸資料時,有幾個因素可能會影響速度、儲存體使用量,甚至是要求的成功或失敗。 若要將資料傳輸的效能和可靠性最大化,請務必根據應用程式執行所在的環境主動設定用戶端程式庫傳輸選項。

本文會逐步解說微調資料傳輸選項的幾個考量,而指導適用於接受 StorageTransferOptions 做為參數的任何 API。 正確調整時,用戶端程式庫可以有效率地將資料分散到多個要求,進而改善作業速度、儲存體使用量和網路穩定性。

使用 StorageTransferOptions 進行效能微調

StorageTransferOptions 中正確調整值是資料傳輸作業可靠效能的關鍵。 儲存體傳輸會根據此結構執行個體中定義的屬性值,分割成數個子傳輸。 支援的傳輸大小上限會因作業和服務版本而異,因此請務必檢查文件以判斷限制。 如需 Blob 儲存體傳輸大小限制的詳細資訊,請參閱調整 Blob 儲存體的目標

您可以根據應用程式的需求來調整 StorageTransferOptions 的下列屬性:

注意

雖然 StorageTransferOptions 結構包含可為 Null 的值,但如果未提供,則用戶端程式庫會針對每個個別值使用預設值。 這些預設值通常在資料中心環境中更有效率,但可能不適合家庭消費者環境。 微調不佳的 StorageTransferOptions 可能會導致作業時間太長,甚至要求逾時。 最好在 StorageTransferOptions 中主動測試這些值,並根據應用程式和環境的需求來調整這些值。

InitialTransferSize

InitialTransferSize - 第一個範圍要求的大小 (以位元組為單位)。 HTTP 範圍要求是部分要求,在此情況下是 InitialTransferSize 定義的大小。 小於此大小的 Blob 會在單一要求中傳輸。 大於大小 MaximumTransferSize 的 Blob 會繼續以區塊傳送。

務必注意,您為 MaximumTransferSize 指定的值不會限制您為 InitialTransferSize 定義的值。 InitialTransferSize 會定義個別的大小限制,讓初始要求一次執行整個作業且沒有子傳輸。 您通常會想要讓 InitialTransferSize 的大小至少為您針對 MaximumTransferSize 定義的值 (如果不是較大)。 視資料傳輸的大小,此方法可能更有效率,因為傳輸是以單一要求完成,並避免多個要求的額外負荷。

如果您不確定哪個值最適合您的情況,安全的選項是將 InitialTransferSize 設定為用於 MaximumTransferSize 的相同值。

注意

使用 BlobClient 物件時,上傳小於 InitialTransferSize 的 Blob 會使用放置 Blob 執行,而不是 放置區塊

MaximumConcurrency

MaximumConcurrency 是平行傳輸中可使用的背景工作角色數目上限。 目前,只有非同步作業可以平行處理傳輸。 同步作業會忽略此值並依序運作。

此值的有效性受限於 .NET 中的連線集區限制,其可能會在特定案例中預設限制效能。 若要深入了解 .NET 中的連線集區限制,請參閱 .NET Framework 連線集區限制和全新的 Azure SDK for .NET (英文)。

MaximumTransferSize

MaximumTransferSize 是傳輸的最大長度 (以位元組為單位)。 如先前所述,這個值不會限制 InitialTransferSize,其可能大於 MaximumTransferSize

為了保持移動資料有效率地,用戶端程式庫的每個傳輸不一定會達到 MaximumTransferSize 值。 視作業而定,傳輸大小支援的最大值可能會有所不同。 例如,使用服務版本 2019-12-12 或更新版本呼叫放置區塊作業的區塊 Blob 的最大區塊大小為 4000 MiB。 如需 Blob 儲存體傳輸大小限制的詳細資訊,請參閱調整 Blob 儲存體的目標中的圖表。

程式碼範例

用戶端程式庫包含 UploadUploadAsync 方法的多載,其會接受 StorageTransferOptions 執行個體,做為 BlobUploadOptions 參數的一部分。 使用 BlobDownloadToOptions 參數時,DownloadToDownloadToAsync 方法也有類似的多載。

下列程式碼範例示範如何為 StorageTransferOptions 執行個體定義值,並將這些設定選項當做參數傳遞至 UploadAsync。 此範例中提供的值並非意欲作為建議。 若要正確調整這些值,您必須考量應用程式的特定需求。

// Specify the StorageTransferOptions
BlobUploadOptions options = new BlobUploadOptions
{
    TransferOptions = new StorageTransferOptions
    {
        // Set the maximum number of parallel transfer workers
        MaximumConcurrency = 2,

        // Set the initial transfer length to 8 MiB
        InitialTransferSize = 8 * 1024 * 1024,

        // Set the maximum length of a transfer to 4 MiB
        MaximumTransferSize = 4 * 1024 * 1024
    }
};

// Upload data from a stream
await blobClient.UploadAsync(stream, options);

在此範例中,我們會使用 MaximumConcurrency 屬性,將平行傳輸背景工作角色的數目設定為 2。 此設定會同時開啟兩個連線,讓上傳可以平行進行。 初始 HTTP 範圍要求會嘗試上傳最多 8 MiB 的資料,如 InitialTransferSize 屬性所定義。 請注意,InitialTransferSize 僅適用使用可搜尋資料流時的上傳。 如果 Blob 大小小於 8 MiB,則只需要單一要求即能完成作業。 如果 Blob 大小大於 8 MiB,則所有後續傳輸要求的大小上限為 4 MiB,我們會使用 MaximumTransferSize 屬性設定。

上傳的效能考量

在上傳期間,儲存體用戶端程式庫會根據 StorageTransferOptions 執行個體中定義的值,將指定的上傳資料流分割成多個子上傳。 每個子上傳都有自己的專屬 REST 作業呼叫。 對於 BlobClient 物件或 BlockBlobClient 物件,此作業為放置區塊。 對於 DataLakeFileClient 物件,此作業為附加資料。 儲存體用戶端程式庫會平行管理這些 REST 作業(視傳輸選項而定),以完成完整上傳。

視上傳資料流是否可搜尋或不可搜尋,用戶端程式庫會以不同的方式處理緩衝處理和 InitialTransferSize,如下列各節所述。 可搜尋的資料流是支援查詢和修改資料流內目前位置的資料流。 若要深入了解 .NET 中的資料流,請參閱資料流類別參考。

注意

區塊 Blob 的最大區塊計數為 50,000 個區塊。 那麼,您的區塊 Blob 的大小上限為 50,000 x MaximumTransferSize

上傳期間的緩衝處理

儲存體 REST 層不支援取得您離開的 REST 上傳作業;個別傳輸會是已完成或遺失。 為確保無法搜尋資料流上傳的復原能力,儲存體用戶端程式庫會先為每個個別 REST 呼叫緩衝處理資料,再開始上傳。 除了網路速度限制之外,此緩衝處理行為也是考量對 MaximumTransferSize 使用較小值的原因,即使依序上傳也是如此。 減少 MaximumTransferSize 的值會減少在每個要求上緩衝處理的資料量上限,以及每次重試失敗的要求。 如果您在特定大小的資料傳輸期間遇到頻繁逾時,減少 MaximumTransferSize 的值會減少緩衝處理時間,並可能導致更好的效能。

另一個發生緩衝處理的情況是,當您使用平行 REST 呼叫上傳資料以最大化網路輸送量時。 用戶端程式庫需要可以平行讀取的來源,而且因為資料流是循序的,儲存體用戶端程式庫會先緩衝處理每個個別 REST 呼叫的資料,之後再開始上傳。 即使所提供的資料流可供搜尋,也會發生此緩衝處理行為。

若要避免在非同步上傳呼叫期間緩衝處理,您必須提供可搜尋的資料流,並將 MaximumConcurrency 設定為 1。 雖然此策略適用於大部分的情況,但如果您的程式碼使用其他需要緩衝處理的用戶端程式庫功能,仍可能會進行緩衝處理。

上傳時的 InitialTransferSize

提供可搜尋的資料流供上傳時,會根據 InitialTransferSize 的值檢查資料流長度。 如果資料流長度小於此值,則不論其他 StorageTransferOptions 值為何,整個資料流都會上傳為單一 REST 呼叫。 否則,上傳會在多個部分中完成,如先前所述。 InitialTransferSize 對不可搜尋的資料流沒有任何影響,且會被忽略。

下載的效能考量

下載期間,儲存體用戶端程式庫會根據 StorageTransferOptions 執行個體中定義的值,將指定的下載要求分割成多個子下載。 每個子下載都有自己的專屬 REST 作業呼叫。 視傳輸選項而定,用戶端程式庫會平行管理這些 REST 作業,以完成完整下載。

下載期間的緩衝處理

同時接收具有本文內容的多個 HTTP 回應對儲存體使用量有影響。 不過,儲存體用戶端程式庫不會明確新增已下載內容的緩衝區步驟。 會依序處理傳入回應。 用戶端程式庫會設定 16 KB 的緩衝區,以便將資料流從 HTTP 回應資料流複製到呼叫端提供的目的地資料流或檔案路徑。

下載時的 InitialTransferSize

在下載期間,儲存體用戶端程式庫會先使用 InitialTransferSize 進行一個下載範圍要求,再執行任何其他動作。 在此初始下載要求期間,用戶端程式庫會知道資源的大小總計。 如果初始要求已成功下載所有內容,作業就會完成。 否則,用戶端程式庫會繼續提出範圍要求最多到 MaximumTransferSize,直到完整下載完成為止。

下一步