Condizioni preliminari per le richieste

In questa pagina vengono descritte le condizioni preliminari delle richieste, che puoi utilizzare per evitare le richieste dall'applicazione a una risorsa quando questa si trova in uno stato imprevisto.

Introduzione

Quando vengono utilizzate le precondizioni in una richiesta a Cloud Storage, continua solo se la risorsa scelta come target soddisfa i criteri definiti nella precondizioni. I controlli di precondizione assicurano che un bucket o un oggetto si trovi nella stato previsto, consentendoti di eseguire aggiornamenti sicuri in lettura, modifica e scrittura condizionali.

Le condizioni preliminari vengono spesso utilizzate per prevenire le condizioni di gara in Richieste mutanti, come caricamenti, eliminazioni o aggiornamenti dei metadati. Razza quando la stessa richiesta viene inviata ripetutamente o quando e processi indipendenti tentano di modificare la stessa risorsa. Consulta Esempi di condizioni di gara e danneggiamento dei dati informazioni. Le precondizioni vengono spesso utilizzate anche quando si recuperano i metadati degli oggetti e dati nelle richieste successive, per garantire che l'oggetto non sia cambiato nel tempo tra le due richieste.

Criteri di precondizione

Cloud Storage supporta l'utilizzo di diverse risorse immutabili proprietà in condizioni preliminari:

Nella tabella seguente sono elencate le condizioni preliminari supportate dall'API JSON e dall'API XML:

API JSON API XML Descrizione
ifGenerationMatch parametro di query Intestazione x-goog-if-generation-match La richiesta procede se il valore generation della risorsa di destinazione corrisponde al valore utilizzato nella condizione preliminare. Se i valori non corrispondono, la richiesta non riesce e restituisce una risposta 412 Precondition Failed.
ifMetagenerationMatch parametro di query Intestazione x-goog-if-metageneration-match La richiesta procede se il valore metageneration della risorsa di destinazione corrisponde al valore utilizzato nella condizione preliminare. Se i valori non corrispondono, la richiesta non riesce e restituisce una risposta 412 Precondition Failed.
ifGenerationNotMatch parametro di query N/D La richiesta procede se il valore generation della risorsa di destinazione non corrisponde al valore utilizzato nella condizione preliminare. Se i valori corrispondono, la richiesta non riesce e restituisce una risposta 304 Not Modified.
ifMetagenerationNotMatch parametro di query N/D La richiesta procede se il valore metageneration della risorsa di destinazione non corrisponde al valore utilizzato nella condizione preliminare. Se i valori corrispondono, la richiesta non riesce e restituisce una risposta 304 Not Modified.
Intestazione If-Match Intestazione If-Match Applicabile per le richieste che recuperano dati. La richiesta procede se il valore ETag della risorsa di destinazione corrisponde al valore utilizzato nella condizione preliminare. Se i valori non corrispondono, la richiesta non riesce e restituisce una risposta 412 Precondition Failed.
Intestazione If-None-Match Intestazione If-None-Match Applicabile per le richieste che recuperano dati. La richiesta procede se il valore ETag della risorsa di destinazione non corrisponde al valore utilizzato nella condizione preliminare. Se i valori corrispondono, la richiesta non riesce e restituisce una risposta 304 Not Modified.
N/D Intestazione If-Modified-Since La richiesta procede se la risorsa di destinazione ha una data Last-Modified successiva al valore utilizzato nella condizione preliminare. Se la risorsa di destinazione non soddisfa questa condizione preliminare, la richiesta non va a buon fine e viene inviata una risposta 304 Not Modified.
N/D Intestazione If-Unmodified-Since La richiesta procede se la risorsa di destinazione ha una data Last-Modified precedente o uguale al valore utilizzato nella precondizione. Se la risorsa di destinazione non soddisfa questa condizione preliminare, la richiesta non va a buon fine e viene inviata una risposta 412 Precondition Failed.

Condizioni preliminari per la composizione di oggetti

Durante la composizione degli oggetti, sia l'API JSON L'API XML supporta quanto segue:

  • Le precondizioni di generazione e metagenerazione corrispondenti per oggetto di destinazione.

  • La precondizione per la corrispondenza di generazione per ogni oggetto di origine. Utilizzo di questo "precondition" impedisce l'utilizzo di componenti errati nel caso in cui un processo indipendente sovrascrive uno dei componenti previsti del composizione. Se utilizzi le precondizioni e si verifica una sovrascrittura, Le operazioni compose non vanno a buon fine con una risposta 412 Precondition Failed.

