Cache concatenata

Panoramica

Flusso di dati

Il recapito di una pagina da un server al browser di un client passa attraverso una moltitudine di sistemi e sottosistemi. Se osservi attentamente, c’è una serie di dati di hop che devono essere raccolti dalla sorgente al drenaggio, ciascuno dei quali è un potenziale candidato per la memorizzazione in cache.

Flusso di dati di unapplicazione CMS tipica

Flusso di dati di un'applicazione CMS tipica

Iniziamo il nostro percorso con dei dati che si trovano su un disco rigido e che devono essere visualizzati in un browser.

Hardware e sistema operativo

Innanzitutto, il disco rigido (HDD) stesso ha alcune cache integrate nell'hardware. In secondo luogo, il sistema operativo che monta il disco rigido utilizza la memoria libera per memorizzare nella cache i blocchi a cui si accede di frequente per velocizzare l'accesso.

Archivio dei contenuti

Il livello successivo è CRX o Oak, ovvero il database di documenti utilizzato dall'AEM. CRX e Oak dividono i dati in segmenti che possono essere memorizzati nella cache, anche per evitare un accesso più lento all’HDD.

Dati di terze parti

La maggior parte delle installazioni Web più grandi dispone anche di dati di terze parti; dati provenienti da un sistema di informazioni di prodotto, un sistema di gestione delle relazioni con i clienti, un database legacy o qualsiasi altro servizio web arbitrario. Non è necessario estrarre questi dati dall’origine ogni volta che sono necessari, soprattutto quando notoriamente non cambiano troppo frequentemente. Può quindi essere memorizzato nella cache, se non è sincronizzato nel database di CRX.

Livello aziendale: app/modello

Di solito, gli script di modelli non eseguono il rendering del contenuto non elaborato proveniente da CRX tramite l’API JCR. Probabilmente si dispone di un livello di business nel mezzo che unisce, calcola e/o trasforma i dati in un oggetto del dominio di business. Indovina un po’: se queste operazioni sono costose, dovresti considerare la possibilità di memorizzarle in cache.

Frammenti markup

Il modello ora è la base per il rendering del markup di un componente. Perché non memorizzare in cache anche il modello renderizzato?

Dispatcher, CDN e altri proxy

Off passa il rendering della pagina HTML a Dispatcher. Abbiamo già discusso del fatto che lo scopo principale di Dispatcher sia quello di memorizzare in cache le pagine HTML e altre risorse web (nonostante il nome). Prima che le risorse raggiungano il browser, è possibile che passi un proxy inverso, che può memorizzare in cache e una rete CDN, utilizzato anche per il caching. Il client può trovarsi in un ufficio, che concede l’accesso web solo tramite un proxy e tale proxy può anche decidere di memorizzare in cache per risparmiare traffico.

Cache browser

Ultimo ma non meno importante: anche il browser memorizza in cache. Questa è una risorsa facilmente trascurata. Ma è la cache più vicina e veloce che hai nella catena di caching. Purtroppo non è condiviso tra gli utenti, ma tra diverse richieste di un utente.

Dove memorizzare in cache e perché

Si tratta di una lunga catena di potenziali cache. E tutti abbiamo dovuto affrontare problemi per i quali abbiamo visto contenuti obsoleti. Ma tenendo conto di quante fasi ci sono, è un miracolo che nella maggior parte dei casi stia funzionando.

Ma in quale punto di quella catena ha senso memorizzare cache? All'inizio? Alla fine? Ovunque? Dipende… e dipende da un numero enorme di fattori. Anche due risorse nello stesso sito web potrebbero desiderare una risposta diversa a tale domanda.

Per darvi un'idea approssimativa di quali fattori potreste prendere in considerazione,

Durata - Se gli oggetti hanno una durata breve intrinseca (i dati sul traffico potrebbero avere una durata inferiore ai dati meteo), potrebbe non valere la pena di essere memorizzati nella cache.

Costo di produzione - Quanto costoso (in termini di cicli della CPU e I/O) è la riproduzione e la consegna di un oggetto. In caso affermativo, la memorizzazione nella cache potrebbe non essere necessaria.

Dimensione - Per gli oggetti di grandi dimensioni sono necessarie più risorse nella cache. Questo potrebbe essere un fattore limitante e deve essere valutato in rapporto al beneficio.

Frequenza di accesso - Se si accede raramente agli oggetti, la memorizzazione nella cache potrebbe non essere efficace. Diventerebbero semplicemente obsoleti o verrebbero invalidati prima di poter accedere la seconda volta dalla cache. Tali elementi bloccherebbero semplicemente le risorse di memoria.

