Överföra data med dataflyttbiblioteket

Kommentar

Den här artikeln innehåller vägledning för att arbeta med version 2.0.XX av Azure Storage Data Movement-biblioteket. Version 2.0.XX är för närvarande i underhållsläge och biblioteket tar bara emot korrigeringar för dataintegritet och säkerhetsproblem. Inga nya funktioner kommer att läggas till och nya lagringstjänstversioner stöds inte av biblioteket.

Betaversioner av ett modernt Data Movement-bibliotek är för närvarande under utveckling. Mer information finns i Azure Storage Data Movement Common-klientbibliotek för .NET på GitHub.

Azure Storage Data Movement-biblioteket är ett plattformsoberoende öppen källkod bibliotek som är utformat för uppladdning, nedladdning och kopiering av blobar och filer med höga prestanda. Data movement-biblioteket innehåller praktiska metoder som inte är tillgängliga i Azure Storage-klientbiblioteket för .NET. Dessa metoder ger möjlighet att ange antalet parallella åtgärder, spåra överföringsförloppet, enkelt återuppta en avbruten överföring och mycket mer.

Det här biblioteket använder också .NET Core, vilket innebär att du kan använda det när du skapar .NET-appar för Windows, Linux och macOS. Mer information om .NET Core finns i .NET Core-dokumentationen. Det här biblioteket fungerar även för traditionella .NET Framework-appar för Windows.

Det här dokumentet visar hur du skapar ett .NET Core-konsolprogram som körs i Windows, Linux och macOS och utför följande scenarier:

  • Ladda upp filer och kataloger till Blob Storage.
  • Definiera antalet parallella åtgärder vid överföring av data.
  • Spåra förloppet för dataöverföring.
  • Återuppta avbruten dataöverföring.
  • Kopiera filen från URL till Blob Storage.
  • Kopiera från Blob Storage till Blob Storage.

Förutsättningar

Konfiguration

  1. Gå till installationsguiden för .NET Core för att installera .NET Core SDK. När du väljer din miljö väljer du kommandoradsalternativet.
  2. Skapa en katalog för projektet från kommandoraden. Navigera till den här katalogen och skriv dotnet new console -o <sample-project-name> sedan för att skapa ett C#-konsolprojekt.
  3. Öppna den här katalogen i Visual Studio Code. Det här steget kan snabbt utföras via kommandoraden genom att code . skriva i Windows.
  4. Installera C#-tillägget från Visual Studio Code Marketplace. Starta om Visual Studio Code.
  5. Nu bör du se två frågor. En är för att lägga till "nödvändiga tillgångar för att skapa och felsöka". Klicka på "ja". En annan uppmaning är att återställa olösta beroenden. Klicka på "återställ".
  6. Ändra launch.json under .vscode för att använda extern terminal som en konsol. Den här inställningen bör läsas som "console": "externalTerminal"
  7. Med Visual Studio Code kan du felsöka .NET Core-program. Tryck F5 för att köra programmet och kontrollera att konfigurationen fungerar. Du bör se "Hello World!" skrivs ut till konsolen.

Lägg till dataflyttbiblioteket i projektet

  1. Lägg till den senaste versionen av dataflyttbiblioteket i dependencies avsnittet i <project-name>.csproj filen. I skrivande stund skulle den här versionen vara "Microsoft.Azure.Storage.DataMovement": "0.6.2"
  2. En uppmaning ska visas för att återställa projektet. Klicka på knappen "återställ". Du kan också återställa projektet från kommandoraden genom att skriva kommandot dotnet restore i roten i projektkatalogen.

Ändra <project-name>.csproj:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Storage.DataMovement" Version="0.6.2" />
        </ItemGroup>
    </Project>

Konfigurera programmets skelett

Det första vi gör är att konfigurera "skeleton"-koden för vårt program. Den här koden uppmanar oss att ange ett lagringskontonamn och en kontonyckel och använder dessa autentiseringsuppgifter för att skapa ett CloudStorageAccount objekt. Det här objektet används för att interagera med vårt lagringskonto i alla överföringsscenarier. Koden uppmanar oss också att välja vilken typ av överföringsåtgärd vi vill köra.

Ändra Program.cs:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.DataMovement;

namespace DMLibSample
{
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("Enter Storage account name:");
            string accountName = Console.ReadLine();

            Console.WriteLine("\nEnter Storage account key:");
            string accountKey = Console.ReadLine();