Condizioni preliminari per la copia degli oggetti

Quando copi o riscrivi un oggetto in Cloud Storage, viene utilizzata Supporto delle API JSON e delle API XML mediante precondizioni standard per il oggetto di destinazione. Ogni API dispone di un supporto aggiuntivo per la condizione preliminare per l'origine oggetti:

  • L'API JSON supporta le precondizioni di generazione e metagenerazione per il , che vengono specificati mediante parametri di ricerca preceduti da un prefisso con ifSource.

  • Tutte le condizioni preliminari supportate dall'API XML possono essere utilizzate per l'oggetto di origine. Queste precondizioni sono specificate in intestazioni con prefisso x-goog-copy-source-.

Il valore 0 in una precondizione per la corrispondenza di generazione

La precondizione per la corrispondenza di generazione accetta il valore 0 come caso speciale. Quando una precondizione per la corrispondenza di generazione con un valore pari a 0 è inclusa in una richiesta la richiesta continua solo se non esiste alcun oggetto con il nome specificato nel o se sono presenti solo versioni non correnti dell'oggetto nel bucket. Se esiste una versione live con il nome specificato, la richiesta ha esito negativo con codice di stato 412 Precondition Failed.

Best practice e considerazioni

  • Puoi utilizzare più precondizioni in una singola richiesta. Se uno dei le condizioni preliminari non sono soddisfatte, la richiesta complessiva non riesce.

  • I bucket non hanno un numero di generazione, anche se hanno un numero di metagenerazione. Non devi utilizzare condizioni preliminari che specificano numero di generazione in una richiesta di bucket.

  • Se utilizzi una precondizione di metagenerazione in una richiesta di oggetto, devi usa sempre anche una precondizione di generazione. In questo modo, la richiesta successo su un oggetto diverso che casualmente ha una metagenerazione numero che supera la precondizione.

  • Per i bucket che hanno versioni dell'oggetto attive e non attuali, le richieste di oggetti non si applicano alle versioni non correnti, a meno che non venga numero è esplicitamente incluso nella richiesta. Ciò significa che, richiesta generica che utilizza le precondizioni, la richiesta non va a buon fine se la versione non soddisfa la condizione preliminare, indipendentemente dal fatto che un indirizzo che soddisfi le precondizioni.

  • In genere dovresti usare invece le precondizioni di generazione e metagenerazione di precondizioni dell'ETag. Insieme, i numeri di generazione e metagenerazione mantengono tenere traccia di tutti gli aggiornamenti degli oggetti, comprese le modifiche ai metadati, fornendo un garantito rispetto agli ETag. Inoltre, i numeri di generazione e metagenerazione coerenti tra le API, mentre gli ETag no.

  • Le condizioni preliminari non possono essere utilizzate nei caricamenti multiparte dell'API XML. Tentativo questo comporta l'errore 400 NotImplemented.

Costo delle precondizioni

Molte architetture che utilizzano condizioni preliminari richiedono la creazione di un oggetto richiesta di metadati prima della richiesta principale, al fine di determinare l'attuale numero di generazione e/o metagenerazione:

  • Se ricevi una richiesta aggiuntiva, puoi raddoppiare la porzione di rete latenza complessiva delle operazioni aggiungendo un ulteriore andata e ritorno, che potrebbe essere è un fattore importante nelle operazioni sensibili alla latenza.

A seconda dell'applicazione, ci sono modi per ridurre l'impatto dell'utilizzo precondizioni come:

  • Archiviazione in locale dei numeri di generazione e metagenerazione degli oggetti in modo da sapere già i numeri corretti da usare nella tua condizione preliminare.
  • Conoscere l'applicazione degli oggetti appena creati, sa già quando utilizzare la precondizione if-generation-match:0.

Esempio: utilizzo di una condizione preliminare

L'esempio seguente utilizza la precondizione per la corrispondenza di generazione in una richiesta per caricare un oggetto. Per procedere con la richiesta, deve esserci un esistente archiviato nel bucket con il nome specificato e di generazione dell'oggetto preesistente deve corrispondere a quello fornito in la condizione preliminare:

