Bagikan melalui


Performan dan skala dalam Fungsi Tahan Lama (Azure Functions)

Untuk mengoptimalkan performa dan skalabilitas, penting untuk memahami karakteristik penskalaan unik Durable Functions. Dalam artikel ini, kami akan menjelaskan bagaimana pekerja diskalakan berdasarkan beban, dan cara menyesuaikan berbagai parameter.

Penskalaan pekerja

Keuntungan mendasar dari konsep hub tugas adalah bahwa jumlah pekerja yang memproses item kerja hub tugas dapat terus disesuaikan. Khususnya, aplikasi dapat menambahkan lebih banyak pekerja (peluasan skala) jika pekerjaan perlu diproses lebih cepat, dan aplikasi dapat menghapus pekerja (memperkecil skala) jika tidak ada cukup pekerjaan untuk membuat pekerja sibuk. Bahkan menskalakan ke nol jika hub tugas benar-benar menganggur dapat dilakukan. Ketika diskalakan ke nol, artinya tidak ada pekerja sama sekali, dan hanya pengontrol skala dan penyimpanan saja yang harus tetap aktif.

Diagram berikut mengilustrasikan konsep ini:

Worker scaling diagram

Penskalaan otomatis

Seperti semua Azure Functions yang berjalan dalam paket Consumption dan Elastic Premium, Durable Functions mendukung skala otomatis melalui pengontrol skala Azure Functions. Pengontrol Skala memantau lama waktu tunggu pesan dan tugas sebelum diproses. Berdasarkan latensi ini, Pengontrol Skala dapat memutuskan apakah akan menambahkan atau menghapus pekerja.

Catatan

Dimulai dengan Durable Functions 2.0, aplikasi fungsi dapat dikonfigurasi untuk berjalan dalam titik akhir layanan yang dilindungi VNET dalam paket Elastic Premium. Dalam konfigurasi ini, Durable Functions memicu memulai permintaan skala alih-alih Pengontrol Skala. Untuk informasi selengkapnya, lihat Pemantauan skala runtime.

Pada paket premium, penskalaan otomatis dapat membantu menjaga jumlah pekerja (sekaligus biaya operasi) yang kira-kira sebanding dengan beban yang dialami aplikasi.

Penggunaan CPU

Fungsi orkestrator dijalankan pada satu rangkaian untuk memastikan bahwa eksekusi dapat bersifat deterministik di banyak pemutaran ulang. Karena eksekusi beralur tunggal ini, penting bahwa alur fungsi orkestrator tidak melakukan tugas yang bersifat intensif CPU, melakukan I/O, atau memblokir karena alasan apa pun. Setiap pekerjaan yang mungkin memerlukan I/O, pemblokiran, atau beberapa alur harus dipindahkan ke fungsi aktivitas.

Fungsi aktivitas memiliki semua perilaku yang sama dengan fungsi yang dipicu antrean reguler. Mereka dapat dengan aman melakukan I/O, menjalankan operasi intensif CPU, dan menggunakan beberapa alur. Karena pemicu aktivitas tanpa status, mereka dapat dengan bebas menskalakan ke jumlah VM yang tidak terbatas.

Fungsi entitas juga dijalankan pada satu rangkaian dan operasi diproses satu per satu. Namun, fungsi entitas tidak memiliki batasan jenis kode yang dapat dieksekusi.

Batas waktu fungsi

Fungsi aktivitas, orkestrator, dan entitas mematuhi batas waktu fungsi yang sama seperti semua Azure Functions. Sebagai aturan umum, Durable Functions memperlakukan batas waktu fungsi dengan cara yang sama seperti pengecualian yang tidak tertangani yang dimunculkan oleh kode aplikasi.

Misalnya, jika waktu aktivitas habis, eksekusi fungsi dicatat sebagai kegagalan, dan orkestrator diberi tahu dan akan menangani batas waktu seperti pengecualian lainnya: percobaan ulang terjadi jika ditentukan oleh panggilan, atau pengatur pengecualian dapat dijalankan.

Pembuatan batch operasi entitas

Untuk meningkatkan performa dan mengurangi biaya, satu item kerja dapat menjalankan seluruh batch operasi entitas. Pada paket konsumsi, setiap batch kemudian ditagih sebagai eksekusi satu fungsi saja.

Secara default, ukuran batch maksimum adalah 50 (untuk paket pemakaian) dan 5000 (untuk paket lainnya). Ukuran batch maksimum juga dapat dikonfigurasi dalam file host.json. Jika ukuran batch maksimum adalah 1, pembuatan batch dinonaktifkan secara efektif.

Catatan

Jika operasi entitas individu membutuhkan waktu lama untuk dijalankan, sebaiknya batasi ukuran batch maksimum untuk mengurangi risiko waktu fungsi habis, khususnya pada paket pemakaian.