            string storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=" + accountName + ";AccountKey=" + accountKey;
            CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);

            ExecuteChoice(account);
        }

        public static void ExecuteChoice(CloudStorageAccount account)
        {
            Console.WriteLine("\nWhat type of transfer would you like to execute?\n1. Local file --> Azure Blob\n2. Local directory --> Azure Blob directory\n3. URL (e.g. Amazon S3 file) --> Azure Blob\n4. Azure Blob --> Azure Blob");
            int choice = int.Parse(Console.ReadLine());

            if(choice == 1)
            {
                TransferLocalFileToAzureBlob(account).Wait();
            }
            else if(choice == 2)
            {
                TransferLocalDirectoryToAzureBlobDirectory(account).Wait();
            }
            else if(choice == 3)
            {
                TransferUrlToAzureBlob(account).Wait();
            }
            else if(choice == 4)
            {
                TransferAzureBlobToAzureBlob(account).Wait();
            }
        }

        public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
        {

        }

        public static async Task TransferLocalDirectoryToAzureBlobDirectory(CloudStorageAccount account)
        {

        }

        public static async Task TransferUrlToAzureBlob(CloudStorageAccount account)
        {

        }

        public static async Task TransferAzureBlobToAzureBlob(CloudStorageAccount account)
        {

        }
    }
}

Ladda upp en lokal fil till en blob

Lägg till metoderna GetSourcePath och GetBlob i Program.cs:

public static string GetSourcePath()
{
    Console.WriteLine("\nProvide path for source:");
    string sourcePath = Console.ReadLine();

    return sourcePath;
}

public static CloudBlockBlob GetBlob(CloudStorageAccount account)
{
    CloudBlobClient blobClient = account.CreateCloudBlobClient();

    Console.WriteLine("\nProvide name of Blob container:");
    string containerName = Console.ReadLine();
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    container.CreateIfNotExistsAsync().Wait();

    Console.WriteLine("\nProvide name of new Blob:");
    string blobName = Console.ReadLine();
    CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

    return blob;
}

TransferLocalFileToAzureBlob Ändra metoden:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    Console.WriteLine("\nTransfer started...");
    await TransferManager.UploadAsync(localFilePath, blob);
    Console.WriteLine("\nTransfer operation complete.");
    ExecuteChoice(account);
}

Den här koden uppmanar oss att ange sökvägen till en lokal fil, namnet på en ny eller befintlig container och namnet på en ny blob. Metoden TransferManager.UploadAsync utför uppladdningen med hjälp av den här informationen.

Tryck F5 för att köra programmet. Du kan kontrollera att uppladdningen inträffade genom att visa ditt Lagringskonto med Microsoft Azure Storage Explorer.

Ange antalet parallella åtgärder

En funktion som erbjuds av dataflyttbiblioteket är möjligheten att ange antalet parallella åtgärder för att öka dataöverföringens dataflöde. Som standard anger Data Movement-biblioteket antalet parallella åtgärder till 8 * antalet kärnor på datorn.

Tänk på att många parallella åtgärder i en miljö med låg bandbredd kan överbelasta nätverksanslutningen och faktiskt förhindra att åtgärderna slutförs helt. Du måste experimentera med den här inställningen för att avgöra vad som fungerar bäst baserat på din tillgängliga nätverksbandbredd.

Nu ska vi lägga till kod som gör att vi kan ange antalet parallella åtgärder. Nu ska vi också lägga till kod som tids nog tar för överföringen att slutföras.

Lägg till en SetNumberOfParallelOperations metod i Program.cs:

public static void SetNumberOfParallelOperations()
{
    Console.WriteLine("\nHow many parallel operations would you like to use?");
    string parallelOperations = Console.ReadLine();
    TransferManager.Configurations.ParallelOperations = int.Parse(parallelOperations);
}

Ändra metoden så att den ExecuteChoice använder SetNumberOfParallelOperations:

public static void ExecuteChoice(CloudStorageAccount account)
{
    Console.WriteLine("\nWhat type of transfer would you like to execute?\n1. Local file --> Azure Blob\n2. Local directory --> Azure Blob directory\n3. URL (e.g. Amazon S3 file) --> Azure Blob\n4. Azure Blob --> Azure Blob");
    int choice = int.Parse(Console.ReadLine());

    SetNumberOfParallelOperations();

    if(choice == 1)
    {
        TransferLocalFileToAzureBlob(account).Wait();
    }
    else if(choice == 2)
    {
        TransferLocalDirectoryToAzureBlobDirectory(account).Wait();
    }
    else if(choice == 3)
    {
        TransferUrlToAzureBlob(account).Wait();
    }
    else if(choice == 4)
    {
        TransferAzureBlobToAzureBlob(account).Wait();
    }
}

