Caching dello storage e CDN
Ogni oggetto viene veicolato tramite proxy attraverso il server anziché reindirizzato a un URL firmato — un URL firmato genera errori in caso di contenuti misti (una pagina HTTPS, un MinIO su HTTP) e su endpoint raggiungibili esclusivamente all’interno del cluster. Di conseguenza, sono gli header di risposta a rendere possibile il funzionamento della cache.
Ciascuna risposta include un ETag debole e Last-Modified, ricavati dalla
dimensione dell’oggetto e dall’orario di modifica. Un client che possiede già
l’oggetto invia If-None-Match e riceve un 304 senza corpo, per cui un
caricamento ripetuto comporta solo un round trip anziché un trasferimento.
Cache-Control dipende da chi è autorizzato a leggere l’oggetto:
| Oggetto | Header |
|---|---|
Sotto il prefisso public/, o publicRead: true |
public, max-age=60, stale-while-revalidate=86400, must-revalidate |
| Qualsiasi altra cosa | private, max-age=60, must-revalidate |
| Trasformazioni di immagini | lo stesso, con max-age=3600 |
private è intenzionale: un oggetto per il cui recupero sono state necessarie
credenziali non deve essere memorizzato da una cache condivisa, altrimenti una
CDN potrebbe consegnare il file di un utente a quello successivo. Vary: Authorization viene inviato per lo stesso motivo.
Nulla viene mai contrassegnato come immutable. Una chiave di storage può
essere sovrascritta — la scrittura su una chiave esistente è un’operazione
comune — quindi la promessa di non effettuare mai una riconvalida renderebbe
invisibile un file sostituito fino alla scadenza dell’intervallo temporale.
Seeking in audio e video
Sezione intitolata “Seeking in audio e video”Ogni risposta di un oggetto include Accept-Ranges: bytes, e a una richiesta
Range si risponde con 206 Partial Content e un Content-Range. Senza di
questo, un browser non consentirà il seeking in un elemento multimediale
servito da qui — e Safari rifiuta di riprodurre un tag <video> la cui prima
risposta non sia un 206 — perciò per i media questa è la differenza tra un
player funzionante e uno non funzionante.
- Un singolo intervallo per richiesta:
bytes=0-499,bytes=500-,bytes=-500. Questo è ciò che i browser inviano per la riproduzione. - A intervalli multipli in un singolo header si risponde con l’intero oggetto
e un
200, operazione sempre valida. Nessun client rilevante ne invia. - Un intervallo che inizia oltre la fine riceve un
416conContent-Range: bytes */<size>, e non una risposta silenziosa con l’intero file. - La riconvalida ha la priorità su un range: una richiesta contenente sia
If-None-MatchsiaRangericeve un304.
Nello storage locale viene letta da disco solo la porzione richiesta. Su S3 e
GCS l’oggetto viene comunque recuperato per intero — un StorageController
non dispone di lettura a intervalli — pertanto il risparmio riguarda la
risposta, non l’upstream.
Inserire una CDN davanti
Sezione intitolata “Inserire una CDN davanti”Poiché gli oggetti pubblici sono public con una finestra di
stale-while-revalidate e un validatore, qualsiasi normale reverse proxy o
CDN può memorizzarli nella cache senza configurazioni aggiuntive. È
sufficiente puntarlo all’origine dell’API e lasciare che rispetti gli header.
Due aspetti da configurare direttamente sulla CDN:
- Rispettare
Vary: Authorization, oppure non inserire affatto in cache le rotte autenticate. Una CDN che ignoraVarye mette in cache risposteprivaterappresenta l’errore per cui questo header è stato creato. - Aspettarsi la riconvalida. Il breve
max-agefa sì che la CDN ripeta la richiesta regolarmente; tali richieste sono leggeri 304, ed è proprio questo a evitare che un oggetto sovrascritto venga servito obsoleto.
Correlati
Sezione intitolata “Correlati”- Storage — i backend da cui vengono serviti questi header, e il prefisso
public/epublicReadche rendono un oggettopublic. - Autorizzazione per Oggetto — chi può leggere un oggetto, ciò che decide tra
publiceprivate. - Campi di caricamento file — le proprietà di collezione che memorizzano i file.