Penembolokan instans

Pada umumnya, untuk memproses item kerja orkestrasi, pekerja harus

  1. Mengambil riwayat orkestrasi.
  2. Memutar ulang kode orkestrator dengan menggunakan riwayat.

Jika pekerja yang sama memproses beberapa item kerja untuk orkestrasi yang sama, penyedia penyimpanan dapat mengoptimalkan proses ini dengan melakukan penembolokan riwayat dalam memori pekerja, yang menghilangkan langkah pertama. Selain itu, penyedia penyimpanan dapat menyimpan orkestrator yang tengah melakukan eksekusi, yang menghilangkan langkah kedua dan pemutaran ulang riwayat.

Efek khas penembolokan adalah berkurangnya I/O terhadap layanan penyimpanan yang mendasar, serta throughput dan latensi yang ditingkatkan secara keseluruhan. Di sisi lain, penembolokan meningkatkan konsumsi memori pada pekerja.

Penembolokan instans saat ini didukung oleh penyedia Azure Storage dan oleh penyedia penyimpanan Netherite. Tabel di bawah ini memberikan perbandingan.

Penyedia Microsoft Azure Storage Penyedia penyimpanan Netherite Penyedia penyimpanan MSSQL
Penembolokan instans Didukung
(hanya pekerja pemrosesan .NET saja)
Didukung Tidak didukung
Pengaturan default Nonaktif Diaktifkan n/a
Mekanisme Perpanjangan Sesi Cache Instans n/a
Dokumentasi Lihat Perpanjangan sesi Lihat Cache instans n/a

Tip

Penembolokan dapat mengurangi seberapa sering riwayat diputar ulang, tetapi tidak dapat sekaligus menghilangkan pemutaran ulang. Saat mengembangkan orkestrator, kami sangat menyarankan agar Anda mengujinya pada konfigurasi yang menonaktifkan penembolokan. Perilaku pemutaran ulang agresif default dapat berguna untuk mendeteksi pelanggaran batasan kode fungsi orkestrator pada saat pengembangan.

Perbandingan mekanisme penembolokan

Penyedia menggunakan mekanisme yang berbeda untuk menerapkan penembolokan, dan menawarkan parameter yang berbeda untuk mengonfigurasi perilaku penembolokan.

  • Perpanjangan sesi, seperti yang digunakan oleh penyedia Azure Storage, menyimpan orkestrator yang tengah melakukan eksekusi dalam memori hingga orkestrator menganggur selama beberapa waktu. Parameter untuk mengontrol mekanisme ini adalah extendedSessionsEnabled dan extendedSessionIdleTimeoutInSeconds. Untuk detail lebih lanjut, lihat bagian Perpanjangan sesi pada dokumentasi penyedia Azure Storage.

Catatan

Perpanjangan sesi hanya didukung di pekerja pemrosesan .NET.

  • Cache Instans, seperti yang digunakan oleh penyedia penyimpanan Netherite, menjaga status semua instans termasuk riwayatnya dalam memori pekerja, sekaligus melacak total memori yang digunakan. Jika ukuran cache melebihi batas yang dikonfigurasi oleh InstanceCacheSizeMB, data instans yang paling jarang digunakan baru-baru ini akan dikeluarkan. Jika CacheOrchestrationCursors diatur ke true, cache juga menyimpan orkestrator yang tengah melakukan eksekusi sekaligus dengan status instans. Untuk detail lebih lanjut, lihat bagian Cache instans pada dokumentasi penyedia penyimpanan Netherite.

Catatan

Cache instans berfungsi untuk semua SDK bahasa pemrogram, tetapi opsi CacheOrchestrationCursors ini hanya tersedia untuk pekerja pemrosesan .NET.

Pembatasan konkurensi

Satu instans pekerja dapat menjalankan beberapa item kerja secara bersamaan. Sehingga, instans pekerja membantu meningkatkan paralelisme dan meningkatkan efisiensi pemanfaatan pekerja. Namun, jika pekerja mencoba memproses terlalu banyak item kerja pada saat yang sama, artinya pekerja akan menghabiskan sumber daya yang tersedia, seperti beban CPU, jumlah koneksi jaringan, atau memori yang tersedia.

Untuk memastikan bahwa pekerja individu tidak overcommit, mungkin perlu untuk membatasi konkurensi untuk setiap instans. Dengan membatasi jumlah fungsi yang berjalan bersamaan pada setiap pekerja, kita dapat menghindari habisnya batas sumber daya pada pekerja tersebut.

Catatan

Pembatasan konkurensi hanya berlaku secara lokal untuk membatasi proses yang sedang berjalan untuk setiap pekerja. Oleh karena itu, pembatasan ini tidak membatasi total throughput sistem.

