Udostępnij za pomocą


Utrwal dane zadań w usłudze Azure Storage za pomocą interfejsu API usługi Batch

Zadanie uruchomione w usłudze Azure Batch może generować dane wyjściowe po uruchomieniu. Dane wyjściowe zadania często muszą być przechowywane do pobierania przez inne zadania w zadaniu, aplikację kliencą, która wykonała zadanie lub oba te zadania. Zadania zapisują dane wyjściowe w systemie plików węzła obliczeniowego usługi Batch, ale wszystkie dane na węźle zostaną utracone w przypadku odświeżenia obrazu lub gdy węzeł opuści pulę. Zadania mogą również mieć okres przechowywania plików, po którym pliki utworzone przez zadanie zostaną usunięte. Ważne jest, aby z tych powodów zapisywać dane wyjściowe zadania, które będą potrzebne później, w magazynie danych, takim jak usługa Azure Storage.

Aby uzyskać informacje o opcjach kont kont magazynowych w Batch, zobacz Konta Batch i konta Azure Storage.

Interfejs API usługi Batch obsługuje utrwalanie danych wyjściowych w usłudze Azure Storage na potrzeby zadań podrzędnych i zadań menedżera zadań uruchamianych w pulach przy użyciu konfiguracji maszyny wirtualnej. Po dodaniu zadania można określić kontener w usłudze Azure Storage jako miejsce docelowe danych wyjściowych zadania. Następnie usługa Batch zapisuje wszystkie dane wyjściowe w tym kontenerze po zakończeniu zadania.

W przypadku używania interfejsu API usługi Batch do utrwalania danych wyjściowych zadania nie trzeba modyfikować aplikacji, która jest uruchomiona. Zamiast tego, za pomocą kilku modyfikacji aplikacji klienckiej, można utrwalić dane wyjściowe zadania z poziomu tego samego kodu, który tworzy zadanie.

Ważne

Zapisywanie danych zadań w Azure Storage za pomocą interfejsu API usługi Batch nie działa z pulami utworzonymi przed 1 lutego 2018 r.

Kiedy używam interfejsu API usługi Batch do utrwalania danych wyjściowych zadania?

Usługa Azure Batch udostępnia więcej niż jeden sposób utrwalania danych wyjściowych zadania. Korzystanie z interfejsu API usługi Batch to wygodne podejście, które najlepiej nadaje się do następujących scenariuszy:

  • Chcesz napisać kod, aby zapisywać dane wyjściowe zadania z poziomu aplikacji klienckiej, bez modyfikowania aplikacji, które to zadanie uruchamia.
  • Chcesz utrwalić dane wyjściowe z zadań Batch oraz zadań menedżera zadań w pulach utworzonych przy użyciu konfiguracji maszyny wirtualnej.
  • Chcesz zachować dane wyjściowe w kontenerze usługi Azure Storage z dowolną nazwą.
  • Chcesz utrwalić wyniki do kontenera usługi Azure Storage o nazwie zgodnej ze standardem Batch File Conventions.

Jeśli twój scenariusz różni się od wymienionych powyżej, może być konieczne rozważenie innego podejścia. Na przykład interfejs API usługi Batch nie obsługuje obecnie danych wyjściowych przesyłanych strumieniowo do usługi Azure Storage podczas działania zadania. Aby przesyłać strumieniowo dane wyjściowe, rozważ użycie biblioteki Batch File Conventions, dostępnej na platformę .NET. W przypadku innych języków należy zaimplementować własne rozwiązanie. Aby uzyskać więcej informacji na temat innych opcji, zobacz Zapis wyników zadania w usłudze Azure Storage.

Tworzenie kontenera w usłudze Azure Storage

Aby utrwały dane wyjściowe zadania w usłudze Azure Storage, należy utworzyć kontener, który służy jako miejsce docelowe dla plików wyjściowych. Utwórz kontener przed uruchomieniem zadania, najlepiej przed przesłaniem zadania, używając odpowiedniej biblioteki klienta usługi Azure Storage lub zestawu SDK. Aby uzyskać więcej informacji na temat interfejsów API usługi Azure Storage, zobacz dokumentację usługi Azure Storage.

