Öğretici: .NET API’si kullanarak Azure Batch ile paralel iş yükü çalıştırma

Büyük ölçekli paralel ve yüksek performanslı bilgi işlem (HPC) toplu işlerini Azure’da verimli bir şekilde çalıştırmak için Azure Batch’i kullanın. Bu öğreticide, Batch kullanarak paralel iş yükü çalıştırmaya ilişkin bir C# örneği açıklanmaktadır. Genel bir Batch uygulaması iş akışı hakkında bilgi alacak ve Batch ve Depolama kaynakları ile programlı olarak etkileşimde bulunmayı öğreneceksiniz.

  • Batch hesabınıza bir uygulama paketi ekleyin.
  • Batch ve Depolama hesaplarıyla kimlik doğrulaması.
  • Giriş dosyalarını Depolama'ya yükleyin.
  • Bir uygulamayı çalıştırmak için işlem düğümleri havuzu oluşturun.
  • Giriş dosyalarını işlemek için bir iş ve görevler oluşturun.
  • Görev yürütmeyi izleyin.
  • Çıkış dosyalarını alın.

Bu öğreticide, ffmpeg açık kaynak aracını kullanarak MP4 medya dosyalarını paralel olarak MP3 biçimine dönüştürebilirsiniz.

Azure aboneliğiniz yoksa başlamadan önce birücretsiz Azure hesabı oluşturun.

Önkoşullar

Azure'da oturum açma

Azure Portal’ında oturum açın.

Uygulama paketi ekleme

Batch hesabınıza uygulama paketi olarak ffmpeg eklemek için Azure portalını kullanın. Uygulama paketleri, görev uygulamalarını ve havuzunuzdaki işlem düğümlerine dağıtımlarını yönetmenize yardımcı olur.

  1. Azure portalında Diğer hizmetler>Batch hesapları'na tıklayın ve Batch hesabınızın adını seçin.

  2. Uygulamalar>Ekle’ye tıklayın.

    Toplu iş hesabının Uygulamalar bölümünün ekran görüntüsü.

  3. Uygulama Kimliği alanına ffmpeg yazın ve Sürüm alanına 4.3.1 paket sürümünü girin. İndirdiğiniz ffmpeg zip dosyasını ve ardından Gönder'i seçin. ffmpeg uygulama paketi, Batch hesabınıza eklenir.

    Uygulama ekle bölümündeki Kimlik ve sürüm alanlarının ekran görüntüsü.

Hesap kimlik bilgilerini alma