Accesso condiviso - I dati utilizzati da più entità devono essere memorizzati nella cache più in alto nella catena. In realtà, la catena di memorizzazione in cache non è una catena, ma un albero. Un elemento di dati nell’archivio potrebbe essere utilizzato da più modelli. Questi modelli, a loro volta, possono essere utilizzati da più script di rendering per generare frammenti di HTML. Questi frammenti sono inclusi in più pagine che vengono distribuite a più utenti con le loro cache private nel browser. Quindi "condividere" non significa condividere solo tra le persone, ma tra parti di software. Se desideri trovare una potenziale cache "condivisa", rintraccia la struttura fino alla radice e individua un predecessore comune: è qui che dovresti memorizzare la cache.

Distribuzione geospaziale - Se gli utenti sono distribuiti in tutto il mondo, l'utilizzo di una rete distribuita di cache potrebbe contribuire a ridurre la latenza.

Larghezza di banda e latenza di rete - A proposito di latenza, chi sono i tuoi clienti e che tipo di rete utilizzano? Forse i tuoi clienti sono clienti mobili in un paese sottosviluppato che utilizzano la connessione 3G di smartphone di vecchia generazione? Prendi in considerazione la creazione di oggetti più piccoli e memorizzali nella cache del browser.

Questa lista di gran lunga non è esaustiva, ma pensiamo che ormai abbiate capito l'idea.

Regole di base per il caching collegato

Ancora una volta - la memorizzazione nella cache è difficile. Condividiamo alcune regole di base, che abbiamo estratto da progetti precedenti che possono aiutarti a evitare problemi nel tuo progetto.

Evita il Double Caching

Ciascuno dei livelli introdotti nell'ultimo capitolo fornisce un valore nella catena di memorizzazione in cache. Salvando i cicli di elaborazione o avvicinando i dati al consumatore. Non è sbagliato memorizzare in cache una parte di dati in più fasi della catena, ma è sempre necessario considerare i vantaggi e i costi della fase successiva. La memorizzazione in cache di una pagina intera nel sistema Publish di solito non offre alcun vantaggio, come già avviene in Dispatcher.

Unione di strategie di invalidazione

Esistono tre strategie di invalidazione di base:

  • TTL, durata: Un oggetto scade dopo un periodo di tempo fisso (ad esempio, "2 ore da ora")
  • Data di scadenza: L'oggetto scade all'ora futura definita (ad esempio, "17:00 del 10 giugno 2019")
  • Basato su evento: l'oggetto viene invalidato esplicitamente da un evento che si è verificato nella piattaforma (ad esempio, quando una pagina viene modificata e attivata)

Ora puoi utilizzare strategie diverse su diversi livelli di cache, ma ce ne sono alcune "tossiche".

Annullamento della validità basato su eventi

Annullamento della validità basato su evento puro

Annullamento della validità basato su evento puro: annullamento della validità dalla cache interna al livello esterno

L’invalidazione pura basata su eventi è la più semplice da comprendere, la più semplice da ottenere teoricamente corretta e la più accurata.

In breve, le cache vengono invalidate una alla volta dopo che l’oggetto è stato modificato.

Devi solo tenere presente una regola:

Annulla sempre la validità dalla cache interna a quella esterna. Se prima hai invalidato una cache esterna, questa potrebbe rimemorizzare in cache il contenuto non aggiornato proveniente da una cache interna. Non fare più supposizioni sull’ora di aggiornamento di una cache, assicurati che. Meglio, attivando l'invalidazione della cache esterna dopo l'invalidazione di quella interna.

Questa è la teoria. Ma in pratica ci sono un certo numero di errori. Gli eventi devono essere distribuiti, potenzialmente su una rete. In pratica, questo rende il regime di invalidazione più difficile da attuare.

Auto - Correzione

Con l’annullamento della validità basato su eventi, è necessario disporre di un piano di emergenza. Cosa succede se si dimentica un evento di invalidazione? Una strategia semplice potrebbe essere quella di invalidare o eliminare dopo un certo periodo di tempo. Quindi, potresti non aver visto quell’evento e ora distribuisci contenuti non aggiornati. Ma gli oggetti hanno anche un TTL implicito di solo diverse ore (giorni). Quindi alla fine il sistema si auto-guarisce da solo.

Annullamento della validità basato su TTL puro

Annullamento della validità basato su TTL non sincronizzato

Annullamento della validità basato su TTL non sincronizzato

Anche questo è un sistema abbastanza comune. Si sovrappongono diversi livelli di cache, ognuno dei quali ha il diritto di servire un oggetto per un certo periodo di tempo.

È facile da implementare. Sfortunatamente, è difficile prevedere l'effettiva durata di vita di un dato.

Possibilità esterna di prolungare la durata di un oggetto interno

Cache esterna che prolunga la durata di un oggetto interno

