Topik wawancara representatif

Wawancara Backend: Bagaimana S3 conditional write mencegah penimpaan bersamaan (concurrent overwrites)?

BackendSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Ketika beberapa klien menulis ke objek S3 yang sama, bagaimana Anda mencegah penimpaan read-then-write? Bandingkan If-None-Match dengan If-Match, dan jelaskan retry serta multipart upload.

Perintah dan konteks

Pertanyaan ini menguji backend API, penyimpanan objek, dan kontrol konkurensi. Permintaan bersyarat AWS menambahkan prasyarat ke PutObject, CompleteMultipartUpload, dan CopyObject: pembuatan dapat mensyaratkan bahwa sebuah key belum ada, sedangkan pembaruan dapat mensyaratkan bahwa ETag belum berubah. Masalah intinya adalah membuat penyimpanan mengevaluasi pemeriksaan bersamaan dengan operasi penulisan, daripada membiarkan klien melakukan HEAD yang rentan terhadap race condition diikuti oleh PUT.

Apa yang sedang diuji oleh pewawancara

Jawaban yang kuat memisahkan pembuatan dari pembaruan, memilih If-None-Match: * atau If-Match dengan etag-value saat ini, dan memetakan kondisi yang gagal ke perilaku retry atau merge. Ini juga mencakup penyelesaian multipart, weak ETag, hasil jaringan yang tidak pasti, dan sinyal audit. Mengatakan "tambahkan kunci (lock)" tidak menjelaskan banyak proses atau pemulihan kegagalan.

Pertanyaan klarifikasi untuk diajukan terlebih dahulu

Semantik penulisan

Apakah ini objek immutable yang hanya ditulis sekali, atau pembaruan berdasarkan versi yang telah dibaca? Yang pertama menggunakan prasyarat keberadaan; yang kedua membutuhkan ETag versi.

Kebijakan konflik

Apakah konflik harus mengembalikan 412 sehingga klien membaca ulang dan menggabungkan (merge), atau apakah upaya tersebut harus dibatalkan? Manifes atau registri biasanya tidak boleh ditimpa secara diam-diam.

Jalur unggahan

Apakah objek kecil akan menggunakan PutObject dan objek besar menggunakan multipart? Terapkan kondisi pada permintaan penyelesaian akhir dan tentukan perilaku interupsi, retry, dan pembersihan.

Kerangka jawaban 30 detik

"Pertama, saya menentukan apakah ini pembuatan baru atau pembaruan berversi. Pembuatan menggunakan If-None-Match: *, sehingga S3 secara atomik menolak key yang sudah ada. Pembaruan membaca ETag saat ini dan mengirimkan If-Match; jika ETag berubah, S3 mengembalikan 412 dan klien membaca ulang atau melakukan merge. Unggahan multipart menerapkan kondisi pada CompleteMultipartUpload. Batas waktu (timeout) bukanlah bukti kegagalan, jadi saya mengueri objek atau menggunakan catatan idempotensi sebelum mencoba lagi, serta memantau 412, part yang terbengkalai, dan jumlah retry."

Jawaban mendalam langkah demi langkah

Langkah 1: Hilangkan check-then-act

HEAD yang diikuti oleh PUT memicu race condition: dua klien dapat sama-sama mengamati ketiadaan objek lalu menulis. Tempatkan prasyarat dalam permintaan penulisan sehingga layanan penyimpanan mengevaluasinya terhadap status objek saat ini.

Langkah 2: Pilih kondisinya

Gunakan If-None-Match: * untuk pembuatan yang bersifat immutable; ini hanya berhasil jika tidak ada representasi saat ini. Gunakan strong If-Match untuk objek yang sudah ada, mengizinkan penulisan hanya jika ETag sama dengan versi yang dibaca. Ketidakcocokan akan mengembalikan 412 dan melindungi konten yang lebih baru.

Langkah 3: Tentukan protokol konflik

Jangan mencoba ulang 412 secara membabi buta. Lakukan GET pada objek saat ini dan tentukan apakah perubahan klien dapat digabungkan; jika tidak, buat catatan konflik atau key baru. Tambahkan backoff dan batas retry agar hot key tidak menimbulkan badai retry (retry storm).

