Problem:

Wysyłasz dane z on prem na Azure Storage Account. Została podjęta decyzja, że użyjesz do tego Pythona i bibliotek azure.storage. Przeglądasz dokumentacje i zastanawiasz się, którą metodę wysyłania danych do Azure wybrać? Czy lepiej wybrać append_date czy upload_data? Czy te metody mają jakieś ograniczenia? Która będzie szybsza?

Rozwiązanie:

Użycie upload_data jest zazwyczaj szybsze, natomiast ma pewne ograniczenie. Wysyłając duże pliki możesz dostać Timeout. Ale wysyłanie danych tą metodą jest zdecydowanie szybsze. Możesz pokusić się o rozwiązanie, które próbuje zrobić upload_data a dopiero potem robi append, jeżeli upload się nie powiódł.

Ale może zacznijmy po początku.

Append data

Użycie funkcji append_data ma swoje dodatkowe wymagania. Jest to taki dość rozwlekły sposób na wysyłanie danych, choć z drugiej strony możesz powiedzieć, że wtedy masz kontrolę nad wszystkimi etapami procesu.

Najpierw wymagane jest stworzenie pliku.
Następnie następuje wysyłanie dany a dopiero później opróżnienie strumienie i poinformowanie o zakończeniu procesu wysyłania danych.

file_client.create_file()
file_client.append_date(input_stream, 0, file_size)
file_client.flush_data(file_size)

Jak widzisz, powyżej wysyłany jest od razu cały plik.

Jeżeli zastanawiasz się, w którym miejscu nadawana jest nazwa pliku to robione to jest w momencie, gdy inicjujesz file_clienta:

fsc.get_file_client(f"landing-zone/next-level/{file_name})

Upload data

Użycie upload_data jest zdecydowanie prostsze. Wystarczy jedna linijka i dane wysyłane są na Azure Storage Account.

file_client.upload_data(input_stream, size, overvrite = True)

Przy czym ze swojej strony napotkałem na jedno poważne ograniczenie.

Przy wysyłaniu dużych plików, większych niż 0.5 GB dostaje błąd:

azure.core.exceptions.ServiceResponseError: ('Connection aborted.', TimeoutError('The write operation timed out'))

Żeby pozbyć się tego błędu najłatwiej ustawić parametr connection_timeout, w moim przypadku to zadziałało.

Czyli kod wyglądał w ten sposób:

file_client.upload_data(input_stream, size, overvrite = True, connection_timeout=6000)

Możesz też spróbować zmniejszać porcję danych, które są przesyłane przez ustawianie chunk_size. Domyślną wartością jest 100 MB.

Konkluzje, wnioski i podsumowania

Potszebujesz większej kontroli nad procesem wysyłania wybierz append_data.

Zależy Ci na szybkości wybierz upload_data. Moje testy wydajnościowe pokazały, że w skrajnych przypadkach append był 4 razy wolniejszy od upload. Co jest zdumiewającą różnicą.

Masz duże pliki do wysłania albo pliki są małe ale widzisz potenciał wzrostu i podejrzewasz że pliki urosną wtedy polecam dodanie parametru connection_timeout.

Dla mnie problemy z upload data zaczęły się przy plikach większych niż 0.5 GB.

Powodzenia w wysyłaniu 🙂

https://learn.microsoft.com/en-us/python/api/azure-storage-file-datalake/azure.storage.filedatalake.datalakefileclient?view=azure-python#azure-storage-filedatalake-datalakefileclient-append-data

https://learn.microsoft.com/en-us/python/api/azure-storage-file-datalake/azure.storage.filedatalake.datalakefileclient?view=azure-python#azure-storage-filedatalake-datalakefileclient-upload-data