Prendi in considerazione l’illustrazione precedente. Ogni livello di caching introduce un TTL di 2 minuti. Ora - anche il TTL complessivo deve essere di 2 minuti, giusto? Non proprio. Se il livello esterno recupera l'oggetto appena prima che diventi obsoleto, il livello esterno in realtà prolunga il tempo di vita effettivo dell'oggetto. In tal caso, il tempo effettivo di esecuzione può essere compreso tra 2 e 4 minuti. Considera che hai concordato con il tuo reparto aziendale, un giorno è tollerabile - e hai quattro livelli di cache. Il TTL effettivo su ciascun livello non deve superare le sei ore… aumentando la percentuale di mancati riscontri nella cache…

Non stiamo dicendo che sia un cattivo schema. Dovresti solo conoscerne i limiti. Ed è una strategia facile e piacevole con cui iniziare. Solo se il traffico del tuo sito aumenta, potresti prendere in considerazione una strategia più precisa.

Sincronizzazione dell'ora di invalidazione mediante l'impostazione di una data specifica

Annullamento della validità basato sulla data di scadenza

Si ottiene una durata effettiva più prevedibile, se si imposta una data specifica sull'oggetto interno e la si propaga alle cache esterne.

Sincronizzazione delle date di scadenza

Sincronizzazione delle date di scadenza

Tuttavia, non tutte le cache sono in grado di propagare le date. E può diventare brutto, quando la cache esterna aggrega due oggetti interni con date di scadenza diverse.

Combinazione dell’annullamento della validità basato su eventi e su TTL

Unione di strategie basate su eventi e su TTL

Unione di strategie basate su eventi e su TTL

Un altro schema comune nel mondo dell’AEM è quello di utilizzare l’invalidazione basata sugli eventi nelle cache interne (ad esempio, cache in memoria in cui gli eventi possono essere elaborati quasi in tempo reale) e nelle cache basate su TTL all’esterno, dove forse non si ha accesso all’invalidazione esplicita.

Nel mondo AEM, si avrebbe una cache in memoria per oggetti business e frammenti HTML nei sistemi Publish, che viene invalidata, quando cambiano le risorse sottostanti e si propaga questo evento di modifica al dispatcher, che funziona anche in base agli eventi. Prima di questo avresti, ad esempio, una rete CDN basata su TTL.

Avere un livello di caching basato su TTL (breve) davanti a un Dispatcher potrebbe attenuare efficacemente un picco che solitamente si verifica dopo un’invalidazione automatica.

Combinazione di TTL e invalidazione basata su eventi

Combinazione di TTL - e annullamento della validità basato su eventi

Tossico: miscelazione di TTL - e invalidazione basata su eventi

Questa combinazione è tossica. Non inserire mai una cache basata su eventi dopo una cache basata su TTL o Expiry. Ricordate quell'effetto di ricaduta che avevamo nella strategia "pure-TTL"? Lo stesso effetto può essere osservato qui. Solo che l’evento di invalidazione della cache esterna è già accaduto potrebbe non accadere più - mai, Questo può espandere la durata dell’oggetto memorizzato nella cache all’infinito.

Combinazione basata su TTL ed evento: effetto di ricaduta sullinfinito

Combinazione basata su TTL ed evento: effetto di ricaduta sull'infinito

Memorizzazione nella cache parziale e memorizzazione nella cache in memoria

Potete agganciarvi allo stadio del processo di rendering per aggiungere livelli di memorizzazione nella cache. Dal recupero di oggetti di trasferimento dati remoti alla creazione di oggetti business locali al caching del markup di un singolo componente. Lasceremo le implementazioni concrete a un tutorial successivo. Ma forse hai già implementato tu stesso alcuni di questi livelli di caching. Quindi il minimo che possiamo fare qui è introdurre i principi di base - e gotchas.

Parole di avvertimento

Rispetta controllo di accesso

Le tecniche qui descritte sono piuttosto potenti e un must-have in ogni casella degli strumenti per gli sviluppatori AEM. Ma non emozionatevi troppo, usateli con saggezza. Memorizzare un oggetto in una cache e condividerlo con altri utenti nelle richieste di follow-up significa in realtà eludere il controllo degli accessi. Questo di solito non è un problema sui siti web rivolti al pubblico, ma può esserlo, quando un utente deve effettuare l’accesso prima di ottenerlo.

Considera di memorizzare il markup HTML del menu principale Sites in una cache in memoria per condividerlo tra varie pagine. In realtà si tratta di un esempio perfetto per archiviare HTML parzialmente renderizzati, in quanto la creazione di una navigazione è solitamente costosa in quanto richiede l’attraversamento di molte pagine.

Non stai condividendo la stessa struttura di menu tra tutte le pagine, ma anche con tutti gli utenti, il che la rende ancora più efficiente. Ma aspetta … forse ci sono alcuni elementi nel menu che sono riservati solo a un certo gruppo di utenti. In tal caso, il caching può diventare un po’ più complesso.