Langkah 4: Tangani multipart dan penyalinan

Klien lain dapat membuat key yang sama saat part sedang diunggah, sehingga CompleteMultipartUpload terakhir juga memerlukan kondisi tersebut. Alur kerja penyalinan atau penggantian harus membawa kondisi ETag, sementara aturan siklus hidup (lifecycle rules) membersihkan unggahan multipart yang ditinggalkan.

Langkah 5: Tangani timeout dan lakukan observasi

Timeout tidak mengungkap apakah penulisan telah dilakukan (committed). Kueri objek dan ETag sebelum mencoba lagi, dan catat ID perintah klien untuk maksud pembuatan. Pantau tingkat 412, tingkat keberhasilan retry, part yang terbengkalai, dan pergeseran versi untuk memverifikasi bahwa konflik ditolak dan bukan ditimpa.

Contoh jawaban berkualitas tinggi

Saya akan memisahkan file data yang bersifat immutable dari registri yang dapat diperbarui. Pembuatan file data menggunakan If-None-Match: *, sehingga hanya satu penulis key yang sama yang berhasil. Registri dibaca dengan ETag dan diperbarui dengan If-Match; kode 412 memicu pembacaan ulang dan merge alih-alih menimpa versi lain. Unggahan besar menerapkan kondisi pada CompleteMultipartUpload, dan proses pembersihan mengklaim kembali unggahan yang gagal. Setelah terjadi network timeout, saya mengueri objek dan ETag sebelum mencoba lagi. S3 menyediakan pemeriksaan konflik atomik; klien memiliki kebijakan merge dan catatan idempotensi. Saya akan memvalidasinya dengan metrik 412, retry, dan part yang terbengkalai.

Kesalahan umum

  • Kesalahan: HEAD untuk memeriksa ketiadaan, lalu PUT. → Mengapa gagal: Dua klien dapat lolos dari pemeriksaan secara bersamaan. → Perbaikan: Gunakan If-None-Match: * pada PUT.
  • Kesalahan: Menggunakan If-None-Match untuk pembaruan. → Mengapa gagal: Ini berarti "tidak boleh ada", bukan "harus sama dengan versi yang saya baca." → Perbaikan: Baca strong ETag dan gunakan If-Match.
  • Kesalahan: Mencoba ulang permintaan asli tanpa syarat setelah 412. → Mengapa gagal: Ini dapat menimpa berulang kali atau menciptakan badai retry. → Perbaikan: Baca ulang, gabungkan (merge), atau batalkan dengan backoff yang dibatasi.
  • Kesalahan: Menerapkan kondisi hanya pada permintaan multipart pertama. → Mengapa gagal: Status objek dapat berubah sebelum penyelesaian. → Perbaikan: Terapkan lagi pada CompleteMultipartUpload.

Tindak lanjut dan tanggapan

Tindak lanjut 1: Bisakah ETag diperlakukan sebagai hash konten?

Tidak secara universal. Kebutuhannya adalah validator versi; skenario multipart dan enkripsi dapat mengubah semantik ETag, jadi gunakan checksum atau validator yang terdokumentasi oleh layanan untuk operasi tersebut.

Tindak lanjut 2: Bagaimana perbedaan 412 dan 409?

Ikuti kontrak API: 412 berarti prasyarat permintaan gagal dan biasanya meminta klien untuk membaca ulang; status konflik lain mungkin menjelaskan status sumber daya atau operasi. Jangan menyimpulkan semantik hanya dari nomor statusnya saja.

Tindak lanjut 3: Bagaimana jika klien tidak dapat melakukan merge?

Pertahankan versi saat ini dan buat catatan konflik atau key baru agar diselesaikan oleh pemilik domain. Penimpaan diam-diam bukanlah kriteria keberhasilan.

Tindak lanjut 4: Bagaimana Anda menguji kebenaran konkurensi?

Jalankan pembuatan dan pembaruan bersamaan pada satu key, lakukan injeksi timeout, duplikasi penyelesaian multipart, dan kegagalan pembersihan, lalu verifikasi bahwa paling banyak satu pembuatan yang berhasil, konten lama tidak pernah menimpa konten yang lebih baru, dan catatan audit cocok dengan hasilnya.

Sumber publik

Pertanyaan terkait