Jalankan tugas secara bersamaan untuk memaksimalkan penggunaan simpul komputasi Batch

Anda dapat memaksimalkan penggunaan sumber daya pada sejumlah kecil simpul komputasi di kumpulan Anda dengan menjalankan lebih dari satu tugas secara bersamaan pada setiap simpul.

Meski beberapa skenario bekerja paling baik dengan semua sumber daya simpul yang didedikasikan untuk satu tugas, beban kerja tertentu mungkin melihat waktu kerja yang lebih pendek dan biaya yang lebih rendah saat beberapa tugas berbagi sumber daya tersebut. Pertimbangkan skenario berikut:

  • Minimalkan transfer data untuk tugas yang dapat berbagi data. Anda dapat secara dramatis mengurangi biaya transfer data dengan menyalin data bersama ke sejumlah kecil simpul, lalu menjalankan tugas secara paralel pada setiap simpul. Strategi ini terutama berlaku jika data yang akan disalin ke setiap simpul harus ditransfer antar wilayah geografis.
  • Maksimalkan penggunaan memori untuk tugas yang memerlukan memori dalam jumlah besar, tetapi hanya selama waktu yang singkat, dan pada waktu variabel selama eksekusi. Anda dapat menggunakan simpul komputasi yang lebih sedikit, tetapi lebih besar dengan lebih banyak memori untuk menangani lonjakan tersebut secara efisien. Simpul ini memiliki beberapa tugas yang berjalan secara paralel pada setiap simpul, tetapi setiap tugas dapat memanfaatkan memori node yang berlimpah pada waktu yang berbeda.
  • Mitigasi batas angka simpul saat komunikasi antar-simpul diperlukan dalam kumpulan. Saat ini, kumpulan yang dikonfigurasi untuk komunikasi antar-simpul dibatasi hingga 50 simpul komputasi. Jika setiap simpul dalam kumpulan seperti itu dapat menjalankan tugas secara paralel, sejumlah besar tugas dapat dijalankan secara bersamaan.
  • Replikasi klaster komputasi lokal, seperti saat pertama kali Anda memindahkan lingkungan komputasi ke Azure. Jika solusi lokal Anda saat ini menjalankan beberapa tugas per simpul komputasi, Anda dapat meningkatkan jumlah maksimum tugas simpul untuk lebih mencerminkan konfigurasi tersebut.

Contoh skenario

Misalnya, bayangkan aplikasi tugas dengan persyaratan CPU dan memori sedemikian rupa sehingga node Standar_D1 sudah memadai. Namun, untuk menyelesaikan pekerjaan dalam waktu yang diperlukan, dibutuhkan 1.000 simpul seperti ini.

Alih-alih menggunakan simpul Standard_D1 yang memiliki satu inti CPU, Anda dapat menggunakan simpul Standard_D14 yang masing-masing memiliki 16 inti, dan mengaktifkan eksekusi tugas paralel. Anda berpotensi menggunakan 16 kali lebih sedikit simpul alih-alih 1.000 simpul, hanya 63 yang diperlukan. Jika file aplikasi besar atau data referensi diperlukan untuk setiap simpul, durasi kerja dan efisiensi ditingkatkan, karena data disalin menjadi hanya 63 simpul.

Aktifkan eksekusi tugas paralel

Anda mengonfigurasi simpul komputasi untuk eksekusi tugas paralel di tingkat kumpulan. Dengan pustaka .NET Batch, atur properti CloudPool.TaskSlotsPerNode saat Anda membuat kumpulan. Jika Anda menggunakan REST API Batch, atur elemen taskSlotsPerNode di badan permintaan selama pembuatan kumpulan.

Catatan

Anda dapat mengatur taskSlotsPerNode elemen dan properti TaskSlotsPerNode hanya pada waktu pembuatan kumpulan. Elemen dan properti tidak dapat dimodifikasi setelah kumpulan dibuat.

