Prasyarat permintaan

Halaman ini membahas prasyarat permintaan, yang Anda gunakan untuk mencegah permintaan diterapkan ke resource saat resource berada dalam status yang tidak terduga.

Pengantar

Jika prasyarat digunakan dalam permintaan ke Cloud Storage, permintaan hanya akan dilanjutkan jika resource yang ditargetkan memenuhi kriteria yang ditentukan dalam prasyarat. Pemeriksaan prasyarat memastikan bahwa bucket atau objek berada dalam status yang diharapkan, sehingga Anda dapat menjalankan update baca-ubah-tulis dan operasi bersyarat yang aman.

Prasyarat sering digunakan untuk mencegah kondisi race dalam permintaan yang bermutasi, seperti upload, penghapusan, atau update metadata. Kondisi race dapat muncul jika permintaan yang sama dikirim berulang kali atau saat proses independen yang berusaha mengubah resource yang sama. Lihat Contoh kondisi race dan kerusakan data untuk mengetahui informasi selengkapnya. Prasyarat juga sering digunakan saat mengambil metadata objek dan data dalam permintaan berturut-turut, untuk memastikan objek tidak berubah dalam waktu di antara kedua permintaan tersebut.

Kriteria prasyarat

Cloud Storage mendukung penggunaan beberapa properti resource yang tidak dapat diubah dalam prasyarat:

Tabel berikut mencantumkan prasyarat yang didukung oleh JSON API dan XML API:

JSON API XML API Deskripsi
Parameter kueri ifGenerationMatch Header x-goog-if-generation-match Permintaan dilanjutkan jika generation resource target cocok dengan nilai yang digunakan dalam prasyarat. Jika nilainya tidak cocok, permintaan akan gagal dengan respons 412 Precondition Failed.
Parameter kueri ifMetagenerationMatch Header x-goog-if-metageneration-match Permintaan dilanjutkan jika metageneration resource target cocok dengan nilai yang digunakan dalam prasyarat. Jika nilainya tidak cocok, permintaan akan gagal dengan respons 412 Precondition Failed.
Parameter kueri ifGenerationNotMatch T/A Permintaan dilanjutkan jika generation resource target tidak cocok dengan nilai yang digunakan dalam prasyarat. Jika nilainya cocok, permintaan akan gagal dengan respons 304 Not Modified.
Parameter kueri ifMetagenerationNotMatch T/A Permintaan dilanjutkan jika metageneration resource target tidak cocok dengan nilai yang digunakan dalam prasyarat. Jika nilainya cocok, permintaan akan gagal dengan respons 304 Not Modified.
Header If-Match Header If-Match Berlaku untuk permintaan yang mengambil data. Permintaan dilanjutkan jika ETag resource target cocok dengan nilai yang digunakan dalam prasyarat. Jika nilainya tidak cocok, permintaan akan gagal dengan respons 412 Precondition Failed.
Header If-None-Match Header If-None-Match Berlaku untuk permintaan yang mengambil data. Permintaan dilanjutkan jika ETag resource target tidak cocok dengan nilai yang digunakan dalam prasyarat. Jika nilainya cocok, permintaan akan gagal dengan respons 304 Not Modified.
T/A Header If-Modified-Since Permintaan dilanjutkan jika resource target memiliki tanggal Last-Modified setelah nilai yang digunakan dalam prasyarat. Jika resource target tidak memenuhi prasyarat ini, permintaan akan gagal dengan respons 304 Not Modified.
T/A Header If-Unmodified-Since Permintaan dilanjutkan jika resource target memiliki tanggal Last-Modified lebih awal dari atau sama dengan nilai yang digunakan dalam prasyarat. Jika resource target tidak memenuhi prasyarat ini, permintaan akan gagal dengan respons 412 Precondition Failed.

Prasyarat komposisi objek

Saat melakukan komposisi objek, JSON API dan XML API mendukung hal berikut:

  • Prasyarat pencocokan generasi dan pencocokan metagenerasi untuk objek tujuan.

  • Prasyarat pencocokan generasi untuk setiap objek sumber. Penggunaan prasyarat ini akan mencegah komponen yang salah digunakan jika proses independen menimpa salah satu komponen komposisi yang diinginkan. Jika Anda menggunakan prasyarat dan terjadi penimpaan, operasi compose akan gagal dengan respons 412 Precondition Failed.

Prasyarat penyalinan objek