Bu örnekte, Batch ve depolama hesaplarınız için kimlik bilgileri sağlamanız gerekir. Gerekli kimlik bilgilerini almanın kolay yolu Azure portalındadır. (Bu kimlik bilgilerini ayrıca Azure API'lerini veya komut satırı araçlarını kullanarak da alabilirsiniz.)

  1. Tüm hizmetler>Batch hesapları'nı ve ardından Batch hesabınızın adını seçin.

  2. Batch kimlik bilgilerini görmek için Anahtarlar'ı seçin. Batch hesabı, URL ve Birincil erişim anahtarı değerlerini metin düzenleyiciye kopyalayın.

  3. Depolama hesabı adını ve anahtarlarını görmek için Depolama hesabı'nı seçin. Depolama hesabı adı ve Key1 değerlerini bir metin düzenleyiciye kopyalayın.

Örnek uygulamayı indirme ve çalıştırma

Örnek uygulamayı indirme

GitHub’dan örnek uygulamayı indirin veya kopyalayın. Örnek uygulama deposunu bir Git istemcisi ile kopyalamak için aşağıdaki komutu kullanın:

git clone https://github.com/Azure-Samples/batch-dotnet-ffmpeg-tutorial.git

BatchDotNetFfmpegTutorial.sln Visual Studio çözüm dosyasını içeren dizine gidin.

Ayrıca, çözümdeki ffmpeg uygulama paketi başvurusunun Batch hesabınıza yüklediğiniz ffmpeg paketinin tanımlayıcısı ve sürümüyle eşleştiğinden emin olun. Örneğin, ffmpeg ve 4.3.1.

const string appPackageId = "ffmpeg";
const string appPackageVersion = "4.3.1";

Örnek projeyi derleme ve çalıştırma

Uygulamayı Visual Studio'da veya dotnet build ve dotnet run komutlarıyla komut satırında derleyip çalıştırın. Uygulamayı çalıştırdıktan sonra, uygulamanın her bir parçasının ne işe yaradığını öğrenmek üzere kodu gözden geçirin. Örneğin Visual Studio'da:

  1. Çözüm Gezgini'da çözüme sağ tıklayın ve Çözüm Derle'yi seçin.

  2. İstenirse, herhangi bir NuGet paketinin geri yüklenmesini onaylayın. Eksik paketleri indirmeniz gerekirse, NuGet Paket Yöneticisi’nin yüklü olduğundan emin olun.

  3. Çözümü çalıştırın. Örnek uygulamayı çalıştırdığınızda, konsol çıktısı aşağıdakine benzer. Yürütme sırasında, havuzun işlem düğümleri başlatıldığı sırada Monitoring all tasks for 'Completed' state, timeout in 00:30:00... konumunda bir duraklama yaşarsınız.

Sample start: 11/19/2018 3:20:21 PM

Container [input] created.
Container [output] created.
Uploading file LowPriVMs-1.mp4 to container [input]...
Uploading file LowPriVMs-2.mp4 to container [input]...
Uploading file LowPriVMs-3.mp4 to container [input]...
Uploading file LowPriVMs-4.mp4 to container [input]...
Uploading file LowPriVMs-5.mp4 to container [input]...
Creating pool [WinFFmpegPool]...
Creating job [WinFFmpegJob]...
Adding 5 tasks to job [WinFFmpegJob]...
Monitoring all tasks for 'Completed' state, timeout in 00:30:00...
Success! All tasks completed successfully within the specified timeout period.
Deleting container [input]...

Sample end: 11/19/2018 3:29:36 PM
Elapsed time: 00:09:14.3418742

Havuz, işlem düğümleri, iş ve görevleri izlemek için Azure portalında Batch hesabınıza gidin. Örneğin, havuzunuzdaki işlem düğümlerinin ısı haritasını görmek için Havuzlar>WinFFmpegPool öğesine tıklayın.

Görevler çalıştırılırken ısı haritası aşağıdakine benzer:

Azure portalındaki havuz ısı haritasının ekran görüntüsü.

Varsayılan yapılandırmasında uygulama çalıştırıldığında tipik yürütme süresi yaklaşık 10 dakikadır. En uzun süreyi havuz oluşturma işlemi alır.

Çıkış dosyalarını alma

ffmpeg görevleri tarafından oluşturulan çıkış MP3 dosyalarını indirmek için Azure portalını kullanabilirsiniz.

  1. Tüm hizmetler>Depolama hesapları seçeneğine ve sonra da depolama hesabınızın adına tıklayın.
  2. Bloblar>çıkış seçeneğine tıklayın.
  3. Çıkış MP3 dosyalarından birine sağ tıklayın ve ardından İndir’e tıklayın. Dosyayı açmak veya kaydetmek için tarayıcınızdaki yönergeleri izleyin.

Çıkış dosyasını indirme

Bu örnekte gösterilmese de dosyaları programlamayla işlem düğümlerinden veya depolama kapsayıcısından indirebilirsiniz.

Kodu gözden geçirin

Aşağıdaki bölümlerde örnek uygulama, Batch hizmetinde iş yükünü işlemeyi gerçekleştiren adımlara ayrılmıştır. Örnekteki her kod satırı tartışılmadığından, bu makalenin geri kalanını okurken çözümdeki dosya Program.cs bakın.

Blob ve Batch istemcilerinde kimlik doğrulaması

Uygulama, bağlı depolama hesabıyla etkileşime geçmek için .NET için Azure.Storage.Blobs Kitaplığı'nı kullanır. Hesap Uri'sine başvuru alan ve DefaultAzureCredential gibi kimlik doğrulama belirteci gerçekleştiren BlobServiceClient sınıfını kullanma.

// TODO: Replace <storage-account-name> with your actual storage account name
Uri accountUri = new Uri("https://<storage-account-name>.blob.core.windows.net/");
BlobServiceClient blobClient = new BlobServiceClient(accountUri, new DefaultAzureCredential());

Uygulama, Batch hizmetinde havuzu oluşturmak için Kaynak yöneticisinin ArmClient'ı aracılığıyla BatchAccountResource'a bir başvuru oluşturur. Örnekteki Arm istemcisi DefaultAzureCredential kimlik doğrulamasını kullanır.

ArmClient _armClient = new ArmClient(new DefaultAzureCredential());
var batchAccountIdentifier = ResourceIdentifier.Parse(BatchAccountResourceID);
BatchAccountResource batchAccount = await _armClient.GetBatchAccountResource(batchAccountIdentifier).GetAsync();

Uygulama, Batch hizmetinde ve işleri ve görevleri oluşturmak için bir BatchClient nesnesi oluşturur. Örnekteki Batch istemcisi DefaultAzureCredential kimlik doğrulamasını kullanır.

// TODO: Replace <batch-account-name> with your actual storage account name
Uri batchUri = new Uri("https://<batch-account-name>t.eastus.batch.azure.com");
BatchClient _batchClient = new BatchClient(batchUri, new DefaultAzureCredential());

Giriş dosyalarını karşıya yükleme

Uygulama, giriş dosyaları için bir depolama kapsayıcısı (MP4 biçimi) ve görev çıkışı için bir kapsayıcı oluşturmak üzere blobServerClient nesnesini CreateContainerIfNotExistc yöntemine geçirir.

CreateContainerIfNotExist(blobClient, inputContainerName);
CreateContainerIfNotExist(blobClient, outputContainerName);

Ardından, dosyalar yerel InputFiles klasöründen giriş kapsayıcısına yüklenir. Depolama alanındaki dosyalar, Batch hizmetinin daha sonra işlem düğümlerine indirebileceği Batch ResourceFile nesneleri olarak tanımlanır.

Program.cs'daki iki yöntem, dosyaların karşıya yüklenmesine dahil edilir:

  • UploadFilesToContainerAsync: Parametreye ResourceFile geçirilen inputFilePaths her dosyayı karşıya yüklemek için bir nesne koleksiyonu ve dahili çağrılar UploadResourceFileToContainerAsync döndürür.
  • UploadResourceFileToContainerAsync: Her dosyayı blob olarak giriş kapsayıcısına yükler. Dosyayı karşıya yükledikten sonra blob için paylaşılan erişim imzası (SAS) alır ve onu temsil eden bir ResourceFile nesne döndürür.
string inputPath = Path.Combine(Environment.CurrentDirectory, "InputFiles");

List<string> inputFilePaths = new List<string>(Directory.GetFileSystemEntries(inputPath, "*.mp4",
    SearchOption.TopDirectoryOnly));

List<ResourceFile> inputFiles = await UploadFilesToContainerAsync(
  blobClient,
  inputContainerName,
  inputFilePaths);

Dosyaları .NET ile blob olarak bir depolama hesabına yükleme hakkında ayrıntılar için bkz. .NET kullanarak blobları yükleme, indirme ve listeleme.

İşlem düğümleri havuzu oluşturma

Ardından örnek, CreatePoolIfNotExistAsync çağrısıyla Batch hesabında bir işlem düğümü havuzu oluşturur. Bu tanımlı yöntem BatchAccountResource.GetBatchAccountPools() kullanır . Düğüm sayısını, VM boyutunu ve havuz yapılandırmasını ayarlamak için CreateOrUpdateAsync yöntemi. Burada bir BatchVmConfiguration nesnesi, Azure Market yayımlanan bir Windows Server görüntüsüne BatchImageReference belirtir. Batch, Azure Market’te çok çeşitli VM görüntülerinin yanı sıra özel VM görüntülerini destekler.

Düğüm sayısı ve VM boyutu, tanımlı sabitler kullanılarak ayarlanır. Batch ayrılmış düğümleri ve Spot düğümleri destekler ve havuzlarınızda ya da her ikisini birden kullanabilirsiniz. Adanmış düğümler, havuzunuz için ayrılmıştır. Spot düğümler, Azure'daki fazla VM kapasitesinden daha düşük bir fiyata sunulur. Azure yeterli kapasiteye sahip değilse spot düğümler kullanılamaz duruma gelir. Örnek varsayılan olarak Standard_A1_v2 boyutu yalnızca 5 Spot düğümü içeren bir havuz oluşturur.

Not

Düğüm kotalarınızı denetlediğinizden emin olun. Kota isteği oluşturma yönergeleri için bkz . Batch hizmeti kotaları ve sınırları .

ffmpeg uygulaması, havuz yapılandırmasına bir ApplicationPackageReference eklenerek işlem düğümlerine dağıtılır.

var credential = new DefaultAzureCredential();
ArmClient _armClient = new ArmClient(credential);

var batchAccountIdentifier = ResourceIdentifier.Parse(BatchAccountResourceID);
BatchAccountResource batchAccount = await _armClient.GetBatchAccountResource(batchAccountIdentifier).GetAsync();

BatchAccountPoolCollection collection = batchAccount.GetBatchAccountPools();
if (collection.Exists(poolId) == false)
{
    var poolName = poolId;
    var imageReference = new BatchImageReference()
    {
        Publisher = "MicrosoftWindowsServer",
        Offer = "WindowsServer",
        Sku = "2019-datacenter-smalldisk",
        Version = "latest"
    };
    string nodeAgentSku = "batch.node.windows amd64";


    ArmOperation<BatchAccountPoolResource> armOperation = await batchAccount.GetBatchAccountPools().CreateOrUpdateAsync(
        WaitUntil.Completed, poolName, new BatchAccountPoolData()
        {
            VmSize = "Standard_DS1_v2",
            DeploymentConfiguration = new BatchDeploymentConfiguration()
            {
                VmConfiguration = new BatchVmConfiguration(imageReference, nodeAgentSku)
            },
            ScaleSettings = new BatchAccountPoolScaleSettings()
            {
                FixedScale = new BatchAccountFixedScaleSettings()
                {
                    TargetDedicatedNodes = DedicatedNodeCount,
                    TargetLowPriorityNodes = LowPriorityNodeCount
                }
            },
            Identity = new ManagedServiceIdentity(ManagedServiceIdentityType.UserAssigned)
            {
                UserAssignedIdentities =
                {
                        [new ResourceIdentifier(ManagedIdentityId)] = new Azure.ResourceManager.Models.UserAssignedIdentity(),
                },
            },
            ApplicationPackages =
            {
                    new Azure.ResourceManager.Batch.Models.BatchApplicationPackageReference(new ResourceIdentifier(appPacakgeResourceID))
                    {
                        Version = appPackageVersion,
                    }
            },

        });
    BatchAccountPoolResource pool = armOperation.Value;

İş oluşturma

Bir Batch işi, üzerinde görevlerin çalıştırılacağı bir havuz ve iş için öncelik ile zamanlama gibi isteğe bağlı ayarları belirtir. Örnek, CreateJobAsync çağrısıyla bir iş oluşturur. Bu tanımlı yöntem, havuzunuzda bir iş oluşturmak için BatchClient.CreateJobAsync yöntemini kullanır.

 BatchJobCreateContent batchJobCreateContent = new BatchJobCreateContent(jobId, new BatchPoolInfo { PoolId = poolId });
 await batchClient.CreateJobAsync(batchJobCreateContent);

Görev oluşturma

Örnek, batchtask nesnelerinin listesini oluşturan yöntemine AddTasksAsync bir çağrı ile işte görevler oluşturur. Her BatchTask, bir CommandLine özelliği kullanarak giriş ResourceFile nesnesini işlemek üzere ffmpeg çalıştırır. ffmpeg, daha önce havuz oluşturulduğunda her bir düğüme yüklenmiştir. Burada komut satırı, her bir giriş MP4 (video) dosyasını bir MP3 (ses) dosyasına dönüştürmek için ffmpeg çalıştırır.

Örnek, komut satırını çalıştırdıktan sonra MP3 dosyası için bir OutputFile nesnesi oluşturur. Her bir görevin çıkış dosyaları (bu örnekte bir tane), görevin OutputFiles özelliği kullanılarak bağlı depolama hesabındaki bir kapsayıcıya yüklenir. Nesnede ayarlanan koşulları not edin outputFile . Görevden bir çıkış dosyası yalnızca görev başarıyla tamamlandıktan (OutputFileUploadCondition.TaskSuccess) sonra kapsayıcıya yüklenir. Diğer uygulama ayrıntıları için GitHub'da tam kod örneğine bakın.

Daha sonra örnek, görevleri createTaskAsync yöntemiyle işe ekler ve bu yöntem bunları işlem düğümlerinde çalışacak şekilde kuyruğa alır.

Yürütülebilir dosyanın dosya yolunu indirdiğiniz sürümün adıyla değiştirin. Bu örnek kod örneği ffmpeg-4.3.1-2020-11-08-full_buildkullanır.

// Create a collection to hold the tasks added to the job:
List<BatchTaskCreateContent> tasks = new List<BatchTaskCreateContent>();

for (int i = 0; i < inputFiles.Count; i++)
{
    // Assign a task ID for each iteration
    string taskId = String.Format("Task{0}", i);

    // Define task command line to convert the video format from MP4 to MP3 using ffmpeg.
    // Note that ffmpeg syntax specifies the format as the file extension of the input file
    // and the output file respectively. In this case inputs are MP4.
    string appPath = String.Format("%AZ_BATCH_APP_PACKAGE_{0}#{1}%", appPackageId, appPackageVersion);
    string inputMediaFile = inputFiles[i].StorageContainerUrl;
    string outputMediaFile = String.Format("{0}{1}",
        System.IO.Path.GetFileNameWithoutExtension(inputMediaFile),
        ".mp3");
    string taskCommandLine = String.Format("cmd /c {0}\\ffmpeg-4.3.1-2020-11-08-full_build\\bin\\ffmpeg.exe -i {1} {2}", appPath, inputMediaFile, outputMediaFile);

    // Create a batch task (with the task ID and command line) and add it to the task list

    BatchTaskCreateContent batchTaskCreateContent = new BatchTaskCreateContent(taskId, taskCommandLine);
    batchTaskCreateContent.ResourceFiles.Add(inputFiles[i]);

    // Task output file will be uploaded to the output container in Storage.
    // TODO: Replace <storage-account-name> with your actual storage account name
    OutputFileBlobContainerDestination outputContainer = new OutputFileBlobContainerDestination("https://<storage-account-name>.blob.core.windows.net/output/" + outputMediaFile)
    {
        IdentityReference = inputFiles[i].IdentityReference,
    };

    OutputFile outputFile = new OutputFile(outputMediaFile,
                                           new OutputFileDestination() { Container = outputContainer },
                                           new OutputFileUploadConfig(OutputFileUploadCondition.TaskSuccess));
    batchTaskCreateContent.OutputFiles.Add(outputFile);

    tasks.Add(batchTaskCreateContent);
}

// Call BatchClient.CreateTaskCollectionAsync() to add the tasks as a collection rather than making a
// separate call for each. Bulk task submission helps to ensure efficient underlying API
// calls to the Batch service. 

await batchClient.CreateTaskCollectionAsync(jobId, new BatchTaskGroup(tasks));

Kaynakları temizleme

Görevleri çalıştırdıktan sonra, uygulama kendi oluşturduğu giriş depolama kapsayıcısını otomatik olarak siler ve Batch havuzu ve işini silme seçeneğini sunar. BatchClient'ın DeleteJobAsync işini silme ve silme işlemini onaylarsanız çağrılan deletePoolAsync havuzunu silme yöntemi vardır. İşlerin ve görevlerin kendileri için sizden ücret alınmasa da işlem düğümleri için ücret alınır. Bu nedenle, havuzları yalnızca gerektiğinde ayırmanız önerilir. Havuzu sildiğinizde düğümler üzerindeki tüm görev çıkışları silinir. Ancak çıkış dosyaları depolama hesabında kalır.

Kaynak grubunu, Batch hesabını ve depolama hesabını artık gerekli değilse silin. Azure portalında bu işlemi yapmak için Batch hesabına ait kaynak grubunu seçin ve Kaynak Grubunu Sil’e tıklayın.

Sonraki adımlar

Bu öğreticide, şunların nasıl yapıldığını öğrendiniz:

  • Batch hesabınıza bir uygulama paketi ekleyin.
  • Batch ve Depolama hesaplarıyla kimlik doğrulaması.
  • Giriş dosyalarını Depolama'ya yükleyin.
  • Bir uygulamayı çalıştırmak için işlem düğümleri havuzu oluşturun.
  • Giriş dosyalarını işlemek için bir iş ve görevler oluşturun.
  • Görev yürütmeyi izleyin.
  • Çıkış dosyalarını alın.

Batch iş yüklerini zamanlamak ve işlemek için .NET API'sini kullanma hakkında daha fazla örnek için GitHub'da Batch C# örneklerine bakın.