Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Gdy aplikacja przesyła dane przy użyciu biblioteki klienta usługi Azure Storage dla platformy .NET, 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, a wskazówki dotyczą dowolnego interfejsu API, który akceptuje StorageTransferOptions jako parametr. 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.
Optymalizacja wydajności za pomocą StorageTransferOptions
Prawidłowe dostrajanie wartości w usłudze StorageTransferOptions jest kluczem do niezawodnej wydajności operacji transferu danych. Transfery przechowywania są dzielone na kilka podtransfery, w oparciu o wartości właściwości zdefiniowane w wystąpieniu tej struktury. 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.
Na podstawie potrzeb aplikacji można dostroić następujące właściwości StorageTransferOptions:
- InitialTransferSize — rozmiar pierwszego żądania w bajtach
- MaximumConcurrency — maksymalna liczba podtransferów, które mogą być używane równolegle
- MaximumTransferSize — maksymalna długość transferu w bajtach
Uwaga
Chociaż struktura zawiera wartości mogące być null, biblioteki klienckie będą używać wartości domyślnych dla każdej wartości z osobna, jeśli nie są dostarczone. Te domyślne ustawienia zazwyczaj działają wydajnie w środowisku centrum danych, ale prawdopodobnie nie będą odpowiednie dla warunków użytkownika domowego. Źle dostrojone StorageTransferOptions może spowodować zbyt długie operacje, a nawet przekroczenie limitu czasu żądania. Najlepiej proaktywnie testować wartości w StorageTransferOptions, i dostrajać je na podstawie potrzeb aplikacji i środowiska.
PoczątkowyRozmiarTransferu
InitialTransferSize to rozmiar pierwszego żądania zakresu w bajtach. Żądanie zakresu HTTP to żądanie częściowe, w którym rozmiar jest zdefiniowany przez InitialTransferSize w tym przypadku. Bloby mniejsze niż ten rozmiar są przenoszone w jednym żądaniu. Bloby większe niż ten rozmiar nadal są przesyłane we fragmentach o rozmiarze MaximumTransferSize.
Należy pamiętać, że określona MaximumTransferSizewartość nie ogranicza wartości zdefiniowanej dla elementu InitialTransferSize.
InitialTransferSize Definiuje oddzielne ograniczenie rozmiaru dla początkowego żądania do wykonania całej operacji jednocześnie bez podtransferów. Często zdarza się, że chcesz, aby InitialTransferSize była co najmniej tak duża, jak wartość zdefiniowana dla , jeśli 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 InitialTransferSize tej samej wartości używanej dla elementu MaximumTransferSize.
Uwaga
W przypadku korzystania z BlobClient obiektu przekazywanie obiektu blob mniejszego niż InitialTransferSize zostanie wykonane przy użyciu funkcji Put Blob, a nie put block.
Maksymalna Liczba Równoległych Procesów
MaximumConcurrency to maksymalna liczba procesów roboczych, które mogą być używane w transferze równoległym. Obecnie tylko operacje asynchroniczne mogą równolegle wykonywać transfery. Operacje synchroniczne ignorują tę wartość i działają w sekwencji.
Skuteczność tej wartości podlega limitom puli połączeń na platformie .NET, które mogą domyślnie ograniczać wydajność w niektórych scenariuszach. Możesz użyć następującego kodu, aby zwiększyć domyślny limit połączenia (czyli zazwyczaj dwa w środowisku klienta lub dziesięć w środowisku serwera) do 100. Zazwyczaj należy ustawić wartość na około liczbę wątków używanych przez aplikację. Ustaw limit połączenia przed otwarciem jakichkolwiek połączeń.
ServicePointManager.DefaultConnectionLimit = 100; //(Or More)
Aby dowiedzieć się więcej na temat limitów puli połączeń w programie .NET Framework, zobacz Limity puli połączeń programu .NET Framework i nowy zestaw Azure SDK dla platformy .NET.
Aby uzyskać więcej informacji, zobacz metodę ThreadPool.SetMinThreads .
MaksymalnaWielkośćTransferu
MaximumTransferSize to maksymalna długość transferu w bajtach. Jak wspomniano wcześniej, ta wartość nie ogranicza InitialTransferSize, która może być większa niż MaximumTransferSize.
Aby wydajnie przenosić dane, biblioteki klienckie mogą nie zawsze osiągać wartości MaximumTransferSize dla każdego transferu. W zależności od operacji maksymalna obsługiwana wartość rozmiaru transferu może się różnić. Na przykład bloby blokowe wywołujące operację Put Block z wersją usługi 2019-12-12 lub nowszą mają maksymalny rozmiar bloku 4000 MiB. 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
Biblioteka klienta zawiera przeciążenia metod Upload i UploadAsync, które akceptują wystąpienie StorageTransferOptions jako część parametru BlobUploadOptions. Podobne przeciążenia istnieją również dla metod DownloadTo i DownloadToAsync, przy użyciu parametru BlobDownloadToOptions.
Poniższy przykład kodu pokazuje, jak zdefiniować wartości dla StorageTransferOptions wystąpienia i przekazać te opcje konfiguracji jako parametr do UploadAsync. 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.
// 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);
W tym przykładzie ustawiliśmy liczbę pracowników transferu na 2, przy użyciu właściwości MaximumConcurrency. Ta konfiguracja otwiera maksymalnie dwa połączenia jednocześnie, co pozwala na równoległe przekazywanie. Początkowe żądanie zakresu HTTP próbuje przesłać do 8 MiB danych, jak określa właściwość InitialTransferSize. Należy pamiętać, że InitialTransferSize dotyczy tylko przesyłania w przypadku korzystania ze strumienia z możliwością wyszukiwania. Jeśli rozmiar obiektu blob jest mniejszy niż 8 MiB, tylko jedno żądanie jest niezbędne do ukończenia operacji. Jeśli rozmiar obiektu blob jest większy niż 8 MiB, wszystkie kolejne żądania transferu mają maksymalny rozmiar 4 MiB, który ustawiliśmy za pomocą MaximumTransferSize właściwości .
Zwiększanie minimalnej liczby wątków
Jeśli używasz wywołań synchronicznych wraz z zadaniami asynchronicznymi, możesz zwiększyć liczbę wątków w puli wątków:
ThreadPool.SetMinThreads(100,100); //(Determine the right number for your application)
Zagadnienia dotyczące wydajności uploadów
Podczas przesyłania bibliotek klientów Storage dzielą dany strumień przesyłania na wiele podstrumieni na podstawie wartości zdefiniowanych w instancji StorageTransferOptions. Każdy podładunek ma własne dedykowane wywołanie operacji REST. W przypadku obiektu BlobClient lub BlockBlobClient ta operacja to Put Block.
DataLakeFileClient W przypadku obiektu ta operacja to Dołączanie danych. 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.
W zależności od tego, czy strumień przekazywania można wyszukiwać, czy nie można go znaleźć, biblioteka klienta obsługuje buforowanie i InitialTransferSize inaczej, zgodnie z opisem w poniższych sekcjach. Strumień z możliwością wyszukiwania to strumień, który obsługuje wykonywanie zapytań i modyfikowanie bieżącego położenia w strumieniu. Aby dowiedzieć się więcej o strumieniach na platformie .NET, zobacz dokumentację klasy Stream.
Uwaga
Blokowe obiekty blob mogą składać się maksymalnie z 50 000 bloków. Maksymalny rozmiar blokowego obiektu blob to 50 000 razy MaximumTransferSize.
Buforowanie podczas przekazywania
Warstwa REST magazynu nie obsługuje wznawiania operacji przesyłania REST od momentu, w którym została przerwana; indywidualne transfery są ukończone lub utracone. Aby zapewnić odporność przy przesyłaniu strumieni danych niemających możliwości wyszukiwania, biblioteki klienckie Storage buforują dane dla każdego pojedynczego wywołania REST przed rozpoczęciem przesyłania. Oprócz ograniczeń szybkości sieci zachowanie buforowania jest powodem, dla którego należy wziąć pod uwagę mniejszą wartość MaximumTransferSize, nawet w przypadku przekazywania w sekwencji. Zmniejszenie wartości MaximumTransferSize 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 MaximumTransferSize skraca czas buforowania i może spowodować lepszą wydajność.
Jednym z przypadków, w którym występuje buforowanie, jest przesyłanie danych z równoległymi wywołaniami REST, co pozwala na maksymalizację przepustowości sieci. Biblioteki klienckie potrzebują źródeł, które mogą odczytywać równolegle, a ponieważ strumienie są sekwencyjne, biblioteki klienta usługi Storage buforują dane dla każdego wywołania REST przed rozpoczęciem przekazywania. To zachowanie buforowania występuje nawet wtedy, gdy podany strumień jest możliwy do wyszukiwania.
Aby uniknąć buforowania podczas asynchronicznego wywołania przesyłania, należy podać strumień z możliwością wyszukiwania i ustawić wartość MaximumConcurrency na 1. Chociaż ta strategia powinna działać w większości sytuacji, nadal jest możliwe buforowanie, jeśli kod korzysta z innych funkcji biblioteki klienta, które wymagają buforowania.
InitialTransferSize podczas wysyłania
Gdy udostępniany jest strumień z możliwością przeszukiwania, długość strumienia jest sprawdzana względem wartości InitialTransferSize. Jeśli długość strumienia jest mniejsza niż ta wartość, cały strumień jest przekazywany jako pojedyncze wywołanie REST, niezależnie od innych StorageTransferOptions wartości. W przeciwnym razie przekazywanie odbywa się w wielu częściach zgodnie z wcześniejszym opisem.
InitialTransferSize nie ma wpływu na strumień nieprzeszukiwany i jest ignorowany.
Zagadnienia dotyczące wydajności pobierania
Podczas pobierania biblioteki klienckie Storage dzielą żądanie pobierania na wiele subpobrań na podstawie wartości zdefiniowanych w wystąpieniu StorageTransferOptions. Każda podczęść pobierania 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.
Buforowanie podczas pobierania
Odbieranie wielu odpowiedzi HTTP jednocześnie z zawartością treści ma wpływ na użycie pamięci. Jednak biblioteki klienckie usługi Storage nie dodają jawnie kroku buforu dla pobranej zawartości. Odpowiedzi przychodzące są przetwarzane w kolejności. Biblioteki klienckie konfigurują bufor 16-kilobajtowy na potrzeby kopiowania strumieni z strumienia odpowiedzi HTTP do strumienia docelowego dostarczanego przez obiekt wywołujący lub ścieżkę pliku.
InitialTransferSize podczas pobierania
Podczas pobierania biblioteki klienckie usługi Storage tworzą jedno żądanie zakresu pobierania przy użyciu InitialTransferSize 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 aż do MaximumTransferSize momentu ukończenia całkowitego pobrania.
Następne kroki
- Ten artykuł jest częścią przewodnika dla deweloperów usługi Blob Storage dla platformy .NET. Zobacz pełną listę artykułów z przewodnika dla deweloperów na stronie Tworzenie aplikacji.
- Aby dowiedzieć się więcej na temat czynników, które mogą mieć wpływ na wydajność operacji usługi Azure Storage, zobacz Opóźnienie w usłudze Blob Storage.
- Aby zapoznać się z listą zagadnień projektowych dotyczących optymalizacji wydajności aplikacji korzystających z usługi Blob Storage, zobacz Lista kontrolna wydajności i skalowalności dla usługi Blob Storage.