Saat menyalin atau menulis ulang objek dalam Cloud Storage, JSON API dan XML API mendukung penggunaan prasyarat standar untuk objek tujuan. Setiap API memiliki dukungan prasyarat tambahan untuk objek sumber:

  • JSON API mendukung prasyarat generasi dan metagenerasi untuk objek sumber, yang ditentukan menggunakan parameter kueri yang diawali dengan ifSource.

  • Semua prasyarat yang didukung oleh XML API dapat digunakan untuk objek sumber. Prasyarat ini ditentukan dalam header yang diawali dengan x-goog-copy-source-.

Nilai 0 dalam prasyarat pencocokan generasi

Prasyarat pencocokan generasi menerima nilai 0 sebagai kasus khusus. Jika prasyarat pencocokan generasi dengan nilai 0 disertakan dalam permintaan, permintaan hanya akan dilanjutkan jika tidak ada objek dengan nama yang ditentukan di bucket atau jika hanya ada objek versi lama di bucket. Jika ada versi aktif dengan nama yang ditentukan, permintaan akan gagal dengan kode status 412 Precondition Failed.

Praktik terbaik dan pertimbangan

  • Anda dapat menggunakan beberapa prasyarat dalam satu permintaan. Jika salah satu prasyarat tidak terpenuhi, permintaan secara keseluruhan akan gagal.

  • Bucket tidak memiliki nomor generasi, meskipun memiliki nomor metagenerasi. Anda tidak boleh menggunakan prasyarat yang menentukan nomor generasi dalam permintaan bucket.

  • Jika Anda menggunakan prasyarat metagenerasi dalam permintaan objek, Anda juga harus selalu menggunakan prasyarat pembuatan. Hal ini mencegah permintaan agar berhasil pada objek lain yang secara kebetulan memiliki nomor metagenerasi yang meneruskan prasyarat.

  • Untuk bucket yang memiliki versi objek aktif dan lama, permintaan objek tidak berlaku untuk versi lama, kecuali jika nomor generasi secara eksplisit disertakan dalam permintaan. Ini berarti bahwa untuk permintaan umum yang menggunakan prasyarat, permintaan akan gagal jika versi aktif tidak cocok dengan prasyarat, terlepas dari apakah versi lama cocok atau tidak dengan prasyarat.

  • Secara umum, Anda harus menggunakan prasyarat generasi dan metagenerasi, bukan prasyarat ETag. Bersama-sama, nomor generasi dan metagenerasi akan melacak semua update objek, termasuk perubahan metadata, sehingga memberikan jaminan yang lebih kuat daripada ETag. Selain itu, nomor generasi dan metagenerasi konsisten di seluruh API, sedangkan ETag tidak.

  • Prasyarat tidak dapat digunakan dalam upload multibagian XML API. Jika Anda mencoba melakukannya, akan muncul error 400 NotImplemented.

Biaya prasyarat

Banyak arsitektur yang menggunakan prasyarat mengharuskan Anda membuat permintaan metadata objek sebelum permintaan utama, untuk menentukan nomor pembuatan dan/atau metapembuatan saat ini:

  • Permintaan tambahan berarti Anda dapat menggandakan bagian jaringan dari latensi operasi secara keseluruhan dengan menambahkan perjalanan dua arah ekstra, yang mungkin menjadi faktor penting dalam operasi yang sensitif terhadap latensi.

Bergantung pada aplikasi Anda, ada cara untuk mengurangi dampak penggunaan prasyarat, seperti:

  • Menyimpan nomor generasi dan metagenerasi objek Anda secara lokal sehingga Anda sudah mengetahui nomor yang benar untuk digunakan dalam prasyarat.
  • Memiliki pengetahuan aplikasi tentang objek mana yang baru dibuat, sehingga Anda sudah tahu kapan harus menggunakan prasyarat if-generation-match:0.

Contoh: Menggunakan prasyarat

Contoh berikut menggunakan prasyarat pencocokan generasi dalam permintaan untuk mengupload objek. Agar permintaan dapat dilanjutkan, harus ada objek yang sudah ada sebelumnya yang disimpan di bucket dengan nama yang ditentukan, dan nomor generasi untuk objek yang sudah ada sebelumnya harus cocok dengan nomor yang diberikan dalam prasyaratnya:

Command line

Gunakan flag --if-generation-match bersama dengan perintah normal:

gcloud storage cp OBJECT_LOCATION gs://DESTINATION_BUCKET_NAME --if-generation-match=GENERATION

Dengan keterangan:

  • GENERATION adalah nomor generasi objek yang Anda ganti. Contoh, 1122334455667788.

  • OBJECT_LOCATION adalah jalur lokal ke objek Anda. Contoh, Desktop/dog.png.

  • DESTINATION_BUCKET_NAME adalah nama bucket tempat Anda mengupload objek. Contoh, my-bucket.

