共用方式為


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

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

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

上傳的效能微調

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

設定上傳的傳輸選項

您可以根據應用程式的需求來調整下列引數:

  • max_single_put_size:以單一要求上傳 Blob 的大小上限。 預設為 64 MiB。
  • max_block_size:在區塊中上傳區塊 Blob 時,傳輸的最大長度 (以位元組為單位)。 預設為 4 MiB。
  • max_concurrency:可能平行使用的子傳輸數目上限。

注意

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

max_single_put_size

max_single_put_size 引數是單一要求上傳的 Blob 大小上限 (以位元組為單位)。 如果 Blob 大小小於或等於 max_single_put_size,Blob 會以單一放置 Blob 要求上傳。 如果 Blob 大小大於 max_single_put_size,或 Blob 大小未知,則會使用一系列的放置區塊呼叫,接著放置區塊清單,以區塊方式上傳 Blob。

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

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

max_block_size

max_block_size 引數是在區塊中上傳區塊 Blob 時,傳輸的最大長度 (以位元組為單位)。 如先前所述,這個值不會限制 max_single_put_size,其可能大於 max_block_size

為了保持移動資料有效率地,用戶端程式庫的每個傳輸不一定會達到 max_block_size 值。 視作業而定,傳輸大小支援的最大值可能會有所不同。 如需 Blob 儲存體傳輸大小限制的詳細資訊,請參閱調整 Blob 儲存體的目標中的圖表。

程式碼範例

下列程式碼範例示範如何在建立 BlobClient 物件時指定資料傳輸選項,以及如何使用該用戶端物件上傳資料。 此範例中提供的值並非意欲作為建議。 若要正確調整這些值,您必須考量應用程式的特定需求。

def upload_blob_transfer_options(self, account_url: str, container_name: str, blob_name: str):
    # Create a BlobClient object with data transfer options for upload
    blob_client = BlobClient(
        account_url=account_url, 
        container_name=container_name, 
        blob_name=blob_name,
        credential=DefaultAzureCredential(),
        max_block_size=1024*1024*4, # 4 MiB
        max_single_put_size=1024*1024*8 # 8 MiB
    )
    
    with open(file=os.path.join(r'file_path', blob_name), mode="rb") as data:
        blob_client = blob_client.upload_blob(data=data, overwrite=True, max_concurrency=2)

在此範例中,我們會在方法呼叫上使用 max_concurrency 引數,將平行傳輸背景工作角色的數目設定為 2。 此設定會同時開啟兩個連線,讓上傳可以平行進行。 在用戶端具現化期間,我們會將 max_single_put_size 引數設定為 8 MiB。 如果 Blob 大小小於 8 MiB,則只需要單一要求即能完成上傳作業。 如果 Blob 大小大於 8 MiB,Blob 會以區塊上傳 (區塊大小上限為 4 MiB),如 max_block_size 引數所設定。

上傳的效能考量

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

您可以在下列各節中了解用戶端程式庫如何處理緩衝處理。

注意

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

上傳期間的緩衝處理

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

依預設,SDK 會根據每個並行子上傳要求緩衝 max_block_size 個位元組的資料,但如果符合下列條件,儲存體使用量可能會限制為每個要求 4 MiB:

  • max_block_size 引數必須大於 min_large_block_upload_thresholdmin_large_block_upload_threshold 引數可以在用戶端具現化期間定義,而且是使用儲存體有效率演算法所需的最小區塊大小。 min_large_block_upload_threshold 引數預設為 4*1024*1024 + 1
  • 提供的資料流必須可供搜尋。 可搜尋的資料流是支援查詢和修改資料流內目前位置的資料流。
  • Blob 必須是區塊 Blob。

雖然此策略適用於大部分的情況,但如果您的程式碼使用其他需要緩衝處理的用戶端程式庫功能,仍可能會進行更多的緩衝處理。

下載的效能微調

正確調整資料傳輸選項是下載可靠效能的關鍵。 儲存體傳輸會根據這些引數的值分割成數個子傳輸。

設定下載的傳輸選項

您可以根據應用程式的需求來調整下列引數:

  • max_chunk_get_size:用於下載 Blob 的最大區塊大小。 預設為 4 MiB。
  • max_concurrency:可能平行使用的子傳輸數目上限。
  • max_single_get_size:在單一呼叫中下載 Blob 的大小上限。 如果 Blob 大小總計超過 max_single_get_size,則會以區塊方式下載其餘的 Blob 資料。 預設為 32 MiB。

程式碼範例

def download_blob_transfer_options(self, account_url: str, container_name: str, blob_name: str):
    # Create a BlobClient object with data transfer options for download
    blob_client = BlobClient(
        account_url=account_url, 
        container_name=container_name, 
        blob_name=blob_name,
        credential=DefaultAzureCredential(),
        max_single_get_size=1024*1024*32, # 32 MiB
        max_chunk_get_size=1024*1024*4 # 4 MiB
    )

    with open(file=os.path.join(r'file_path', 'file_name'), mode="wb") as sample_blob:
        download_stream = blob_client.download_blob(max_concurrency=2)
        sample_blob.write(download_stream.readall())

下載的效能考量

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

下載的 max_single_get_size

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

下一步