Microsoft Azure Batch memungkinkan Anda mengatur slot tugas per simpul hingga (4x) jumlah inti simpul. Misalnya, jika kumpulan dikonfigurasi dengan simpul berukuran "Large" (empat inti), maka taskSlotsPerNode dapat diatur ke 16. Namun, terlepas dari berapa banyak inti yang dimiliki simpul tersebut, Anda tidak dapat memiliki lebih dari 256 slot tugas per simpul. Untuk detail tentang jumlah inti untuk setiap ukuran simpul, lihat Ukuran untuk Cloud Services (klasik). Untuk informasi selengkapnya tentang batas layanan, lihat Kuota dan batas layanan Batch.

Tip

Pastikan untuk memperhitungkan taskSlotsPerNodenilai saat Anda membuat rumus skala otomatis untuk kumpulan Anda. Misalnya, rumus yang mengevaluasi $RunningTasks dapat dipengaruhi secara dramatis oleh peningkatan tugas per simpul. Untuk informasi selengkapnya, lihat Membuat rumus otomatis untuk menskalakan simpul komputasi dalam kumpulan Batch.

Tentukan distribusi tugas

Saat mengaktifkan tugas bersamaan, penting untuk menentukan bagaimana Anda ingin tugas didistribusikan di seluruh simpul dalam kumpulan.

Dengan menggunakan properti CloudPool.TaskSchedulingPolicy, Anda dapat menentukan bahwa tugas harus ditetapkan secara merata di semua simpul dalam kumpulan ("menyebar"). Atau Anda dapat menentukan bahwa tugas sebanyak mungkin harus ditetapkan ke setiap simpul sebelum tugas ditetapkan ke simpul lain dalam kumpulan ("packing").

Sebagai contoh, pertimbangkan kumpulan simpul Standard_D14 (dalam contoh sebelumnya) yang dikonfigurasi dengan nilai CloudPool.TaskSlotsPerNode 16. Jika CloudPool.TaskSchedulingPolicy dikonfigurasi dengan ComputeNodeFillType dari Pack, itu akan memaksimalkan penggunaan semua 16 inti dari tiap simpul dan memungkinkan kumpulan autoscaling menghapus simpul yang tidak digunakan (simpul tanpa tugas yang ditetapkan) dari kumpulannya. Autoscaling meminimalkan penggunaan sumber daya dan dapat menghemat uang.

Tentukan slot variabel per tugas

Tugas dapat ditentukan dengan properti CloudTask.RequiredSlots , menentukan berapa banyak slot yang diperlukan untuk berjalan pada simpul komputasi. Nilai default adalah 1. Anda dapat mengatur slot tugas variabel jika tugas Anda memiliki bobot yang berbeda yang terkait dengan penggunaan sumber dayanya pada simpul komputasi. Slot tugas variabel memungkinkan setiap simpul komputasi memiliki jumlah tugas yang berjalan bersamaan yang wajar tanpa sumber daya sistem yang luar biasa seperti CPU atau memori.

Misalnya, untuk kumpulan dengan propertitaskSlotsPerNode = 8, Anda dapat mengirimkan tugas intensif CPU multiinti yang diperlukanrequiredSlots = 8, sementara tugas lain dapat diatur ke requiredSlots = 1. Ketika beban kerja campuran ini dijadwalkan, tugas intensif CPU berjalan secara eksklusif pada simpul komputasi mereka, sementara tugas lain dapat berjalan secara bersamaan (hingga delapan tugas sekaligus) pada simpul lain. Beban kerja campuran membantu Anda menyeimbangkan beban kerja di seluruh simpul komputasi dan meningkatkan efisiensi penggunaan sumber daya.

Pastikan Anda tidak menentukan tugas requiredSlots agar lebih besar dari kumpulan taskSlotsPerNode, atau tugas tidak pernah berjalan. Layanan Batch saat ini tidak memvalidasi konflik ini saat Anda mengirimkan tugas. Ini tidak memvalidasi konflik, karena pekerjaan mungkin tidak memiliki kumpulan yang terikat pada waktu pengiriman, atau dapat berubah ke kumpulan yang berbeda dengan menonaktifkan/mengaktifkan kembali.