JSON API

  1. Telah menginstal dan melakukan inisialisasigcloud CLI, agar dapat membuat token akses untuk header Authorization.

    Atau, Anda dapat membuat token akses menggunakan OAuth 2.0 Playground dan menyertakannya di header Authorization.

  2. Gunakan cURL untuk memanggil JSON API dengan permintaan POST Object:

    curl -X POST --data-binary @OBJECT_LOCATION \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: OBJECT_CONTENT_TYPE" \
      "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=media&name=OBJECT_NAME"&ifGenerationMatch=GENERATION"

    Dengan keterangan:

    • OBJECT_LOCATION adalah jalur lokal ke objek Anda. Contoh, Desktop/dog.png.
    • OBJECT_CONTENT_TYPE adalah jenis konten objek. Contoh, image/png.
    • BUCKET_NAME adalah nama bucket tempat Anda mengupload objek. Contoh, my-bucket.
    • OBJECT_NAME adalah nama yang ingin Anda berikan ke objek. Contoh, dog.png.
    • GENERATION adalah nomor generasi objek yang Anda ganti. Contoh, 1122334455667788.

XML API

  1. Telah menginstal dan melakukan inisialisasigcloud CLI, agar dapat membuat token akses untuk header Authorization.

    Atau, Anda dapat membuat token akses menggunakan OAuth 2.0 Playground dan menyertakannya di header Authorization.

  2. Gunakan cURL untuk memanggil XML API dengan permintaan Objek PUT:

    curl -X PUT --data-binary @OBJECT_LOCATION \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: OBJECT_CONTENT_TYPE" \
      -H "x-goog-if-generation-match: GENERATION" \
      "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"

    Dengan keterangan:

    • OBJECT_LOCATION adalah jalur lokal ke objek Anda. Contoh, Desktop/dog.png.
    • OBJECT_CONTENT_TYPE adalah jenis konten objek. Contoh, image/png.
    • GENERATION adalah nomor generasi objek yang Anda ganti. Contoh, 1122334455667788.
    • BUCKET_NAME adalah nama bucket tempat Anda mengupload objek. Contoh, my-bucket.
    • OBJECT_NAME adalah nama yang ingin Anda berikan ke objek. Contoh, dog.png.

Skenario untuk menggunakan prasyarat

Skenario berikut mempelajari kondisi race dan contoh penyimpanan dalam cache yang merupakan manfaat dari penggunaan prasyarat.

Beberapa percobaan ulang permintaan

Cloud Storage adalah sistem terdistribusi. Karena permintaan dapat gagal akibat kondisi jaringan atau layanan, cara yang direkomendasikan untuk mencoba lagi kegagalan adalah dengan backoff eksponensial. Namun, karena sifat sistem yang terdistribusi, terkadang percobaan ulang ini dapat menyebabkan perilaku yang mengejutkan.

Pertimbangkan kasus berikut: Anda ingin menghapus objek, file.txt, yang disimpan di salah satu bucket Anda. Setelah itu, Anda ingin menambahkan objek baru dengan nama yang sama ke bucket. Untuk melakukannya, Anda mengeluarkan permintaan penghapusan untuk menghapus objek. Namun, kondisi jaringan — seperti router perantara yang kehilangan konektivitas untuk sementara — mencegah permintaan mencapai Cloud Storage, dan Anda tidak menerima respons.

Karena tidak menerima respons terhadap permintaan pertama, Anda mengeluarkan permintaan penghapusan kedua untuk objek tersebut, yang berhasil, dan Anda akan menerima respons yang mengonfirmasi penghapusan. Satu menit kemudian, Anda mengupload file.txt baru, dan upload berhasil.

Kondisi race terjadi jika router yang kehilangan konektivitas kemudian mendapatkannya kembali dan mengirimkan permintaan penghapusan asli Anda yang tampaknya hilang, selanjutnya ke Cloud Storage. Saat sampai di Cloud Storage, permintaan akan berhasil karena ada file.txt baru. Cloud Storage mengirim respons yang tidak Anda terima karena klien Anda berhenti memprosesnya. File baru tidak hanya dihapus, bertentangan dengan niat Anda, tetapi juga Anda tidak menyadari telah terjadi penghapusan kedua.

Diagram berikut menunjukkan hal yang terjadi:

Mencegah kondisi race

