Udostępnij za pomocą


Dostrajanie wydajności przekazywania i pobierania za pomocą języka Python

Gdy aplikacja przesyła dane przy użyciu biblioteki klienta usługi Azure Storage dla języka Python, istnieje kilka czynników, które mogą mieć wpływ na szybkość, użycie pamięci, a nawet powodzenie lub niepowodzenie żądania. Aby zmaksymalizować wydajność i niezawodność transferów danych, ważne jest, aby aktywnie konfigurować opcje transferu biblioteki klienta w oparciu o środowisko, w których działa aplikacja.

W tym artykule przedstawiono kilka zagadnień dotyczących dostrajania opcji transferu danych. Odpowiednio dostrojona biblioteka klienta może efektywnie dystrybuować dane między wieloma żądaniami, co może spowodować zwiększenie szybkości działania, użycia pamięci i stabilności sieci.

Dostrajanie wydajności przesyłania danych

Prawidłowe dostrajanie opcji transferu danych jest kluczem do niezawodnej wydajności przekazywania. Transfery przechowywania są podzielone na kilka podtransferów na podstawie wartości tych argumentów. Maksymalny obsługiwany rozmiar transferu różni się w zależności od wersji operacji i usługi, dlatego zapoznaj się z dokumentacją, aby określić limity. Aby uzyskać więcej informacji na temat limitów rozmiaru transferu dla usługi Blob Storage, zobacz Skalowanie obiektów docelowych dla usługi Blob Storage.

Ustaw opcje transferu dla przesyłania

Na podstawie potrzeb aplikacji można dostosować następujące argumenty:

  • max_single_put_size: maksymalny rozmiar obiektu blob do przesłania za pomocą jednego żądania. Wartość domyślna to 64 MiB.
  • max_block_size: maksymalna długość transferu w bajtach podczas wysyłania blokowego obiektu blob we fragmentach. Wartość domyślna to 4 MiB.
  • max_concurrency: maksymalna liczba podtransferów, które mogą być używane równolegle.

Note

Biblioteki klienckie będą używać wartości domyślnych dla każdej opcji transferu danych, jeśli nie zostanie podana. Te domyślne ustawienia zazwyczaj dobrze sprawdzają się w środowisku centrum danych, ale prawdopodobnie nie będą odpowiednie dla środowisk konsumenckich w domach. Źle dostrojone opcje transferu danych mogą spowodować zbyt długie operacje, a nawet przekroczenia limitu czasu żądania. Najlepiej proaktywnie testować te wartości i dostrajać je w zależności od potrzeb aplikacji i środowiska.

max_single_put_size

Argumentem max_single_put_size jest maksymalny rozmiar obiektu blob w bajtach dla przesyłania jednego żądania. Jeśli rozmiar obiektu blob jest mniejszy lub równy max_single_put_size, obiekt blob jest przekazywany za pomocą pojedynczego żądania put blob . Jeśli rozmiar bloba jest większy niż max_single_put_size, lub jeśli rozmiar bloba jest nieznany, blob jest przekazywany we fragmentach przy użyciu serii wywołań Put Block, a następnie Put Block List.

Należy pamiętać, że określona max_block_size wartość nie ogranicza wartości zdefiniowanej dla elementu max_single_put_size. Argument max_single_put_size definiuje oddzielne ograniczenie rozmiaru dla żądania do wykonania całej operacji jednocześnie bez podtransferów. Często zdarza się, że chcesz, aby max_single_put_size była co najmniej tak duża, jak wartość, którą definiujesz dla max_block_size, o ile nie większa. W zależności od rozmiaru transferu danych takie podejście może być bardziej wydajne, ponieważ transfer jest wykonywany przy użyciu jednego żądania i pozwala uniknąć narzutów na wiele żądań.

Jeśli nie masz pewności, jaka wartość jest najlepsza dla twojej sytuacji, bezpieczna opcja to ustawienie max_single_put_size tej samej wartości używanej dla elementu max_block_size.

max_block_size

Argument max_block_size jest maksymalną długością transferu w bajtach podczas przesyłania blokowego blobu w segmentach. Jak wspomniano wcześniej, ta wartość nie ogranicza wartości max_single_put_size, która może być większa niż max_block_size.

Aby wydajnie przenosić dane, biblioteki klienckie mogą nie zawsze osiągać wartość max_block_size dla każdego transferu. W zależności od operacji maksymalna obsługiwana wartość rozmiaru transferu może się różnić. Aby uzyskać więcej informacji na temat limitów rozmiaru transferu dla usługi Blob Storage, zobacz wykres w temacie Skalowanie obiektów docelowych dla usługi Blob Storage.

Przykład kodu

Poniższy przykład kodu przedstawia sposób określania opcji transferu danych podczas tworzenia BlobClient obiektu oraz sposobu przekazywania danych przy użyciu tego obiektu klienta. Wartości podane w tym przykładzie nie są przeznaczone do zalecenia. Aby prawidłowo dostosować te wartości, należy wziąć pod uwagę konkretne potrzeby aplikacji.

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)

W tym przykładzie ustawiliśmy liczbę równoległych pracowników transferu na 2, używając argumentu max_concurrency podczas wywołania metody. Ta konfiguracja otwiera maksymalnie dwa połączenia jednocześnie, co pozwala na równoległe przekazywanie. Podczas tworzenia wystąpienia klienta ustawiamy max_single_put_size argument na wartość 8 MiB. Jeśli rozmiar obiektu blob jest mniejszy niż 8 MiB, tylko jedno żądanie jest niezbędne do ukończenia operacji przekazywania. Jeśli rozmiar obiektu blob jest większy niż 8 MiB, obiekt blob jest przekazywany we fragmentach z maksymalnym rozmiarem fragmentu wynoszącym 4 MiB, zgodnie z ustawieniem argumentu max_block_size .