Jeśli na przykład piszesz aplikację w języku C#, użyj biblioteki klienta usługi Azure Storage dla platformy .NET. W poniższym przykładzie pokazano, jak utworzyć kontener:

CloudBlobContainer container = storageAccount.CreateCloudBlobClient().GetContainerReference(containerName);
await container.CreateIfNotExists();

Określ pliki wyjściowe dla wyników zadania

Aby określić pliki wyjściowe zadania, utwórz kolekcję obiektów OutputFile i przypisz ją do właściwości CloudTask.OutputFiles podczas tworzenia zadania. Aby uwierzytelnić dostęp do kontenera, można użyć sygnatury dostępu współdzielonego (SAS) lub tożsamości zarządzanej.

Używanie sygnatury dostępu współdzielonego

Po utworzeniu kontenera uzyskaj sygnaturę dostępu współdzielonego (SAS) z uprawnieniami do zapisu w kontenerze. Sygnatura dostępu współdzielonego zapewnia delegowany dostęp do kontenera. Sygnatura dostępu współdzielonego (SAS) udziela dostępu z określonym zestawem uprawnień na określony przedział czasu. Usługa Batch potrzebuje sygnatury dostępu współdzielonego z uprawnieniami do zapisu, aby zapisać dane wyjściowe zadania w kontenerze. Aby uzyskać więcej informacji na temat sygnatur dostępu współdzielonego, zobacz Używanie sygnatur dostępu współdzielonego (SAS) w usłudze Azure Storage.

Po uzyskaniu sygnatury dostępu współdzielonego (SAS) przy użyciu interfejsów API usługi Azure Storage, interfejs API zwraca ciąg tokenu SAS. Ten ciąg tokenu zawiera wszystkie parametry SAS, w tym uprawnienia i okres, w którym jest on prawidłowy. Aby uzyskać dostęp do kontenera w usłudze Azure Storage przy użyciu SAS, należy dołączyć ciąg tokenu SAS do identyfikatora URI zasobu. Identyfikator URI zasobu wraz z dołączonym tokenem SAS zapewnia uwierzytelniony dostęp do usługi Azure Storage.

W poniższym przykładzie pokazano, jak uzyskać token SAS z dostępem tylko do zapisu dla kontenera, a następnie dołączyć go do identyfikatora URI kontenera.

string containerSasToken = container.GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddDays(1),
    Permissions = SharedAccessBlobPermissions.Write
});

string containerSasUrl = container.Uri.AbsoluteUri + containerSasToken;

Poniższy przykład kodu w języku C# tworzy zadanie, które zapisuje liczby losowe w pliku o nazwie output.txt. Przykład tworzy plik wyjściowy dla output.txt, który ma zostać zapisany w kontenerze. W przykładzie są również tworzone pliki wyjściowe dla wszystkich plików dziennika, które są zgodne ze wzorcem std*.txt pliku (np.stdout.txt i stderr.txt). Adres URL kontenera wymaga sygnatury dostępu współdzielonego utworzonej wcześniej dla kontenera. Usługa Batch używa SAS (sygnatury dostępu współdzielonego) do uwierzytelniania dostępu do kontenera.