Untuk mencegah terjadinya situasi di atas, Anda harus memulai dengan mendapatkan metadata untuk file.txt agar dapat menentukan generasinya saat ini. Kemudian, gunakan generasi dalam prasyarat pencocokan generasi yang Anda sertakan sebagai bagian dari permintaan penghapusan. Prasyarat memastikan bahwa hanya objek dengan nomor generasi spesifik tersebut yang akan dihapus, terlepas dari kapan permintaan penghapusan mencapai Cloud Storage atau berapa kali permintaan penghapusan dengan prasyarat tersebut akan dikirim. Setiap upaya yang tidak diinginkan untuk menghapus generasi file.txt yang berbeda akan gagal dengan kode respons 412 Precondition Failed.

Karena gangguan jaringan yang serupa dapat menyebabkan kondisi race untuk permintaan upload yang mengikuti permintaan penghapusan, Anda dapat menghindari banyak kondisi race tersebut dengan menggunakan nilai 0 dalam prasyarat pencocokan generasi yang disertakan dalam permintaan upload. Penggunaan prasyarat ini akan memastikan bahwa percobaan ulang upload tidak akan menulis objek dua kali secara tidak sengaja, karena prasyarat memungkinkan permintaan untuk dilanjutkan hanya jika tidak ada generasi objek saat ini.

Dengan menerapkan prasyarat ini, Anda melindungi data agar tidak hilang secara tidak sengaja saat melakukan permintaan penghapusan dan upload. Hal ini dapat dilihat pada diagram berikut:

Pengaitan metadata objek

Data dan metadata objek adalah entity terpisah yang bersama-sama menentukan objek di Cloud Storage. Karena keduanya ada secara terpisah, data objek dapat berubah saat Anda bekerja dengan metadata objek.

Pertimbangkan kasus berikut:

  • Anda ingin mendownload metadata dan data untuk sebuah objek, yang harus diambil dari Cloud Storage dalam dua permintaan terpisah. Anda perlu meminta metadata objek terlebih dahulu, tetapi sebelum dapat meminta data objek, sebuah proses atau pengguna independen akan mengganti objek tersebut. Permintaan Anda untuk data objek masih berhasil, tetapi sekarang Anda memiliki metadata objek lama dan data objek baru.

  • Anda ingin mengupdate metadata untuk sebuah objek agar mengambil metadata saat ini agar objek tersebut menentukan statusnya saat ini. Agar Anda dapat mengirim permintaan untuk mengupdate metadata dengan modifikasi yang diinginkan, proses atau pengguna independen akan menggantikan objek tersebut. Permintaan Anda untuk mengubah metadata objek baru masih berhasil, tetapi kini dikaitkan dengan data objek yang berbeda dari yang Anda inginkan.

Mencegah kondisi race

Untuk mencegah situasi ini terjadi, Anda harus menggunakan nomor generasi yang ditampilkan dalam permintaan awal untuk metadata objek, lalu menggunakan nilai ini dalam prasyarat pencocokan generasi dalam permintaan kedua. Dengan begitu, metadata cocok dengan data secara tepat, atau permintaan kedua gagal dengan kode respons 412 Precondition Failed sehingga Anda dapat meminta metadata yang benar untuk objek baru.

Jika khawatir metadata objek dapat berubah antara permintaan pertama dan kedua, Anda juga dapat menyalin nomor metagenerasi yang ditemukan dalam permintaan awal dan menggunakannya dalam prasyarat pencocokan metagenerasi dalam permintaan kedua.

Keaktualan salinan lokal

Jika memiliki salinan lokal objek yang disimpan di Cloud Storage, Anda sering kali ingin salinan lokal Anda selalu diupdate dengan salinan yang disimpan di bucket Anda. Namun, jika objek yang disimpan di bucket Anda tidak berubah, Anda tidak ingin membuang waktu dan resource untuk mendownloadnya lagi, terutama jika objeknya besar.

Untuk mencegah download konten yang masih baru yang tidak perlu, Anda dapat menggunakan nomor generasi salinan lokal sebagai nilai dalam prasyarat generasi yang tidak cocok, yang Anda sertakan dalam permintaan download:

  • Jika data dalam bucket Anda terus cocok dengan salinan lokal, nomor generasi akan cocok, yang menyebabkan prasyarat gagal. Akibatnya, keseluruhan permintaan gagal dengan respons 304 Not Modified, dan data tidak perlu didownload.

  • Jika data di bucket Anda telah berubah, jumlah generasinya tidak cocok, dan prasyarat berhasil. Artinya, keseluruhan permintaan akan berjalan seperti biasa dan mendownload versi konten yang telah diupdate.

Langkah selanjutnya