Topik wawancara representatif

Wawancara system design: Bagaimana cara mengisolasi konkurensi dependensi untuk mencegah kelebihan beban beruntun (cascading overload)?

Desain sistemSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah layanan biasanya memerlukan 10 ms per panggilan downstream, tetapi satu dependensi tiba-tiba memakan waktu 1 detik, menghabiskan thread pool, connection pool, dan antrean. Rancang isolasi konkurensi tingkat dependensi dan jelaskan kuota hard/soft, timeout, penolakan, degradasi, pemulihan, serta validasi.

Petunjuk dan konteks

Sebuah layanan memanggil database, penyedia pembayaran, dan sistem rekomendasi. Rekomendasi melambat dari 10 ms menjadi 1 detik. Permintaan in-flight meningkat hingga thread dan koneksi habis terpakai, dan API yang tidak memerlukan rekomendasi pun ikut gagal. Rancang bulkhead agar dependensi yang lambat hanya memengaruhi fungsionalitas terkait.

AWS Builders’ Library menggambarkan hal ini sebagai kelebihan beban konkurensi akibat latensi (latency-driven concurrency overload): timeout bukanlah batas konkurensi. Sumber daya harus diisolasi di sekitar setiap dependensi atau klien, guna melindungi layanan itu sendiri maupun sistem downstream.

Hal yang dievaluasi pewawancara

  • Anda menjelaskan intuisi Hukum Little (Little’s Law) bahwa waktu layanan yang lebih lama akan meningkatkan beban kerja in-flight pada tingkat kedatangan (arrival rate) yang sama.
  • Anda mengalokasikan konkurensi berdasarkan dependensi, API, tenant, atau resource pool sehingga satu dependensi yang lambat tidak dapat menghabiskan kapasitas global.
  • Anda membandingkan kuota hard, soft, dan dinamis beserta pertukaran antara keadilan (fairness) dan utilisasinya.
  • Anda merancang penolakan cepat, degradasi, batas waktu (deadline), perilaku circuit, pemulihan, dan observabilitas.
  • Anda membuktikan bahwa API yang tidak terkait tetap sehat tanpa antrean tak terbatas atau kelaparan sumber daya (starvation).

Pertanyaan klarifikasi awal

  • API mana yang memanggil rekomendasi dan mana yang kritis? Apakah ada jalur yang dapat didegradasi?
  • Berapa batas thread, koneksi, memori, dan antrean serta bagaimana distribusi konkurensi saat ini?
  • Apakah dependensi mendukung pembatalan, idempotensi, batching, atau caching? Bagaimana deadline pemanggil dipropagasi?
  • Apakah alokasi diisolasi berdasarkan API, dependensi, tenant, atau Availability Zone? Apakah peminjaman kuota diperlukan?
  • Pengalaman pengguna, kontrak kesalahan, dan target pemulihan apa yang berlaku selama kegagalan?

Jawaban 30 detik

“Saya membuat bulkhead konkurensi berbatas dan antrean per dependensi, dengan pool terpisah untuk API kritis dan API yang dapat didegradasi. Setiap permintaan membawa deadline; pekerjaan yang melebihi kuota akan gagal dengan cepat (fail fast) atau menyajikan data cache daripada menunggu tanpa batas. Saya menggunakan kuota soft untuk efisiensi utilisasi tetapi menerapkan batas global dan per kelas yang hard, dengan peminjaman berbatas. Metrik mencakup pekerjaan in-flight, penolakan, waktu tunggu, timeout, degradasi, dan pemulihan berdasarkan dependensi dan API. Pengujian dependensi lambat harus memastikan API yang tidak terkait tetap sehat.”

Solusi langkah demi langkah

Langkah 1: Kuantifikasi konkurensi akibat latensi

Ukur tingkat kedatangan, waktu layanan, permintaan in-flight, dan timeout per dependensi. Jika waktu layanan naik dari 10 ms menjadi 1 detik, pekerjaan in-flight dapat melonjak sekitar 100 kali lipat pada tingkat kedatangan yang sama. Temukan sumber daya yang terbatas sebelum menentukan ukuran bulkhead.

Langkah 2: Partisi kumpulan sumber daya (resource pools)

Berikan setiap dependensi connection pool, semaphore, dan antrean berbatas tersendiri; pisahkan API kritis dan API yang dapat didegradasi untuk dependensi yang sama. Pastikan bahwa isolasi tersebut nyata: thread, koneksi, dan status tidak boleh tetap dipakai bersama di balik penghitung (counter) yang terpisah.

Langkah 3: Pilih kuota hard, soft, dan dinamis

Kuota hard melindungi API tetapi membuang kapasitas saat terjadi ketimpangan beban. Kuota soft meminjam kapasitas menganggur di bawah batas global. Kuota dinamis beradaptasi terhadap beban tetapi memerlukan jaminan minimum, batas maksimum, dan laju perubahan yang aman. Tambahkan partisi tenant jika keadilan menjadi prioritas.

text
global_limit = 500
payments = hard 150
recommendations = soft 200, borrow <= 100
other_apis = reserved 50

Langkah 4: Tolak dan degradasi secara terencana

