Load Shedding Melindungi Layanan Saat Kapasitas Habis
Sebuah layanan dapat menerima pekerjaan lebih banyak daripada yang mampu diselesaikannya. Gejala pertama sering bukan error langsung, melainkan antrean yang terus tumbuh sementara seluruh worker sibuk. Request menunggu lebih lama, deadline habis, client melakukan retry, dan traffic retry tambahan dapat memperparah overload.
Load shedding menempatkan titik penolakan eksplisit sebelum spiral tersebut menghabiskan resource yang tersedia. Layanan menerima pekerjaan yang masih sesuai kapasitas operasional dan menggagalkan kelebihannya dengan cepat agar throughput berguna tetap tersedia bagi request yang masih dapat selesai.
Antrean tidak menciptakan kapasitas
Queue menyerap lonjakan singkat ketika arrival rate sesaat melampaui service rate. Queue menjadi masalah ketika kelebihan permintaan berlangsung terus-menerus.
Bayangkan worker pool mampu menyelesaikan 500 request per detik sementara 800 request per detik masuk. Queue dapat menunda penolakan, tetapi tidak menghilangkan defisit 300 request per detik. Backlog terus bertambah sampai mencapai batas atau resource lain lebih dahulu gagal.
arrival rate: 800 req/s
service rate: 500 req/s
net backlog: +300 req/sAntrean panjang juga memakai sebagian latency budget sebelum eksekusi dimulai. Request yang menunggu 900 ms dalam queue dengan deadline 1 detik hanya menyisakan sedikit waktu untuk database call, remote RPC, atau serialisasi.
Karena itu, bounded queue adalah batas kapasitas, bukan janji bahwa setiap item yang diterima pasti selesai.
Penolakan sebaiknya dekat dengan resource yang terbatas
Keputusan shedding yang berguna memerlukan sinyal yang terkait dengan saturasi aktual. Sinyal umum mencakup active concurrency, queue depth, queue age, memory pressure, connection-pool occupancy, dan perkiraan kapasitas tersisa.
Gateway dapat menolak traffic sebelum mencapai aplikasi, tetapi belum tentu melihat bottleneck di satu dependency. Aplikasi dapat menerapkan limit yang lebih ketat di sekitar jalur yang memakai dependency tersebut.
request
|
global admission
|
handler
|
dependency-specific limit
|
databaseLimit berlapis dapat melindungi resource yang berbeda. Nilainya perlu terkoordinasi agar lapisan luar tidak menerima jauh lebih banyak pekerjaan daripada yang mungkin dilayani lapisan dalam.
Fast failure dapat mempertahankan throughput yang berhasil
Saat layanan sudah jenuh, menerima setiap request dapat mengurangi jumlah pekerjaan berguna yang selesai. Context switching meningkat, queue menahan memory, connection pool penuh, dan pekerjaan dapat terus berjalan setelah caller tidak lagi menunggunya.
Penolakan dini mencegah kapasitas langka dihabiskan oleh request yang kecil peluangnya untuk selesai sebelum deadline. Layanan HTTP umumnya menyatakan kondisi ini dengan 503 Service Unavailable; batas berbasis rate dapat memakai 429 Too Many Requests jika status tersebut sesuai kontrak.
Status code bukan mekanisme kontrolnya. Sifat yang penting adalah pekerjaan yang ditolak berhenti memakai resource yang sedang jenuh.
Tidak semua request memiliki nilai yang sama
Satu aturan admission FIFO memperlakukan semua request sebagai pekerjaan yang setara. Banyak sistem memiliki kelas traffic dengan kepentingan operasional berbeda.
Interactive read mungkin perlu diprioritaskan dibanding background refresh. Operasi control plane dapat memerlukan kapasitas cadangan, sementara bulk export dapat menoleransi penundaan. Health check sebaiknya tetap murah agar monitoring tidak bersaing berat dengan traffic aplikasi.
Priority memerlukan limit eksplisit. Tanpanya, kelas prioritas tinggi dapat memakai seluruh kapasitas dan membuat kelas lebih rendah tidak mendapat giliran.
Salah satu pola mencadangkan kapasitas per kelas sambil mengizinkan borrowing terkontrol saat suatu kelas sedang idle:
total capacity
├── reserved: critical
├── reserved: interactive
└── reserved: backgroundKebijakan sebaiknya bertumpu pada requirement layanan, bukan sekadar identitas caller. Jika tidak, priority berubah menjadi sistem privilege yang tidak sengaja dan sulit dioperasikan secara konsisten.
Perilaku retry menentukan apakah penolakan membantu
Load shedding bekerja buruk ketika setiap penolakan memicu retry seketika. Client yang melakukan retry terhadap response 503 dalam tight loop mengubah fast failure menjadi beban tambahan.
Client memerlukan retry terbatas, backoff, jitter, dan deadline keseluruhan. Server dapat memberikan Retry-After ketika memiliki estimasi yang bermakna, tetapi client tetap memerlukan limit lokal karena waktu recovery tidak pasti.
Retry budget sangat berguna selama overload. Mekanisme ini membatasi proporsi traffic yang berasal dari retry sehingga pekerjaan asli tetap memperoleh kapasitas.
original traffic + bounded retry traffic <= offered load policyShedding dan kebijakan retry membentuk satu feedback system. Menyetel sisi server saja masih membiarkan client menciptakan kembali tekanan yang baru saja dihilangkan oleh penolakan.
Concurrency limit dapat adaptif, tetapi tetap memerlukan guardrail
Static concurrency limit sederhana dan dapat diprediksi ketika biaya workload stabil. Biaya request yang bervariasi dan perubahan downstream latency dapat membuat satu nilai tetap kurang efisien.
Adaptive limiter dapat menyesuaikan concurrency yang diterima berdasarkan latency teramati atau sinyal saturasi lain. Mekanisme ini tetap memerlukan nilai minimum, maksimum, smoothing, dan aturan update konservatif. Sinyal yang noisy tidak seharusnya membuat limit berosilasi cepat.
Adaptasi juga tidak dapat menciptakan kapasitas downstream. Jika database terbatas pada 100 operasi concurrent yang efektif, menaikkan concurrency aplikasi di atas titik tersebut terutama hanya menciptakan waktu tunggu.
Cancellation mencegah pekerjaan yang ditinggalkan menghabiskan kapasitas
Admission control menangani pekerjaan sebelum eksekusi. Cancellation menangani pekerjaan yang sudah tidak berguna setelah diterima.
Jika deadline caller habis, operasi downstream sebaiknya menerima cancellation ketika protocol dan library mendukungnya. Melanjutkan pekerjaan mahal untuk response yang tidak lagi dipakai akan bersaing dengan request aktif.
Cancellation tidak selalu aman. Write mungkin sudah melewati commit boundary walaupun caller terputus. Operasi mutasi tetap memerlukan semantik idempotency dan completion yang eksplisit, bukan menganggap cancellation menghapus efeknya.
Shedding memerlukan alasan yang dapat diamati
Counter penolakan tanpa konteks membuat insiden kapasitas sulit didiagnosis. Telemetry yang berguna memisahkan rejection berdasarkan route, traffic class, limiter, dependency, dan alasan.
Operator juga memerlukan sinyal yang mendorong keputusan admission: concurrency, queue depth, queue age, latency, deadline expiration, volume retry, dan saturasi resource.
Targetnya bukan nol penolakan. Saat overload benar-benar terjadi, sebagian rejection menunjukkan boundary sedang bekerja. Pertanyaan operasionalnya adalah apakah sistem mempertahankan latency terbatas dan throughput berguna untuk pekerjaan yang diterima.
Batas kapasitas mengubah overload menjadi mode kegagalan terkontrol
Layanan dengan resource terbatas pada akhirnya memerlukan kebijakan untuk permintaan yang melampaui resource tersebut. Penerimaan tanpa batas menyerahkan kebijakan itu kepada pertumbuhan queue, timeout cascade, memory exhaustion, atau kegagalan tidak disengaja lainnya.
Load shedding membuat batas tersebut eksplisit. Bounded queue menyerap lonjakan singkat, admission limit melindungi resource terbatas, priority mempertahankan pekerjaan tertentu, cancellation membuang pekerjaan yang ditinggalkan, dan retry yang disiplin mencegah penolakan memberi makan overload.
Hasilnya bukan kapasitas tanpa batas. Layanan dapat menolak permintaan berlebih secara sengaja sambil menjaga pekerjaan yang diterima tetap berada dalam operating envelope yang terkendali.