Tip

Dalam beberapa kasus, pembatasan konkurensi untuk setiap pekerja benar-benar dapat meningkatkan jumlah total throughput sistem. Fenomena ini dapat terjadi ketika setiap pekerja tidak menangani terlalu banyak pekerjaan, sehingga pengontrol skala menambahkan lebih banyak pekerja untuk mengikuti antrean, yang kemudian meningkatkan total throughput.

Konfigurasi pembatasan

Batas konkurensi fungsi aktivitas, orkestrator, dan entitas dapat dikonfigurasi dalam file host.json. Pengaturan yang relevan adalah durableTask/maxConcurrentActivityFunctions untuk fungsi aktivitas dan durableTask/maxConcurrentOrchestratorFunctions untuk fungsi orkestrator dan entitas. Pengaturan ini mengontrol jumlah maksimum fungsi orkestrator, entitas, atau aktivitas yang dapat dimuat ke dalam memori pada satu pekerja.

Catatan

Orkestrasi dan entitas hanya akan dimuat ke dalam memori ketika mereka terus memproses kejadian atau operasi, atau jika penembolokan instans diaktifkan. Setelah menjalankan logika mereka dan menunggu, seperti pernyataan await (C#) atau yield (JavaScript, Python) dalam kode fungsi orkestrator, orkestrator dan entitas akan dilepaskan dari memori. Orkestrasi dan entitas yang dilepaskan dari memori tidak dihitung terhadap throttle maxConcurrentOrchestratorFunctions. Meski jutaan orkestrasi atau entitas berada dalam status "Berjalan", orkestrasi atau entitas tersebut hanya mengurangi batas pembatasan saat dimuat ke dalam memori aktif. Orkestrasi yang menjadwalkan fungsi aktivitas juga tidak dihitung dalam throttle jika orkestrasi menunggu aktivitas selesai dieksekusi.

Functions 2.0

{
  "extensions": {
    "durableTask": {
      "maxConcurrentActivityFunctions": 10,
      "maxConcurrentOrchestratorFunctions": 10
    }
  }
}

Functions 1.x

{
  "durableTask": {
    "maxConcurrentActivityFunctions": 10,
    "maxConcurrentOrchestratorFunctions": 10
  }
}

Pertimbangan waktu proses bahasa

Waktu proses bahasa yang Anda pilih dapat memberlakukan pembatasan konkurensi yang ketat atau fungsi Anda. Misalnya, aplikasi Durable Function yang ditulis di Python atau PowerShell mungkin hanya mendukung menjalankan satu fungsi sekaligus pada satu VM. Hal ini dapat mengakibatkan masalah kinerja yang signifikan jika tidak diperhitungkan dengan cermat. Misalnya, jika orkestra dikembangkan ke 10 kegiatan tetapi waktu proses bahasa membatasi konkurensi hanya untuk satu fungsi, maka 9 dari 10 fungsi aktivitas akan terjebak menunggu kesempatan untuk dijalankan. Selain itu, 9 kegiatan yang macet ini tidak akan dapat dimuat seimbang dengan pekerja lain karena runtime Durable Functions sudah memuatnya ke dalam memori. Ini menjadi sangat bermasalah jika fungsi aktivitas berjalan lama.

Jika waktu proses bahasa yang Anda gunakan menempatkan pembatasan pada konkurensi, Anda harus memperbarui pengaturan konkurensi Durable Functions agar sesuai dengan pengaturan konkurensi waktu proses bahasa Anda. Ini memastikan bahwa runtime Durable Functions tidak akan mencoba menjalankan lebih banyak fungsi secara bersamaan daripada yang diizinkan oleh runtime bahasa, memungkinkan aktivitas yang tertunda dimuat seimbang dengan VM lainnya. Sebagai contohnya, jika Anda memiliki aplikasi Python yang membatasi konkurensi ke 4 fungsi (mungkin hanya dikonfigurasi dengan 4 rangkaian pada proses pekerja satu bahasa pemrogram atau 1 rangkaian pada 4 proses pekerja bahasa pemrogram), Anda harus mengonfigurasi baik maxConcurrentOrchestratorFunctions maupun maxConcurrentActivityFunctions menjadi 4.

Untuk informasi selengkapnya dan rekomendasi performa untuk Python, lihat Meningkatkan kinerja throughput aplikasi Python di Azure Functions. Teknik yang disebutkan dalam dokumentasi referensi pengembang Python ini dapat memiliki dampak besar pada kinerja dan skalabilitas Durable Functions.

Jumlah partisi

Beberapa penyedia penyimpanan menggunakan mekanisme pemartisian dan membuat agar Anda dapat menentukan parameter partitionCount.

Saat menggunakan pemartisian, pekerja tidak secara langsung bersaing untuk item kerja individual. Sebaliknya, item kerja pertama-tama akan dikelompokkan menjadi partisi partitionCount. Partisi ini kemudian ditetapkan untuk pekerja. Pendekatan dipartisi untuk distribusi beban ini dapat membantu mengurangi jumlah total akses penyimpanan yang diperlukan. Selain itu, pendekatan ini dapat mengaktifkan penembolokan instans dan meningkatkan lokalitas karena menciptakan afinitas: semua item kerja untuk instans yang sama diproses oleh pekerja yang sama.

Catatan

Batas partisi meluaskan skala karena sebagian besar pekerja partitionCount dapat memproses item kerja dari antrean yang dipartisi.

Tabel berikut menunjukkan antrean mana yang dipartisi untuk setiap penyedia penyimpanan, dan rentang yang diizinkan dan nilai default untuk parameter partitionCount.

Penyedia Microsoft Azure Storage Penyedia penyimpanan Netherite Penyedia penyimpanan MSSQL
Pesan instans Dipartisi Dipartisi Tidak dipartisi
Pesan aktivitas Tidak dipartisi Dipartisi Tidak dipartisi
Default partitionCount 4 12 n/a
Maksimum partitionCount 16 32 n/a
Dokumentasi Lihat Peluasan skala orkestrator Lihat Pertimbangan jumlah partisi n/a

Peringatan

Jumlah partisi tidak akan dapat diubah setelah hub tugas dibuat. Dengan demikian, sebaiknya atur ke nilai yang cukup besar untuk mengakomodasi persyaratan peluasan skala di masa mendatang untuk instans hub tugas.

Konfigurasi jumlah partisi

Parameter partitionCount dapat ditentukan dalam file host.json. Cuplikan host.json contoh berikut mengatur properti durableTask/storageProvider/partitionCount (atau durableTask/partitionCount dalam Durable Functions 1.x) ke 3.

Durable Functions 2.x

{
  "extensions": {
    "durableTask": {
      "storageProvider": {
        "partitionCount": 3
      }
    }
  }
}

Durable Functions 1.x

{
  "extensions": {
    "durableTask": {
      "partitionCount": 3
    }
  }
}

Pertimbangan untuk meminimalkan latensi pemanggilan

Dalam keadaan normal, permintaan pemanggilan (untuk aktivitas, orkestrator, entitas, dll.) harus diproses dengan agak cepat. Namun, tidak ada jaminan pada latensi maksimum permintaan pemanggilan apa pun karena tergantung pada faktor-faktor seperti: jenis perilaku skala Paket App Service Anda, pengaturan konkurensi Anda, dan ukuran backlog aplikasi Anda. Dengan demikian, sebaiknya berinvestasi dalam pengujian stres untuk mengukur dan mengoptimalkan latensi ekor aplikasi Anda.

Target performa

Ketika berencana menggunakan Durable Functions untuk aplikasi produksi, penting untuk mempertimbangkan persyaratan performa di awal proses perencanaan. Beberapa skenario penggunaan dasar meliputi:

  • Eksekusi aktivitas berurutan: Skenario ini menjelaskan fungsi orkestrator yang menjalankan serangkaian fungsi aktivitas satu demi satu. Ini paling mirip dengan sampel Penautan Fungsi.
  • Eksekusi aktivitas paralel: Skenario ini menjelaskan fungsi orkestrator yang menjalankan banyak fungsi aktivitas secara paralel menggunakan pola Fan-out, Fan-in.
  • Pemrosesan respons paralel: Skenario ini adalah paruh kedua dari pola Fan-out, Fan-in. Skenario ini berfokus pada performa fan-in. Penting untuk dicatat bahwa tidak seperti fan-out, fan-in dilakukan oleh satu instans fungsi orkestrator, dan karena itu hanya dapat berjalan pada satu VM.
  • Pemrosesan peristiwa eksternal: Skenario ini mewakili instans fungsi orkestrator tunggal yang menunggu peristiwa eksternal, satu per satu.
  • Pemrosesan operasi entitas: Skenario ini menguji seberapa cepat Entitas penghitungtunggal dapat memproses aliran operasi konstan.

Kami menyediakan nomor throughput untuk skenario ini dalam dokumentasi yang relevan untuk penyedia penyimpanan. Secara khusus:

Tip

Tidak seperti fan-out, operasi fan-in terbatas pada satu VM. Jika aplikasi Anda menggunakan pola fan-out, fan-in, dan Anda mengkhawatirkan performa fan-in, pertimbangkan untuk membagi fan-out fungsi aktivitas di beberapa sub-orkestrasi.

Langkah berikutnya