new CloudTask(taskId, "cmd /v:ON /c \"echo off && set && (FOR /L %i IN (1,1,100000) DO (ECHO !RANDOM!)) > output.txt\"")
{
    OutputFiles = new List<OutputFile>
    {
        new OutputFile(
            filePattern: @"..\std*.txt",
            destination: new OutputFileDestination(
         new OutputFileBlobContainerDestination(
                    containerUrl: containerSasUrl,
                    path: taskId)),
            uploadOptions: new OutputFileUploadOptions(
            uploadCondition: OutputFileUploadCondition.TaskCompletion)),
        new OutputFile(
            filePattern: @"output.txt",
            destination: 
         new OutputFileDestination(new OutputFileBlobContainerDestination(
                    containerUrl: containerSasUrl,
                    path: taskId + @"\output.txt")),
            uploadOptions: new OutputFileUploadOptions(
            uploadCondition: OutputFileUploadCondition.TaskCompletion)),
}

Uwaga

Jeśli używasz tego przykładu z systemem Linux, pamiętaj, aby zmienić ukośniki odwrotne na ukośniki.

Korzystanie z tożsamości zarządzanej

Zamiast generować i przekazywać do usługi Batch sygnaturę dostępu współdzielonego z dostępem do zapisu do kontenera, można użyć tożsamości zarządzanej do uwierzytelnienia w usłudze Azure Storage. Tożsamość musi być przypisana do puli usługi Batch, a także mieć Storage Blob Data Contributor przypisanie roli, do której ma zostać zapisany kontener. Następnie można poinformować usługę Batch, aby użyła tożsamości zarządzanej zamiast SAS do uwierzytelniania dostępu do kontenera.

CloudBlobContainer container = storageAccount.CreateCloudBlobClient().GetContainerReference(containerName);
await container.CreateIfNotExists();

new CloudTask(taskId, "cmd /v:ON /c \"echo off && set && (FOR /L %i IN (1,1,100000) DO (ECHO !RANDOM!)) > output.txt\"")
{
    OutputFiles = new List<OutputFile>
    {
        new OutputFile(
            filePattern: @"..\std*.txt",
            destination: new OutputFileDestination(
         new OutputFileBlobContainerDestination(
                    containerUrl: container.Uri,
                    path: taskId,
                    identityReference: new ComputeNodeIdentityReference() { ResourceId = "/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name"} })),
            uploadOptions: new OutputFileUploadOptions(
            uploadCondition: OutputFileUploadCondition.TaskCompletion))
    }
}

Określanie wzorca pliku do dopasowywania

Po określeniu pliku wyjściowego można użyć właściwości OutputFile.FilePattern , aby określić wzorzec pliku do dopasowania. Wzorzec pliku może być zgodny z zerowym plikiem, pojedynczym plikiem lub zestawem plików tworzonych przez zadanie.

Właściwość FilePattern obsługuje standardowe symbole wieloznaczne systemu plików, takie jak * (w przypadku dopasowań niecyklicznych) i ** (w przypadku dopasowań cyklicznych). Na przykład, powyższy przykładowy kod określa wzorzec pliku, aby dopasowywał std*.txt bez rekurencji.

filePattern: @"..\std*.txt"

Aby przekazać pojedynczy plik, określ wzorzec pliku bez symboli wieloznacznych. Na przykład powyższy przykładowy kod określa wzorzec pliku do dopasowania z output.txt.

filePattern: @"output.txt"

Określanie warunku przekazywania

Właściwość OutputFileUploadOptions.UploadCondition zezwala na warunkowe przekazywanie plików wyjściowych. Typowym scenariuszem jest przekazanie jednego zestawu plików, jeśli zadanie zakończy się powodzeniem, oraz inny zestaw plików, jeśli zakończy się niepowodzeniem. Na przykład możesz przesłać pełne pliki dziennika tylko wtedy, gdy zadanie zakończy się niepowodzeniem i zakończy działanie z kodem zakończenia niezerowym. Podobnie możesz przekazać pliki wynikowe tylko wtedy, gdy zadanie zakończy się pomyślnie, ponieważ te pliki mogą być brakujące lub niekompletne, jeśli zadanie zakończy się niepowodzeniem.

Powyższy przykład kodu ustawia właściwość UploadCondition na TaskCompletion. To ustawienie określa, że plik ma zostać przekazany po zakończeniu zadania, bez względu na wartość kodu zakończenia.

uploadCondition: OutputFileUploadCondition.TaskCompletion

Aby uzyskać inne informacje na temat ustawień, zobacz wyliczenie OutputFileUploadCondition.

Uściślanie plików o tej samej nazwie