Jika tidak ada izin yang tersedia, kembalikan kesalahan eksplisit atau hasil cache alih-alih memasukkannya ke dalam antrean tak terbatas. Hormati deadline pemanggil dan batalkan pekerjaan yang memungkinkan untuk dibatalkan. Percobaan ulang (retries) membutuhkan anggaran, backoff, dan idempotensi; operasi penulisan kritis tidak boleh didegradasi secara diam-diam.

Langkah 5: Pulihkan tanpa osilasi

Setelah pemulihan, tingkatkan izin secara bertahap dan gunakan probe half-open untuk menghindari lonjakan tiba-tiba. Pertahankan data runtun waktu (time series) untuk penolakan, timeout, dan batas antrean (watermarks), yang disegmentasikan berdasarkan dependensi, API, tenant, dan cell. Buat versi konfigurasi dan siapkan mekanisme rollback.

Langkah 6: Verifikasi batas isolasi

Injeksikan latensi, kesalahan, dan habisnya koneksi ke salah satu dependensi. Amati penolakan rekomendasi, keberhasilan pembayaran, penggunaan thread/koneksi global, dan tail latency. Uji lonjakan beban mendadak, ketimpangan tenant, perubahan konfigurasi, dan kegagalan cell; SLO API yang tidak terkait dan batas antrean adalah tolok ukur penerimaannya.

Contoh jawaban yang kuat

“Saya menggunakan tingkat kedatangan, waktu layanan, dan pekerjaan in-flight untuk menunjukkan mengapa dependensi rekomendasi yang lambat melipatgandakan konkurensi. Setiap dependensi memiliki semaphore, pool, dan antrean berbatas tersendiri; API kritis dan yang dapat didegradasi dipisahkan. Pembayaran mendapatkan reservasi hard; rekomendasi menggunakan kuota soft dengan peminjaman berbatas. Setiap panggilan mempropagasi deadline dan langsung gagal cepat atau mengembalikan cache saat izin habis.”

“Pemulihan menggunakan probe half-open dan peningkatan izin secara bertahap. Metrik mencakup pekerjaan in-flight, penolakan, waktu tunggu, timeout, frekuensi degradasi, kesalahan downstream, dan waktu pemulihan. Simulasi pengujian hanya memperlambat rekomendasi dan memeriksa bahwa tail latency, pool, dan thread untuk pembayaran serta API tak terkait tetap berada dalam batas aman.”

Kesalahan umum

  • Hanya menaikkan timeout → pekerjaan in-flight melonjak → tetapkan batas konkurensi tingkat dependensi.
  • Menggunakan satu thread pool dan connection pool bersama → satu dependensi lambat melumpuhkan seluruh layanan → partisi berdasarkan dependensi dan tingkat kekritisan.
  • Menggunakan antrean tak berbatas → memori dan latensi lepas kendali → batasi antrean dan tolak dengan cepat.
  • Kuota hard statis di semua tempat → ketimpangan beban menyisakan kapasitas menganggur → izinkan peminjaman kuota soft yang berbatas.
  • Retry tanpa batas anggaran → kelebihan beban downstream makin teramplifikasi → propagasikan deadline, batasi percobaan, dan wajibkan idempotensi.
  • Hanya menguji dependensi yang gagal → isolasi belum terbukti → verifikasi SLO API yang tidak terkait secara bersamaan.

Pertanyaan lanjutan dan jawaban

Mengapa timeout bukan merupakan batas konkurensi?

Timeout hanya membatasi durasi satu kali tunggu, tetapi permintaan yang sedang menunggu tersebut tetap memakai thread, koneksi, dan memori. Latensi dependensi yang lebih tinggi menyebabkan lebih banyak permintaan in-flight, sehingga izin akseslah yang harus dibatasi.

Bagaimana peminjaman soft mencegah satu API mengambil semua sumber daya?

Gunakan batas global, reservasi minimum per API, batas pinjaman maksimum, dan tingkat pengembalian (reclaim rate). Begitu peminjam mencapai batas maksimalnya, sistem akan gagal cepat alih-alih terus tumbuh tanpa batas.

Kapan penyajian data cache aman dilakukan?

Untuk operasi baca di mana data basi dalam batas tertentu (bounded staleness) dapat diterima, kembalikan nilai cache yang memiliki stempel waktu. Hasil pembayaran, otorisasi, dan operasi tulis tidak boleh digantikan secara diam-diam oleh data basi.

Bagaimana Anda membuktikan bahwa isolasi berhasil?

Injeksikan kelambatan dan kesalahan pada satu dependensi, lalu periksa pekerjaan in-flight, tail latency, penggunaan thread/koneksi, dan tingkat keberhasilan pada API yang tidak terkait. Degradasi yang terjadi secara sinkron menandakan bahwa masih ada sumber daya bersama atau batasan antrean yang belum terisolasi.

Sumber publik

Pertanyaan terkait

Alat wawancara terkait

Gunakan Jawab untuk jawaban desain sistem

Perjelas persyaratan terlebih dahulu, lalu lanjutkan dengan skala, arsitektur, pilihan komponen, dan trade-off.

Lihat alat