Pertanyaan dan konteks
Sebuah API baca yang idempoten memiliki p99 yang tinggi sementara p50 sehat; panggilan lambat tampaknya berasal dari antrean berkala atau gangguan host sesaat. Rancang request hedging: kirim permintaan utama, kirim salinan ke replika lain setelah penundaan, kembalikan hasil pertama yang dapat diterima, dan batalkan yang lainnya. Jelaskan batasan biaya dan amplifikasi kegagalan.
Apa yang sedang diuji oleh pewawancara
Memahami tujuannya
Hedging menargetkan tail; ini tidak membuat setiap permintaan lebih cepat. Ini cocok untuk pembacaan yang dapat diulang dengan aman dan tidak boleh secara membabi buta menduplikasi penulisan yang memiliki efek samping.
Mengendalikan biaya
Menduplikasi setiap permintaan dapat melipatgandakan beban backend hampir dua kali lipat. Desain yang kuat menggunakan pemicu tertunda, batas jumlah percobaan maksimum, pembatasan laju (throttling), pembatalan, dan metrik berdasarkan permintaan asli.
Menangani kegagalan yang berkorelasi
Mengirim kedua percobaan ke satu host yang kelebihan beban memiliki nilai yang sangat kecil. Perutean lintas-instans, zona, atau domain kegagalan ditambah perlindungan antrean dan kesalahan menentukan apakah hedging aman.
Pertanyaan untuk diklarifikasi terlebih dahulu
- Apakah API bersifat idempoten, dan apakah beberapa pembacaan konkuren dapat diterima?
- Berapa baseline p50, p95, p99, p99.9 dan SLO?
- Apakah panggilan lambat merupakan straggler yang terisolasi atau masalah antrean yang dialami oleh setiap replika?
- Bagaimana replika dipilih di seluruh instans, zona, dan versi?
- Apakah pembatalan benar-benar melepaskan thread, koneksi, dan komputasi downstream?
- Tingkat kesalahan, kedalaman antrean, atau tingkat pemicuan hedge mana yang menonaktifkan kebijakan?
Jawaban 30 detik
“Saya akan mengaktifkan hedging hanya untuk pembacaan idempoten. Kirim permintaan utama terlebih dahulu; gunakan ambang batas dinamis bergaya p95 per kelas permintaan, lalu kirim satu hedge ke replika yang sehat di domain kegagalan lain hanya ketika ambang batas berakhir dan anggaran memungkinkannya. Bagikan satu batas waktu (deadline), kembalikan keberhasilan pertama, dan batalkan pihak yang kalah. Batasi percobaan, gunakan throttling serta pengaman antrean/kesalahan, dan pantau p99, tingkat pemicuan, permintaan ekstra, keberhasilan pembatalan, dan latensi asli. Nonaktifkan kebijakan ketika itu memperkuat beban.”
Jawaban mendalam langkah demi langkah
Tentukan state machine permintaan
Statusnya adalah primary_sent, hedge_waiting, hedge_sent, winner_selected, dan deadline_exceeded. Kirim permintaan utama terlebih dahulu; selesaikan jika kembali dalam ambang batas, jika tidak buat satu hedge. Respons sukses pertama menang dan semua percobaan lainnya menerima pembatalan.
Pilih ambang batas dan cakupan
Pertahankan histogram latensi yang dikelompokkan berdasarkan metode, tenant, ukuran permintaan, atau panjang prompt. Gunakan ambang batas dinamis bergaya p95 dengan batas atas-bawah dan fallback cold-start. Jangan hanya menggunakan rata-rata global atau menduplikasi setiap permintaan secara langsung.
Rute ke replika independen
Hindari host, zona, atau domain kegagalan milik permintaan utama. Utamakan node yang sehat dengan antrean pendek. Jika setiap kandidat kelebihan beban, hedging menambah kemacetan; lebih baik menunggu, mendegradasi layanan, atau gagal cepat (fail fast).
Tangani pembatalan dan batas waktu
Klien dan proksi harus menyebarkan token pembatalan. Pekerjaan downstream harus berhenti dan melepaskan koneksi, thread, GPU, atau cache. Kedua percobaan berbagi total batas waktu sehingga duplikasi tidak dapat memperpanjang waktu tunggu yang terlihat oleh pengguna.
Lindungi kapasitas downstream
Tetapkan maxAttempts, penundaan hedge minimum, anggaran in-flight, dan token bucket per layanan. gRPC membatasi maxAttempts pada angka 5 dan menawarkan throttling percobaan ulang; desain produksi tetap memerlukan kapasitas dan anggaran kesalahannya sendiri.
Tangani kesalahan dan panggilan non-idempoten
Lanjutkan hanya untuk kasus idempoten yang dapat dicoba ulang. Kembalikan kesalahan validasi atau autentikasi deterministik secara langsung. Penulisan memerlukan kunci idempotensi dan deduplikasi, atau harus menggunakan satu permintaan ditambah kompensasi.
Pseudokode
~~~text send(primary) timer = hedgeThreshold(request_class) if primary unfinished at timer and budget_allows(): send(hedge, differentfailuredomain) winner = firstsuccessbefore_deadline() cancel(allotherattempts) record(primarylatency, hedgefired, winner, cancel_result) ~~~
Kompleksitas, observabilitas, dan rollback
Jumlah percobaan terburuk dibatasi oleh maxAttempts; volume permintaan ekstra bergantung pada tingkat pemicuan dan latensi pembatalan. Lacak p50/p95/p99, tingkat pemicuan hedge, QPS ekstra, antrean downstream, kesalahan, keberhasilan pembatalan, dan latensi permintaan utama asli. Matikan kebijakan per layanan, tenant, atau wilayah saat kemacetan atau kesalahan meningkat.
| Kontrol | Tujuan | Mode kegagalan jika salah konfigurasi |
|---|---|---|
| hedge delay | Duplikasi hanya panggilan lambat | Terlalu pendek mengamplifikasi QPS |
| maxAttempts | Batasi salinan konkuren | Terlalu tinggi menciptakan badai permintaan |
| cancellation | Bebaskan sumber daya pihak yang kalah | Kegagalan terus menghabiskan kapasitas |
| throttle budget | Perketat selama kemacetan | Metrik yang hilang menyembunyikan kelebihan beban |
Jawaban model
“Pertama-tama saya akan memastikan bahwa ini adalah pembacaan idempoten dan membuat histogram latensi per kelas permintaan. Setelah mengirimkan permintaan utama, saya akan mengirimkan satu hedge hanya setelah ambang batas bergaya p95, replika independen yang sehat, dan anggaran konkurensi semuanya mengizinkannya. Kedua percobaan berbagi batas waktu; keberhasilan pertama menang dan proksi menyebarkan pembatalan sambil mencatat apakah sumber daya benar-benar dibebaskan. Batas percobaan maksimum, token throttling, kedalaman antrean, dan tingkat kesalahan melindungi backend, sementara kesalahan deterministik tidak pernah diduplikasi. Saya akan menguji coba kebijakan ini secara canary dan membandingkan p99, tingkat pemicuan, QPS ekstra, latensi pembatalan, dan latensi utama tanpa hedge; badai hedge akan menonaktifkannya secara otomatis.”
Kesalahan umum
Menduplikasi setiap permintaan secara langsung
Hal itu mengubah hedging menjadi replikasi tanpa syarat, meningkatkan beban normal dan biaya tanpa membuktikan bahwa straggler yang menyebabkan lonjakan tail.
Melakukan hedging pada penulisan yang memiliki efek samping
Dua percobaan dapat membuat dua catatan atau menagih pembayaran dua kali. Tanpa kunci idempotensi, deduplikasi, dan semantik transaksi, jangan lakukan hedging.
Menggunakan domain kegagalan yang sama
Kegagalan host, rak, atau zona bersama memperlambat kedua percobaan dan menambah beban pada lokasi yang kelebihan beban.
Hanya melihat p99 yang terlihat oleh pengguna
Hedging dapat menyembunyikan jalur utama yang memburuk dan menunda sinyal penskalaan (scaling). Catat juga latensi utama tanpa hedge dan kedalaman antrean.
Mengabaikan pembatalan
Menghentikan waktu tunggu bukanlah menghentikan pekerjaan downstream. Verifikasi penyebaran, pelepasan sumber daya, dan latensi pembatalan.
Tidak memiliki kill switch
Kesalahan tinggi, penumpukan antrean, atau tingkat pemicuan hedge yang tidak normal memerlukan sakelar penonaktifan cepat di tingkat layanan, tenant, atau wilayah.
Pertanyaan lanjutan dan tanggapan
Apa perbedaan hedging dengan retry?
Retry biasanya menunggu kegagalan sebelum mengirim lagi. Hedging mengirimkan salinan setelah ambang latensi tercapai saat percobaan pertama masih berjalan. Keduanya memerlukan idempotensi, batas waktu, dan throttling.
Mengapa memulai dengan p95?
Ini membiarkan sebagian besar permintaan normal tidak tersentuh sambil mencakup sebagian kecil latensi tail. Ambang batas harus disesuaikan per kelas permintaan, anggaran, dan hasil eksperimen.
Bagaimana jika setiap replika mengalami kemacetan?
Hentikan hedging dan gunakan rate limit, antrean, degradasi, atau kegagalan cepat. Hedging tidak dapat memperbaiki kapasitas yang tidak mencukupi.
Bagaimana Anda membuktikan bahwa pembatalan berfungsi?
Catat pembatalan downstream, penyelesaian pekerjaan, penggunaan koneksi, dan latensi pelepasan. Injeksikan pihak kalah yang lambat dan konfirmasikan bahwa itu berhenti setelah pemenang dipilih.
Bagaimana streaming mengubah desain ini?
Gunakan waktu untuk byte atau token pertama sebagai pemicu, tetapi menduplikasi setelah output dimulai dapat menghasilkan data duplikat. Tentukan penggabungan stream, pembatalan, dan visibilitas klien terlebih dahulu.
Apa saja konfigurasi kunci gRPC?
maxAttempts, hedgingDelay, dan kode status non-fatal mengontrol kapan salinan dikirim. gRPC membatasi percobaan hingga 5 dan menyediakan throttling percobaan ulang serta pushback server; layanan tetap memerlukan anggaran kapasitasnya sendiri.