Riga di comando

Utilizza il flag --if-generation-match insieme al comando normale:

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

Dove:

  • GENERATION è il numero di generazione previsto dell'oggetto che stai sostituendo. Ad esempio, 1122334455667788.

  • OBJECT_LOCATION è il percorso locale dell'oggetto. Ad esempio, Desktop/dog.png.

  • DESTINATION_BUCKET_NAME è il nome del bucket su cui stai caricando l'oggetto. Ad esempio, my-bucket.

API JSON

  1. Avere gcloud CLI installato e inizializzato, per generare un token di accesso per l'intestazione Authorization.

    In alternativa, puoi creare un token di accesso utilizzando il metodo OAuth 2.0 Playground e includilo nell'intestazione Authorization.

  2. Utilizza cURL per chiamare l'API JSON con una chiamata Richiesta POST oggetto:

    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"

    Dove:

    • OBJECT_LOCATION è il percorso locale . Ad esempio, Desktop/dog.png.
    • OBJECT_CONTENT_TYPE è il tipo di contenuti di dell'oggetto. Ad esempio, image/png.
    • BUCKET_NAME è il nome del bucket dell'oggetto. Ad esempio, my-bucket.
    • OBJECT_NAME è il nome che vuoi assegnare al tuo . Ad esempio, dog.png.
    • GENERATION è il numero di generazione previsto dell'oggetto che stai sostituendo. Ad esempio, 1122334455667788.

API XML

  1. Avere gcloud CLI installato e inizializzato, per generare un token di accesso per l'intestazione Authorization.

    In alternativa, puoi creare un token di accesso utilizzando il metodo OAuth 2.0 Playground e includilo nell'intestazione Authorization.

  2. Utilizza cURL per chiamare l'API XML con un Richiesta PUT oggetto:

    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"

    Dove:

    • OBJECT_LOCATION è il percorso locale . Ad esempio, Desktop/dog.png.
    • OBJECT_CONTENT_TYPE è il tipo di contenuti di dell'oggetto. Ad esempio, image/png.
    • GENERATION è il numero di generazione previsto dell'oggetto che stai sostituendo. Ad esempio, 1122334455667788.
    • BUCKET_NAME è il nome del bucket dell'oggetto. Ad esempio, my-bucket.
    • OBJECT_NAME è il nome che vuoi assegnare al tuo . Ad esempio, dog.png.

Scenari di utilizzo delle condizioni preliminari

Gli scenari seguenti esplorano le condizioni di gara ed esempi di memorizzazione nella cache che possono trarre vantaggio dall'uso di condizioni preliminari.

Più tentativi di richiesta

Cloud Storage è un sistema distribuito. Poiché le richieste possono non andare a buon fine condizioni di rete o di servizio, il modo consigliato per riprovare gli errori è backoff esponenziale. Tuttavia, a causa della natura di deployment sistemi, a volte questi nuovi tentativi possono causare comportamenti sorprendenti.

Considera il seguente caso: vuoi eliminare un oggetto, file.txt, archiviato uno dei tuoi bucket. In seguito vorrai aggiungere un nuovo oggetto con lo stesso nome al bucket. A questo scopo, devi inviare una richiesta di eliminazione per eliminare il . Tuttavia, c'è una condizione di rete, come un router intermedio perdere temporaneamente la connettività; impedisce che la richiesta raggiunga Cloud Storage e non ricevi una risposta.

Poiché non hai ricevuto una risposta alla prima richiesta, emetti un secondo di eliminazione dell'oggetto, che ha esito positivo, e riceverai una risposta confermando l'eliminazione. Un minuto dopo, carichi un nuovo file.txt e i tuoi caricamento riuscito.

Si verifica una race condition se il router ha perso successivamente la connettività lo recupera e invia la richiesta di eliminazione originale, apparentemente persa, di archiviazione ideale in Cloud Storage. Quando la richiesta arriva a Cloud Storage, operazione riuscita perché è presente un nuovo file.txt. Cloud Storage invia una risposta che non ricevi perché il cliente ha smesso di ascoltarla. Il nuovo file non viene solo eliminato, contrariamente alle tue intenzioni, ma anche non sai che si è verificata la seconda eliminazione.

Il seguente diagramma mostra cosa è successo:

Prevenzione della race condition