Ändra metoden så att den TransferLocalFileToAzureBlob använder en timer:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    Console.WriteLine("\nTransfer started...");
    Stopwatch stopWatch = Stopwatch.StartNew();
    await TransferManager.UploadAsync(localFilePath, blob);
    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Spåra överföringsstatus

Det är användbart att veta hur lång tid det tog för data att överföras. Men att kunna se förloppet för överföringen under överföringsåtgärden skulle vara ännu bättre. För att uppnå det här scenariot måste vi skapa ett TransferContext objekt. Objektet TransferContext finns i två former: SingleTransferContext och DirectoryTransferContext. Den förra är för överföring av en enda fil och den senare är till för överföring av en katalog med filer.

Lägg till metoderna GetSingleTransferContext och GetDirectoryTransferContext i Program.cs:

public static SingleTransferContext GetSingleTransferContext(TransferCheckpoint checkpoint)
{
    SingleTransferContext context = new SingleTransferContext(checkpoint);

    context.ProgressHandler = new Progress<TransferStatus>((progress) =>
    {
        Console.Write("\rBytes transferred: {0}", progress.BytesTransferred );
    });

    return context;
}

public static DirectoryTransferContext GetDirectoryTransferContext(TransferCheckpoint checkpoint)
{
    DirectoryTransferContext context = new DirectoryTransferContext(checkpoint);

    context.ProgressHandler = new Progress<TransferStatus>((progress) =>
    {
        Console.Write("\rBytes transferred: {0}", progress.BytesTransferred );
    });

    return context;
}

Ändra metoden så att den TransferLocalFileToAzureBlob använder GetSingleTransferContext:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    Console.WriteLine("\nTransfer started...\n");
    Stopwatch stopWatch = Stopwatch.StartNew();
    await TransferManager.UploadAsync(localFilePath, blob, null, context);
    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Återuppta en avbruten överföring

En annan praktisk funktion som erbjuds av dataflyttbiblioteket är möjligheten att återuppta en avbruten överföring. Nu ska vi lägga till kod som gör att vi tillfälligt kan avbryta överföringen genom att cskriva och sedan återuppta överföringen 3 sekunder senare.