Kwestie wydajności przy wysyłaniu

Podczas przesyłania biblioteki klienta usługi Storage dzielą dany strumień przesyłania na wiele podprzesyłów na podstawie opcji konfiguracji określonych przy tworzeniu klienta. Każdy podładunek ma własne dedykowane wywołanie operacji REST. BlobClient W przypadku obiektu ta operacja to Put Block. Biblioteka klienta usługi Storage zarządza tymi operacjami REST równolegle (w zależności od opcji transferu), aby ukończyć pełne przekazywanie.

Możesz dowiedzieć się, jak biblioteka klienta obsługuje buforowanie w poniższych sekcjach.

Note

Blobowe obiekty blokowe mają maksymalną liczbę bloków wynoszącą 50 000. Maksymalny rozmiar blokowego obiektu blob to 50 000 razy max_block_size.

Buforowanie podczas przekazywania

Warstwa REST magazynu nie obsługuje wznawiania operacji przesyłania REST od miejsca, w którym została przerwana; indywidualne transfery są albo ukończone, albo utracone. Aby zapewnić odporność na przekazywanie strumienia, biblioteki klienckie usługi Storage buforują dane dla każdego wywołania REST przed rozpoczęciem przekazywania. Oprócz ograniczeń szybkości sieci zachowanie buforowania jest powodem, dla którego należy wziąć pod uwagę mniejszą wartość max_block_size, nawet w przypadku przekazywania w sekwencji. Zmniejszenie wartości max_block_size zmniejsza maksymalną ilość danych buforowanych dla każdego żądania i ponawianie próby żądania, które zakończyło się niepowodzeniem. Jeśli występują częste przekroczenia limitu czasu podczas transferów danych o określonym rozmiarze, zmniejszenie wartości max_block_size skraca czas buforowania i może spowodować lepszą wydajność.

Domyślnie zestaw SDK buforuje dane o rozmiarze max_block_size bajtów na jedno jednoczesne żądanie podładowania, ale użycie pamięci można ograniczyć do 4 MiB na żądanie, jeśli spełnione są następujące warunki:

  • Argument max_block_size musi być większy niż min_large_block_upload_threshold. Argument min_large_block_upload_threshold można zdefiniować podczas tworzenia klienta i określa minimalny rozmiar fragmentu w bajtach wymaganych do użycia algorytmu oszczędzającego pamięć. Argument min_large_block_upload_threshold domyślnie ma wartość 4*1024*1024 + 1.
  • Podany strumień musi być przeszukiwalny. Strumień z możliwością wyszukiwania to strumień, który obsługuje wykonywanie zapytań i modyfikowanie bieżącego położenia w strumieniu.
  • Obiekt blob musi być blokowym blobem.

Chociaż ta strategia ma zastosowanie do większości sytuacji, nadal istnieje możliwość zwiększenia buforowania, jeśli kod korzysta z innych funkcji biblioteki klienta, które wymagają buforowania.

Dostrajanie wydajności pobierania

Prawidłowe dostrajanie opcji transferu danych jest kluczem do niezawodnej wydajności pobierania. Transfery przechowywania są podzielone na kilka podtransferów na podstawie wartości tych argumentów.

Ustawianie opcji transferu dla pobierania

Na podstawie potrzeb aplikacji można dostosować następujące argumenty:

  • max_chunk_get_size: maksymalny rozmiar fragmentu używany do pobierania obiektu blob. Wartość domyślna to 4 MiB.
  • max_concurrency: maksymalna liczba podtransferów, które mogą być używane równolegle.
  • max_single_get_size: maksymalny rozmiar obiektu blob, który można pobrać w jednym wywołaniu. Jeśli całkowity rozmiar obiektu blob przekracza wartość max_single_get_size, pozostałe dane obiektu blob są pobierane we fragmentach. Wartość domyślna to 32 MiB.
  • connection_data_block_size: określa rozmiar bloków danych odczytywanych ze strumienia sieciowego. Wartość domyślna to 4 KiB.

Przykład kodu

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
        connection_data_block_size=1024*4, # 4 KiB
    )

    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())

Zagadnienia dotyczące wydajności pobierania

Podczas pobierania biblioteki klienckie usługi Storage dzielą dane żądanie pobierania na wiele podpobierze na podstawie opcji konfiguracji zdefiniowanych podczas budowy klienta. Każde podpobieranie ma własne dedykowane wywołanie operacji REST. W zależności od opcji transferu biblioteki klienckie zarządzają tymi operacjami REST równolegle w celu ukończenia pełnego pobierania.

max_single_get_size dla pobrań

Podczas pobierania biblioteki klienckie usługi Storage tworzą jedno żądanie zakresu pobierania przy użyciu max_single_get_size przed wykonaniem czegokolwiek innego. Podczas tego początkowego żądania pobierania biblioteki klienckie znają całkowity rozmiar zasobu. Jeśli początkowe żądanie pomyślnie pobrało całą zawartość, operacja zostanie ukończona. W przeciwnym razie biblioteki klienckie nadal wysyłają żądania zakresu do max_chunk_get_size momentu ukończenia pełnego pobierania.

rozmiar_bloku_danych_podłączenia dla pobierania

Podczas pobierania to ustawienie connection_data_block_size może znacząco wpływać na wydajność pobierania. Jego wpływ jest bardzo zależny od konkretnego środowiska i konfiguracji sprzętu. Spróbuj rozpocząć od wartości, takiej jak 64KiB, i stopniowo dostosowywać ją, aby znaleźć optymalną równowagę podczas monitorowania wydajności i użycia zasobów.

Dalsze kroki