Per evitare che si verifichi la situazione di cui sopra, dovresti iniziare a ottenere lo metadati per file.txt al fine di determinarne la generazione attuale. Poi utilizza la generazione in una precondizione di corrispondenza di generazione che includi come parte della richiesta di eliminazione. La condizione preliminare garantisce che solo l'oggetto con quell'oggetto un numero di generazione specifico viene eliminato, indipendentemente da quando è stata richiesta raggiunge Cloud Storage o quante volte la richiesta di eliminazione viene inviata la precondizione. Eventuali tentativi involontari di eliminare una generazione diversa di file.txt non riesce con il codice di risposta 412 Precondition Failed.

Poiché interruzioni di rete simili potrebbero causare le condizioni di gara per il caricamento successiva alla tua richiesta di eliminazione, puoi evitare molte utilizzando il valore 0 in una precondizione di corrispondenza di generazione incluso nella richiesta di caricamento. L'uso di questa condizione preliminare garantisce che i nuovi tentativi non scrivano accidentalmente due volte l'oggetto perché la precondizione consente di proseguire la richiesta solo se non esistono generazioni attuali dell'oggetto.

Con queste precondizioni, proteggi i tuoi dati da incidenti persi durante l'esecuzione delle richieste di eliminazione e caricamento. Questo può essere visto nel seguente diagramma:

Associazione di metadati degli oggetti

I dati e i metadati di un oggetto sono entità separate che definiscono in Cloud Storage. Poiché esistono separatamente, è possibile modificare i dati dell'oggetto mentre lavori con i metadati dell'oggetto.

Considera i seguenti casi:

  • Vuoi scaricare i metadati e i dati di un oggetto, che devono essere recuperate da Cloud Storage in due richieste separate. Hai richiesto dei metadati dell'oggetto, ma prima di poter richiedere i dati dell'oggetto, l'oggetto viene sostituito da un processo indipendente o da un utente. La tua richiesta dei dati dell'oggetto ha ancora esito positivo, ma ora hai i metadati vecchio oggetto e i dati di quello nuovo.

  • Vuoi aggiornare i metadati per un oggetto, in modo da recuperare lo stato attuale metadati per l'oggetto al fine di determinarne lo stato attuale. Prima di poter invia la richiesta di aggiornamento dei metadati con le modifiche desiderate, da un processo indipendente o da un utente. La tua richiesta di modificare i metadati per il nuovo oggetto hanno ancora esito positivo, ma ora sono associati diversi da quelli previsti.

Prevenzione della race condition

Per evitare che si verifichino queste situazioni, è necessario utilizzare il numero di generazione che viene restituito nella richiesta iniziale per i metadati dell'oggetto, in una precondizione di corrispondenza di generazione nella seconda richiesta. Ciò garantisce i metadati corrispondano correttamente ai dati o la seconda richiesta non riesce con un codice di risposta 412 Precondition Failed, che ti consente di richiedere i metadati corretti per il nuovo oggetto.

Se temi che i metadati dell'oggetto possano cambiare tra il primo e seconda richiesta, puoi anche copiare il numero di metagenerazione trovato nella e usarla in una precondizione di corrispondenza di metagenerazione nella seconda richiesta.

Aggiornamento della copia locale

Se hai una copia locale di un oggetto archiviato in Cloud Storage, spesso vuoi che la copia locale sia sempre aggiornata e la copia archiviata nel bucket. Tuttavia, se l'oggetto archiviato nel tuo bucket non cambia, non vuoi perdere tempo e risorse a scaricarlo di nuovo soprattutto se l'oggetto è di grandi dimensioni.

Per evitare download inutili di contenuti ancora attuali, puoi utilizzare lo numero di generazione della copia locale come valore in un valore di generazione non corrispondente precondizione, che includi nella richiesta di download:

  • Se i dati nel bucket continuano a corrispondere alla copia locale, la generazione numeri corrispondenti, causando il mancato superamento della condizione preliminare. Di conseguenza, nel complesso non riesce con una risposta 304 Not Modified e i dati non sono scaricato inutilmente.

  • Se i dati nel bucket sono cambiati, i numeri di generazione non corrispondono. e la condizione preliminare viene soddisfatta. Ciò significa che la richiesta complessiva procede normalmente e scarica la versione aggiornata dei contenuti.

Passaggi successivi