Zadania w ramach pracy mogą tworzyć pliki o identycznej nazwie. Na przykład stdout.txt i stderr.txt są tworzone dla każdego zadania uruchamianego w zadaniu. Ponieważ każde zadanie jest uruchamiane we własnym kontekście, te pliki nie powodują konfliktu w systemie plików węzła. Niemniej jednak, podczas przesyłania plików z wielu zadań do udostępnionego kontenera, należy rozróżniać pliki o tej samej nazwie.

OutputFileBlobContainerDestination.Path określa docelowy obiekt blob lub katalog wirtualny dla plików wyjściowych. Możesz użyć właściwości Path , aby nazwać obiekt blob lub katalog wirtualny w taki sposób, aby pliki wyjściowe o tej samej nazwie zostały unikatowo nazwane w usłudze Azure Storage. Użycie identyfikatora zadania w ścieżce jest dobrym sposobem zapewnienia unikatowych nazw i łatwego identyfikowania plików.

Jeśli właściwość FilePattern jest ustawiona na wyrażenie wieloznaczne, wszystkie pliki zgodne ze wzorcem są przekazywane do katalogu wirtualnego określonego przez właściwość Path . Jeśli na przykład kontener to mycontainer, identyfikator zadania to mytask, a wzorzec pliku to ..\std*.txt, bezwzględne identyfikatory URI do plików wyjściowych w usłudze Azure Storage będą podobne do następujących:

https://myaccount.blob.core.windows.net/mycontainer/mytask/stderr.txt
https://myaccount.blob.core.windows.net/mycontainer/mytask/stdout.txt

Jeśli właściwość FilePattern jest ustawiona na zgodną z pojedynczą nazwą pliku, co oznacza, że nie zawiera żadnych symboli wieloznacznych, wartość właściwości Path określa w pełni kwalifikowaną nazwę obiektu blob. Jeśli przewidujesz konflikty nazewnictwa z jednym plikiem z wielu zadań, dołącz nazwę katalogu wirtualnego jako część nazwy pliku, aby uściślić te pliki. Na przykład ustaw właściwość Path tak, aby zawierała identyfikator zadania, znak ogranicznika (zazwyczaj ukośnik) i nazwę pliku:

path: taskId + @"/output.txt"

Bezwzględne adresy URI do plików wynikowych dla zestawu zadań będą podobne do:

https://myaccount.blob.core.windows.net/mycontainer/task1/output.txt
https://myaccount.blob.core.windows.net/mycontainer/task2/output.txt

Aby uzyskać więcej informacji na temat katalogów wirtualnych w usłudze Azure Storage, zobacz Wyświetlanie listy obiektów blob w kontenerze.

Wiele plików wyjściowych

Gdy zadanie określa wiele plików wyjściowych, mogą wystąpić limity nałożone przez interfejs API usługi Azure Batch. Zaleca się, aby zadania były małe i zachować niską liczbę plików wyjściowych.

Jeśli wystąpią limity, rozważ zmniejszenie liczby plików wyjściowych przez zastosowanie wzorców plików lub użycie kontenerów plików, takich jak tar lub zip, w celu skonsolidowania plików wyjściowych. Alternatywnie, możesz użyć montowania lub innych metod do utrwalania danych wyjściowych (patrz Utrwalanie danych wyjściowych pracy i zadań).

Diagnozowanie błędów przekazywania plików

Jeśli przekazywanie plików wyjściowych do usługi Azure Storage zakończy się niepowodzeniem, zadanie zostanie przeniesione do stanu Ukończone i TaskExecutionInformation.Właściwość FailureInformation jest ustawiona. Sprawdź właściwość FailureInformation , aby określić, jaki błąd wystąpił. Na przykład poniżej przedstawiono błąd występujący podczas przekazywania pliku, jeśli nie można odnaleźć kontenera:

Category: UserError
Code: FileUploadContainerNotFound
Message: One of the specified Azure container(s) was not found while attempting to upload an output file

W przypadku każdego załadowania pliku usługa Batch zapisuje dwa pliki dziennika w węźle obliczeniowym: fileuploadout.txt i fileuploaderr.txt. Możesz zbadać te pliki dziennika, aby dowiedzieć się więcej na temat konkretnego błędu. W przypadkach, gdy nigdy nie podjęto próby przesłania pliku, na przykład dlatego, że samo zadanie nie mogło się uruchomić, te pliki dziennika nie będą istnieć.