Tip

Saat menggunakan slot tugas variabel, ada kemungkinan tugas besar dengan slot yang lebih diperlukan untuk sementara dapat gagal dijadwalkan karena tidak cukup slot yang tersedia pada simpul komputasi apa pun, bahkan saat masih ada slot menganggur pada beberapa simpul. Anda dapat meningkatkan prioritas pekerjaan untuk tugas-tugas ini untuk meningkatkan kesempatan mereka untuk bersaing untuk slot yang tersedia pada simpul.

Layanan Batch memancarkan TaskScheduleFailEvent ketika gagal menjadwalkan tugas untuk dijalankan dan terus mencoba kembali penjadwalan hingga slot yang diperlukan tersedia. Anda dapat mendengarkan acara tersebut untuk mendeteksi potensi masalah penjadwalan tugas dan menguranginya.

Contoh Batch .NET

Cuplikan kode API Batch .NET berikut menunjukkan cara membuat kumpulan dengan beberapa slot tugas per simpul dan cara mengirimkan tugas dengan slot yang diperlukan.

Membuat kumpulan dengan beberapa slot tugas per simpul

Cuplikan kode ini menunjukkan permintaan untuk membuat kumpulan yang berisi empat simpul, dengan empat slot tugas yang diizinkan per simpul. Ini menentukan kebijakan penjadwalan tugas yang mengisi setiap simpul dengan tugas sebelum menetapkan tugas ke simpul lain di kumpulan.

Untuk informasi selengkapnya tentang menambahkan kumpulan dengan menggunakan Batch .NET API, lihat BatchClient.PoolOperations.CreatePool.