Ändra TransferLocalFileToAzureBlob:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    try
    {
        task = TransferManager.UploadAsync(localFilePath, blob, null, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetSingleTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.UploadAsync(localFilePath, blob, null, context);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Hittills har vårt checkpoint värde alltid angetts till null. Om vi avbryter överföringen hämtar vi den sista kontrollpunkten för vår överföring och använder sedan den här nya kontrollpunkten i vår överföringskontext.

Överföra en lokal katalog till Blob Storage

Det skulle vara en besvikelse om dataflyttbiblioteket bara kunde överföra en fil i taget. Lyckligtvis är detta inte fallet. Data movement-biblioteket ger möjlighet att överföra en katalog med filer och alla dess underkataloger. Nu ska vi lägga till kod som gör att vi kan göra just det.

Lägg först till metoden GetBlobDirectory i Program.cs:

public static CloudBlobDirectory GetBlobDirectory(CloudStorageAccount account)
{
    CloudBlobClient blobClient = account.CreateCloudBlobClient();

    Console.WriteLine("\nProvide name of Blob container. This can be a new or existing Blob container:");
    string containerName = Console.ReadLine();
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    container.CreateIfNotExistsAsync().Wait();

    CloudBlobDirectory blobDirectory = container.GetDirectoryReference("");

    return blobDirectory;
}

TransferLocalDirectoryToAzureBlobDirectoryÄndra sedan :

public static async Task TransferLocalDirectoryToAzureBlobDirectory(CloudStorageAccount account)
{
    string localDirectoryPath = GetSourcePath();
    CloudBlobDirectory blobDirectory = GetBlobDirectory(account);
    TransferCheckpoint checkpoint = null;
    DirectoryTransferContext context = GetDirectoryTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    UploadDirectoryOptions options = new UploadDirectoryOptions()
    {
        Recursive = true
    };

    try
    {
        task = TransferManager.UploadDirectoryAsync(localDirectoryPath, blobDirectory, options, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetDirectoryTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.UploadDirectoryAsync(localDirectoryPath, blobDirectory, options, context);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Det finns några skillnader mellan den här metoden och metoden för att ladda upp en enda fil. Vi använder TransferManager.UploadDirectoryAsync nu och den getDirectoryTransferContext metod som vi skapade tidigare. Dessutom tillhandahåller vi nu ett options värde för vår uppladdningsåtgärd, vilket gör att vi kan ange att vi vill inkludera underkataloger i uppladdningen.

Kopiera en fil från URL till en blob

Nu ska vi lägga till kod som gör att vi kan kopiera en fil från en URL till en Azure Blob.

Ändra TransferUrlToAzureBlob:

public static async Task TransferUrlToAzureBlob(CloudStorageAccount account)
{
    Uri uri = new Uri(GetSourcePath());
    CloudBlockBlob blob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    try
    {
        task = TransferManager.CopyAsync(uri, blob, CopyMethod.ServiceSideAsyncCopy, null, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetSingleTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.CopyAsync(uri, blob, CopyMethod.ServiceSideAsyncCopy, null, context, cancellationSource.Token);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Ett viktigt användningsfall för den här funktionen är när du behöver flytta data från en annan molntjänst (t.ex. AWS) till Azure. Så länge du har en URL som ger dig åtkomst till resursen kan du enkelt flytta resursen TransferManager.CopyAsync till Azure Blobs med hjälp av metoden . Den här metoden introducerar även en CopyMethod-parameter . I följande tabell visas tillgängliga alternativ för den här parametern:

Medlemsnamn Värde beskrivning
SyncCopy 0 Ladda ned data från källa till minne och ladda upp data från minnet till målet. För närvarande är det bara tillgängligt för kopiering från en Azure Storage-resurs till en annan.
ServiceSideAsyncCopy 1 Skicka en begäran om startkopiering till Azure Storage så att den kan utföra kopieringen. övervaka kopieringsåtgärdens förlopp tills kopian har slutförts.
ServiceSideSyncCopy 2 Kopiera innehållet i varje segment med med Placera blockera från URL, Lägg till blockera från URL eller Placera sida från URL.

Kopiera en blob

En annan funktion som tillhandahålls unikt av dataflyttbiblioteket är möjligheten att kopiera från en Azure Storage-resurs till en annan.

Ändra TransferAzureBlobToAzureBlob:

public static async Task TransferAzureBlobToAzureBlob(CloudStorageAccount account)
{
    CloudBlockBlob sourceBlob = GetBlob(account);
    CloudBlockBlob destinationBlob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    try
    {
        task = TransferManager.CopyAsync(sourceBlob, destinationBlob, CopyMethod.SyncCopy, null, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetSingleTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.CopyAsync(sourceBlob, destinationBlob, CopyMethod.SyncCopy, null, context, cancellationSource.Token);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

I det här exemplet anger vi den booleska parametern i TransferManager.CopyAsync för CopyMethod.SyncCopy att indikera att vi vill göra en synkron kopia. Det innebär att resursen laddas ned till vår lokala dator först och sedan laddas upp till Azure Blob. Det synkrona kopieringsalternativet är ett bra sätt att se till att kopieringsåtgärden har en konsekvent hastighet. Däremot beror hastigheten på en asynkron kopia på serversidan på den tillgängliga nätverksbandbredden på servern, vilket kan variera. Synkron kopiering kan dock generera ytterligare utgående kostnad jämfört med asynkron kopia. Den rekommenderade metoden är att använda synkron kopiering på en virtuell Azure-dator som finns i samma region som ditt källlagringskonto för att undvika utgående kostnader.

Dataförflyttningsprogrammet är nu klart. Det fullständiga kodexemplet är tillgängligt på GitHub.

Nästa steg

Referensdokumentation för Azure Storage Data Movement-biblioteket.

Dricks

Hantera Azure Blob Storage-resurser med Azure Storage Explorer. Azure Storage Explorer är en kostnadsfri, fristående app från Microsoft som gör att du kan hantera Azure Blob Storage-resurser. Med Azure Storage Explorer kan du skapa, läsa, uppdatera och ta bort blobcontainrar och blobbar visuellt, samt hantera åtkomst till dina blobcontainrar och blobar.