Prestandajustering för uppladdningar och nedladdningar med .NET
När ett program överför data med hjälp av Azure Storage-klientbiblioteket för .NET finns det flera faktorer som kan påverka hastighet, minnesanvändning och till och med lyckade eller misslyckade begäranden. För att maximera prestanda och tillförlitlighet för dataöverföringar är det viktigt att vara proaktiv när det gäller att konfigurera överföringsalternativ för klientbibliotek baserat på den miljö som appen körs i.
Den här artikeln går igenom flera överväganden för att justera alternativ för dataöverföring, och vägledningen gäller för alla API:er StorageTransferOptions
som accepterar som en parameter. När klientbiblioteket är korrekt justerat kan det effektivt distribuera data över flera begäranden, vilket kan leda till förbättrad drifthastighet, minnesanvändning och nätverksstabilitet.
Prestandajustering med StorageTransferOptions
Korrekt justering av värdena i StorageTransferOptions är nyckeln till tillförlitliga prestanda för dataöverföringsåtgärder. Lagringsöverföringar partitioneras i flera undertransfers baserat på de egenskapsvärden som definieras i en instans av den här structen. Den maximala överföringsstorleken som stöds varierar beroende på åtgärd och tjänstversion, så se till att kontrollera dokumentationen för att fastställa gränserna. Mer information om överföringsstorleksgränser för Blob Storage finns i Skalningsmål för Blob Storage.
Följande egenskaper StorageTransferOptions
för kan justeras baserat på appens behov:
- InitialTransferSize – storleken på den första begäran i byte
- MaximumConcurrency – det maximala antalet undertransfers som kan användas parallellt
- MaximumTransferSize – den maximala längden på en överföring i byte
Kommentar
StorageTransferOptions
Även om structen innehåller null-värden använder klientbiblioteken standardvärden för varje enskilt värde, om det inte anges. Dessa standardvärden fungerar vanligtvis i en datacentermiljö, men är troligen inte lämpliga för hemkonsumentmiljöer. Dåligt justerad StorageTransferOptions
kan resultera i överdrivet långa åtgärder och till och med tidsgränser för begäranden. Det är bäst att vara proaktiv när du testar värdena i StorageTransferOptions
och justerar dem baserat på behoven i ditt program och din miljö.
InitialTransferSize
InitialTransferSize är storleken på den första intervallbegäran i byte. En HTTP-intervallbegäran är en partiell begäran med den storlek som definieras av InitialTransferSize
i det här fallet. Blobbar som är mindre än den här storleken överförs i en enda begäran. Blobar som är större än den här storleken fortsätter att överföras i segment av storlek MaximumTransferSize
.
Det är viktigt att observera att det värde du anger för MaximumTransferSize
inte begränsar det värde som du definierar för InitialTransferSize
. InitialTransferSize
definierar en separat storleksbegränsning för en inledande begäran för att utföra hela åtgärden samtidigt, utan undertransfers. Det är ofta så att du vill InitialTransferSize
vara minst lika stor som värdet du definierar för MaximumTransferSize
, om inte större. Beroende på storleken på dataöverföringen kan den här metoden vara mer högpresterande eftersom överföringen slutförs med en enda begäran och undviker omkostnaderna för flera begäranden.
Om du är osäker på vilket värde som är bäst för din situation är ett säkert alternativ att ange InitialTransferSize
samma värde som används för MaximumTransferSize
.
Kommentar
När du använder ett BlobClient
objekt utförs uppladdning av en blob som är mindre än den InitialTransferSize
som ska utföras med hjälp av Put Blob i stället för Put Block.
MaximumConcurrency
MaximumConcurrency är det maximala antalet arbetare som kan användas i en parallell överföring. För närvarande kan endast asynkrona åtgärder parallellisera överföringar. Synkrona åtgärder ignorerar det här värdet och fungerar i ordning.
Det här värdets effektivitet omfattas av gränser för anslutningspooler i .NET, vilket kan begränsa prestanda som standard i vissa scenarier. Mer information om gränser för anslutningspooler i .NET finns i .NET Framework-gränser för anslutningspooler och det nya Azure SDK för .NET.
MaximumTransferSize
MaximumTransferSize är den maximala längden på en överföring i byte. Som tidigare nämnts begränsar inte det här värdet , som kan vara större än MaximumTransferSize
. InitialTransferSize
För att hålla data i rörelse effektivt kanske klientbiblioteken inte alltid når MaximumTransferSize
värdet för varje överföring. Beroende på åtgärden kan det maximala värdet för överföringsstorleken variera. Till exempel har blockblobar som anropar put block-åtgärden med en tjänstversion av 2019-12-12 eller senare en maximal blockstorlek på 4 000 MiB. Mer information om gränserna för överföringsstorlek för Blob Storage finns i diagrammet i Skala mål för Blob Storage.
Kodexempel
Klientbiblioteket innehåller överlagringar för Upload
metoderna och UploadAsync
som accepterar en StorageTransferOptions-instans som en del av en BlobUploadOptions-parameter . Liknande överlagringar finns också för DownloadTo
metoderna och DownloadToAsync
med hjälp av parametern BlobDownloadToOptions .
Följande kodexempel visar hur du definierar värden för en StorageTransferOptions
instans och skickar dessa konfigurationsalternativ som en parameter till UploadAsync
. De värden som anges i det här exemplet är inte avsedda att vara en rekommendation. Om du vill justera dessa värden korrekt måste du ta hänsyn till appens specifika behov.
// 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);
I det här exemplet anger vi antalet parallella överföringsarbetare till 2 med hjälp av MaximumConcurrency
egenskapen . Den här konfigurationen öppnar upp till två anslutningar samtidigt, vilket gör att uppladdningen kan ske parallellt. Den första HTTP-intervallbegäran försöker ladda upp upp till 8 MiB data enligt egenskapens definition InitialTransferSize
. Observera att InitialTransferSize
endast gäller för uppladdningar när du använder en sökbar ström. Om blobstorleken är mindre än 8 MiB krävs bara en enda begäran för att slutföra åtgärden. Om blobstorleken är större än 8 MiB har alla efterföljande överföringsbegäranden en maximal storlek på 4 MiB, som vi anger med MaximumTransferSize
egenskapen .
Prestandaöverväganden för uppladdningar
Under en uppladdning delar Storage-klientbiblioteken upp en viss uppladdningsström i flera underuppdateringar baserat på de värden som definierats i instansen StorageTransferOptions
. Varje underuppladdning har ett eget dedikerat anrop till REST-åtgärden. För ett BlobClient
objekt eller BlockBlobClient
objekt är den här åtgärden Placera block. För ett DataLakeFileClient
objekt är den här åtgärden Tilläggsdata. Storage-klientbiblioteket hanterar dessa REST-åtgärder parallellt (beroende på överföringsalternativ) för att slutföra den fullständiga uppladdningen.
Beroende på om uppladdningsströmmen kan sökas eller inte kan sökas hanterar klientbiblioteket buffring och InitialTransferSize
på olika sätt, enligt beskrivningen i följande avsnitt. En sökbar ström är en ström som stöder frågor och ändringar av den aktuella positionen i en dataström. Mer information om strömmar i .NET finns i klassen Stream-referens.
Kommentar
Blockblobar har ett maximalt blockantal på 50 000 block. Den maximala storleken på blockbloben är då 50 000 gånger MaximumTransferSize
.
Buffring under uppladdningar
Storage REST-lagret har inte stöd för att hämta en REST-uppladdningsåtgärd där du slutade. enskilda överföringar antingen slutförs eller förloras. För att säkerställa återhämtning för icke-sökbara dataströmuppladdningar buffrar Storage-klientbiblioteken data för varje enskilt REST-anrop innan uppladdningen startas. Förutom begränsningar i nätverkshastigheten är det här buffringsbeteendet en anledning att överväga ett mindre värde för MaximumTransferSize
, även när du laddar upp i sekvens. Om du minskar värdet för MaximumTransferSize
minskar den maximala mängden data som buffrats för varje begäran och varje nytt försök av en misslyckad begäran. Om du har frekventa timeouter under dataöverföringar av en viss storlek minskar en minskning av MaximumTransferSize
värdet för buffringstiden och kan resultera i bättre prestanda.
Ett annat scenario där buffring sker är när du laddar upp data med parallella REST-anrop för att maximera nätverkets dataflöde. Klientbiblioteken behöver källor som de kan läsa från parallellt, och eftersom strömmarna är sekventiella buffrar Storage-klientbiblioteken data för varje enskilt REST-anrop innan uppladdningen startas. Det här buffringsbeteendet inträffar även om den angivna strömmen kan sökas.
För att undvika buffring under ett asynkront uppladdningsanrop måste du ange en sökbar ström och ange MaximumConcurrency
1. Även om den här strategin bör fungera i de flesta situationer är det fortfarande möjligt att buffring sker om koden använder andra klientbiblioteksfunktioner som kräver buffring.
InitialTransferSize vid uppladdning
När en sökbar ström tillhandahålls för uppladdning kontrolleras strömlängden mot värdet InitialTransferSize
för . Om strömlängden är mindre än det här värdet laddas hela strömmen upp som ett enda REST-anrop, oavsett andra StorageTransferOptions
värden. Annars görs uppladdningen i flera delar enligt beskrivningen tidigare. InitialTransferSize
har ingen effekt på en ström som inte kan sökas och ignoreras.
Prestandaöverväganden för nedladdningar
Under en nedladdning delar Lagringsklientbiblioteken upp en viss nedladdningsbegäran i flera undernedladdningar baserat på de värden som definierats i instansen StorageTransferOptions
. Varje underdelast har ett eget dedikerat anrop till REST-åtgärden. Beroende på överföringsalternativ hanterar klientbiblioteken dessa REST-åtgärder parallellt för att slutföra den fullständiga nedladdningen.
Buffring under nedladdningar
Att ta emot flera HTTP-svar samtidigt med brödtextinnehåll har konsekvenser för minnesanvändningen. Lagringsklientbiblioteken lägger dock inte uttryckligen till ett buffertsteg för nedladdat innehåll. Inkommande svar bearbetas i ordning. Klientbiblioteken konfigurerar en buffert på 16 kilobyte för att kopiera strömmar från en HTTP-svarsström till en målström eller filsökväg som tillhandahålls av anroparen.
InitialTransferSize vid nedladdning
Under en nedladdning gör Storage-klientbiblioteken en begäran om nedladdningsintervall med hjälp av InitialTransferSize
innan du gör något annat. Under den första nedladdningsbegäran känner klientbiblioteken till resursens totala storlek. Om den första begäran har laddat ned allt innehåll är åtgärden slutförd. Annars fortsätter klientbiblioteken att göra intervallbegäranden fram tills MaximumTransferSize
den fullständiga nedladdningen är klar.
Nästa steg
- Den här artikeln är en del av utvecklarguiden för Blob Storage för .NET. Se den fullständiga listan över utvecklarguideartiklar i Skapa din app.
- Mer information om faktorer som kan påverka prestanda för Azure Storage-åtgärder finns i Svarstid i Blob Storage.
- En lista över designöverväganden för att optimera prestanda för appar med bloblagring finns i Checklista för prestanda och skalbarhet för Blob Storage.