Diagnozowanie wydajności przekazywania plików

Plik fileuploadout.txt rejestruje postęp przesyłania. Możesz sprawdzić ten plik, aby dowiedzieć się więcej o tym, jak długo trwa przekazywanie plików. Należy pamiętać, że istnieje wiele czynników mających wpływ na wydajność przekazywania, w tym rozmiar węzła, inne działanie w węźle w momencie przekazywania, czy kontener docelowy znajduje się w tym samym regionie co pula usługi Batch, ile węzłów jest przekazywanych do konta magazynu w tym samym czasie i tak dalej.

Używanie interfejsu API usługi Batch ze standardem Konwencji plików wsadowych

W przypadku utrwalania danych wyjściowych zadania przy użyciu interfejsu API usługi Batch można nazwać kontener docelowy i obiekty blob, jak tylko chcesz. Możesz również nazwać je zgodnie z Batch File Conventions standard. Standard Konwencji Plików określa nazwy kontenera docelowego i obiektu blob w usłudze Azure Storage dla danego pliku wyjściowego na podstawie nazw pracy i zadania. Jeśli używasz standardu File Conventions do nazewnictwa plików wyjściowych, pliki wyjściowe są dostępne do wyświetlania w witrynie Azure Portal.

Jeśli programujesz w języku C#, możesz użyć metod wbudowanych w bibliotekę Konwencji plików usługi Batch dla platformy .NET. Ta biblioteka tworzy poprawnie nazwane kontenery i ścieżki blobów. Na przykład możesz wywołać interfejs API, aby uzyskać poprawną nazwę kontenera na podstawie nazwy zadania:

string containerName = job.OutputStorageContainerName();

Możesz użyć metody CloudJobExtensions.GetOutputStorageContainerUrl , aby zwrócić adres URL sygnatury dostępu współdzielonego (SAS), który jest używany do zapisywania w kontenerze. Następnie można przekazać tę sygnaturę dostępu współdzielonego (SAS) do konstruktora OutputFileBlobContainerDestination.

Jeśli programujesz w języku innym niż C#, musisz samodzielnie zaimplementować standard Konwencji plików.

Przykład kodu

Przykładowy projekt PersistOutputs jest jednym z przykładów kodu usługi Azure Batch w witrynie GitHub. To rozwiązanie programu Visual Studio pokazuje, jak używać biblioteki klienta usługi Batch dla platformy .NET do utrwalania danych wyjściowych zadań w magazynie trwałym. Aby uruchomić przykład, wykonaj następujące kroki:

  1. Otwórz projekt w programie Visual Studio 2019.
  2. Dodaj poświadczenia konta Batch i magazynu do pliku AccountSettings.settings w projekcie Microsoft.Azure.Batch.Samples.Common.
  3. Skompiluj (ale nie uruchamiaj) rozwiązania. Jeśli zostanie wyświetlony monit, przywróć wszystkie pakiety NuGet.
  4. Użyj portalu Azure, aby przekazać pakiet aplikacji dla PersistOutputsTask. Uwzględnij PersistOutputsTask.exe oraz jego zestawy zależne w pakiecie .zip, ustaw identyfikator aplikacji na "PersistOutputsTask" i wersję pakietu aplikacji na "1.0".
  5. Uruchom projekt PersistOutputs.
  6. Po pojawieniu się monitowania o wybór technologii przechowywania do uruchomienia przykładu, wprowadź 2, aby uruchomić przykład przy użyciu interfejsu API usługi Batch w celu utrwalenia danych wyjściowych zadania.
  7. W razie potrzeby uruchom ponownie przykład, wprowadzając 3, aby utrwalać dane wyjściowe za pomocą interfejsu API usługi Batch, a także nazwać docelowy kontener i ścieżkę obiektu blob zgodnie ze standardem Konwencje plików.

Następne kroki