CloudPool pool =
    batchClient.PoolOperations.CreatePool(
        poolId: "mypool",
        targetDedicatedComputeNodes: 4
        virtualMachineSize: "standard_d1_v2",
        VirtualMachineConfiguration: new VirtualMachineConfiguration(
            imageReference: new ImageReference(
                                publisher: "MicrosoftWindowsServer",
                                offer: "WindowsServer",
                                sku: "2019-datacenter-core",
                                version: "latest"),
            nodeAgentSkuId: "batch.node.windows amd64");

pool.TaskSlotsPerNode = 4;
pool.TaskSchedulingPolicy = new TaskSchedulingPolicy(ComputeNodeFillType.Pack);
pool.Commit();

Membuat tugas dengan slot yang diperlukan

Cuplikan kode ini membuat tugas dengan nondefault requiredSlots. Tugas ini berjalan ketika ada cukup slot gratis yang tersedia pada simpul komputasi.

CloudTask task = new CloudTask(taskId, taskCommandLine)
{
    RequiredSlots = 2
};

Daftar simpul komputasi dengan hitungan untuk menjalankan tugas dan slot

Cuplikan kode ini mencantumkan semua simpul komputasi dalam kumpulan dan mencetak hitungan untuk menjalankan tugas dan slot tugas per simpul.

ODATADetailLevel nodeDetail = new ODATADetailLevel(selectClause: "id,runningTasksCount,runningTaskSlotsCount");
IPagedEnumerable<ComputeNode> nodes = batchClient.PoolOperations.ListComputeNodes(poolId, nodeDetail);

await nodes.ForEachAsync(node =>
{
    Console.WriteLine(node.Id + " :");
    Console.WriteLine($"RunningTasks = {node.RunningTasksCount}, RunningTaskSlots = {node.RunningTaskSlotsCount}");

}).ConfigureAwait(continueOnCapturedContext: false);

Daftar hitungan tugas untuk pekerjaan tersebut

Cuplikan kode ini mendapatkan jumlah tugas untuk pekerjaan tersebut, yang mencakup jumlah tugas dan slot tugas per status tugas.

TaskCountsResult result = await batchClient.JobOperations.GetJobTaskCountsAsync(jobId);

Console.WriteLine("\t\tActive\tRunning\tCompleted");
Console.WriteLine($"TaskCounts:\t{result.TaskCounts.Active}\t{result.TaskCounts.Running}\t{result.TaskCounts.Completed}");
Console.WriteLine($"TaskSlotCounts:\t{result.TaskSlotCounts.Active}\t{result.TaskSlotCounts.Running}\t{result.TaskSlotCounts.Completed}");

Contoh Batch REST

Cuplikan kode API Batch REST berikut menunjukkan cara membuat kumpulan dengan beberapa slot tugas per simpul dan cara mengirimkan tugas dengan slot yang diperlukan.

Membuat kumpulan dengan beberapa slot tugas per simpul

Cuplikan ini menunjukkan permintaan untuk membuat kumpulan yang berisi dua simpul besar dengan maksimum empat tugas per simpul.

Untuk informasi selengkapnya tentang menambahkan kumpulan dengan menggunakan REST API, lihat Menambahkan kumpulan ke akun.

{
  "odata.metadata":"https://myaccount.myregion.batch.azure.com/$metadata#pools/@Element",
  "id":"mypool",
  "vmSize":"large",
  "virtualMachineConfiguration": {
    "imageReference": {
      "publisher": "canonical",
      "offer": "ubuntuserver",
      "sku": "20.04-lts"
    },
    "nodeAgentSKUId": "batch.node.ubuntu 20.04"
  },
  "targetDedicatedComputeNodes":2,
  "taskSlotsPerNode":4,
  "enableInterNodeCommunication":true,
}

Membuat tugas dengan slot yang diperlukan

Cuplikan ini menunjukkan permintaan untuk menambahkan tugas dengan nondefault requiredSlots. Tugas ini hanya berjalan ketika ada cukup slot gratis yang tersedia pada simpul komputasi.

{
  "id": "taskId",
  "commandLine": "bash -c 'echo hello'",
  "userIdentity": {
    "autoUser": {
      "scope": "task",
      "elevationLevel": "nonadmin"
    }
  },
  "requiredSLots": 2
}

Sampel kode di GitHub

Proyek ParallelTasks di GitHub menggambarkan penggunaan properti CloudPool.TaskSlotsPerNode.

Aplikasi konsol C# ini menggunakan pustakaBatch .NET untuk membuat kumpulan dengan satu atau beberapa simpul komputasi. Ini menjalankan sejumlah tugas yang dapat dikonfigurasi pada simpul tersebut untuk menyimulasikan beban variabel. Output dari aplikasi menunjukkan simpul mana yang menjalankan setiap tugas. Aplikasi ini juga memberikan ringkasan parameter dan durasi pekerjaan.

Contoh berikut menunjukkan bagian ringkasan output dari dua eksekusi aplikasi sampel ParallelTasks yang berbeda. Durasi kerja yang ditampilkan di sini tidak termasuk waktu pembuatan kumpulan, karena setiap pekerjaan diserahkan ke kumpulan yang dibuat sebelumnya yang simpul komputasinya berada dalam status Diam pada waktu penyerahan.

Eksekusi pertama dari aplikasi contoh menunjukkan bahwa dengan satu simpul dalam kumpulan dan pengaturan default satu tugas per simpul, durasi pekerjaan lebih dari 30 menit.

Nodes: 1
Node size: large
Task slots per node: 1
Max slots per task: 1
Tasks: 32
Duration: 00:30:01.4638023

Proses kedua sampel menunjukkan penurunan durasi kerja yang signifikan. Pengurangan ini karena kumpulan dikonfigurasi dengan empat tugas per simpul, memungkinkan eksekusi tugas paralel untuk menyelesaikan pekerjaan dalam hampir seperempat waktu.

Nodes: 1
Node size: large
Task slots per node: 4
Max slots per task: 1
Tasks: 32
Duration: 00:08:48.2423500

Langkah berikutnya