PHP – Velocizzare le pagine con APC

7 Lug

Out Of Date Warning

Questo post è stato pubblicato più di 2 anni fa (il 7 luglio 2012). Le idee vanno avanti velocemente, le prospettive cambiano quindi i contenuti potrebbero non essere aggiornati. Ti prego di tenere in considerazione questo, e di verificare le informazioni tecniche presenti nell'articolo prima di farne affidamento per i tuoi scopi.

APC (Alternative PHP Cache) è un’estensione per il caching e l’ottimizzazione del codice intermedio PHP.

Premessa

La cache è una memoria temporanea (secondaria) nella quale possiamo memorizzare le informazioni per un più veloce accesso futuro. La cache è sicuramente meno capiente della memoria principale (qualunque essa sia), ma è molto più performante. Wikipedia dice:

Una cache è associata ad una memoria “principale”, in cui risiedono i dati. Essa è tipicamente di capienza inferiore rispetto alla memoria principale, ma il suo utilizzo è più conveniente in termini di tempo di accesso e/o carico sul sistema.
Quando è necessario l’accesso ad un dato, questo dato viene prima cercato nella cache. Se è presente e valido, viene utilizzata la copia presente. Viceversa, viene recuperato dalla memoria principale, e memorizzato nella cache, nel caso possa servire successivamente.

Quindi l’obiettivo della cache è memorizzare informazioni il cui reperimento è particolarmente dispendioso, come l’esecuzione di queries complesse da un database.
In pratica se l’informazione non è stata modificata nel corso del tempo converrà recuperarla dalla cache piuttosto che rieseguire nuovamente la query tutte le volte che ne abbiamo bisogno.
Naturalmente dovremo escogitare un sistema che garantisca che le informazioni memorizzate nella cache siano aggiornate, altrimenti rischiamo di combinare un “bel pasticcio”.
Di solito quando si memorizza un dato nella cache si specifica anche un tempo di vita (lifetime). Passato questo tempo l’informazione non sarà valida.
Tuttavia, anche settando lifetime particolarmente bassi, potrebbe sempre verificarsi l’ipotisi di un aggiornamento del dato prima della sua scadenza. In questo caso la regola più semplice da seguire è quella di eliminarlo dalla cache oppure, ancora più semplice, svuotare completamente la cache ad ogni aggiornamento.
Riassumendo, un sistema di cache in PHP dovrebbe lavorare, grosso modo, in questo modo:

  1. Ho bisogno di un certo dato.
  2. Controllo se il dato è memorizzato nella cache (e non è scaduto).
  3. Se il dato non c’è (o è scaduto) lo recupero della memoria principale (per esempio dal DB) e lo salvo nella cache.
  4. Prelevo il dato dalla cache.

Naturalmente si presuppone che il punto 3 sia per la maggior parte delle volte saltato, rendendo quindi efficace il meccanismo.

Installazione

APC è disponibile tramite PECL (PHP Extension Community Library), cioè un archivio di moduli che estendono l’interprete PHP.
Per l’installazione vedere: www.php.net/manual/en/apc.installation.php
Mentre su macchine Windows bisogna scaricare l’estensione (.dll) ed aggiungerla al php.ini, vedere:
docs.moodle.org/20/en/Installing_APC_in_Windows

APC come acceleratore

Oltre a fornire un sistema di caching (di cui parleremo dopo), APC fa parte anche degli acceleratori di bytecode, cioè del codice intermedio di PHP.
Essendo PHP un linguaggio interpretato, ad ogni esecuzione, prima il codice sorgente viene tradotto in un codice intermedio (bytecode o codice oggetto) e poi viene eseguito.
In pratica, PHP usa un’architettura di esecuzione a due tempi. Fase uno, compilazione del codice sorgente in codice intermedio. Fase due esecuzione del codice intermedio. Ma cosa succede una volta che il codice intermedio viene eseguito? Il codice viene deallocato e distrutto. Questo significa che alla successiva esecuzione dello script lo Zend Engine (l’interprete PHP) dovrà ritradurre il codice sorgente in codice intermedio e rieseguire il codice intermedio.
Questo approccio, che da un lato può offrire anche diversi vantaggi (es. perfetto isolamento tra diverse richieste) dall’altro, soprattutto per siti con milioni di visitatori giornalieri, può rappresentare un collo di bottiglia, difatti il processo di interpretazione è sicuramente oneroso in termini di tempo.
Gli acceleratori (come APC) servono appunto per memorizzare il codice intermedio in una cache temporanea per riutilizzarlo alla successiva richiesta di interpretazione. Questa funzionalità è svolta in maniera del tutto trasparente e senza nessun intervento sul codice sorgente.
I vantaggi ottenuti dall’utilizzo di un acceleratore dipendono fortemente dalla natura dell’applicazione. Applicazioni in cui la maggior parte dell’overhead è sull’attesa di una risposta del database, beneficeranno in maniera minore dell’annullamento dell’overhead di compilazione. D’altra parte, applicazioni che utilizzeranno molti files, con sovraccarichi di esecuzione relativamente bassi potranno ottenere un notevole aumento delle prestazioni.

Nota: Il codice intermedio è un codice composto da operazioni molto semplici, piuttosto simile all’Assembly.

APC come sistema di caching

Vediamo ora come , noi sviluppatori, possiamo utilizzare APC per memorizzare e leggere informazioni dalla cache. L’estensione è infatti provvista di una seri di funzioni che ci rendono semplice il lavoro.

Salvare dati nella cache

Possiamo farlo con due comode funzioni: apc_add ed apc_store:
bool apc_add ( string $key [, mixed $var [, int $ttl = 0 ]] )
bool apc_store ( string $key , mixed $var [, int $ttl = 0 ] )

$key: è la chiave del dato da memorizzare.
$var: è il valore da memorizzare.
$ttl: è il tempo per il quale il dato è valido.

Le due funzioni accettano anche questa sintassi:
array apc_add ( array $values [, mixed $unused [, int $ttl = 0 ]] )
array apc_store ( array $values [, mixed $unused [, int $ttl = 0 ]] )

$values è un array in cui le chiavi sono le chiavi del dato da memorizzare.

Entrambe le funzioni restituiscono true o false a seconda se il dato viene memorizzato o meno. In caso della variante con array sarà restituito un array con le chiavi che generano errore (che non vengono memorizzate).
Se il tempo di vita (ttl) non viene indicato il valore di default è 0 (zero), cioè nessuna scadenza. Possiamo memorizzare qualsiasi tipo di dato, numeri, stringhe, array oggetti etc..
La differenza tra apc_add ed apc_store consiste nel fatto che la prima non sovrascriverà mai una chiave esistente, mentre la seconda si.

Leggere dalla cache

Per leggere un dato dalla cache possiamo utilizzare la funzione apc_fetch():

Rimuovere un dato dalla cache

Per cancellare un dato dalla cache usiamo la funzione apc_delete():
mixed apc_delete ( string $key )

$key è la chiave che vogliamo rimuovere.
Ritorna true o false in caso di successo o fallimento.

Svuotare la cache

Possiamo anche decidere di svuotare completamente la cache. In questo caso usiamo la funzione apc_clear_cache(). Visto che APC potrà anche essere usato come acceleratore, dobbiamo specificare quale cache eliminare:
bool apc_clear_cache ([ string $cache_type ] )

cache_type: se è “user“, allora sarà svuotata la cache utente; altrimenti sarà pulita la cache di sistema (APC come acceleratore).
Ritorna true o false in caso di successo o fallimento.

Modificare valori numerici

In caso volessimo memorizzare valori numerici abbiamo due comode funzione per aumentarli o decrementarli: apc_inc ed apc_dec.
int apc_inc ( string $key [, int $step = 1 [, bool &$success ]] )
int apc_dec ( string $key [, int $step = 1 [, bool &$success ]] )

$key: è la chiave che vogliamo modificare
$step: è il valore da incrementare o decremenentare

Restituisce il valore corrente della chiave in caso di successo o false in caso di errore.

Verificare se una chiave esiste

Per farlo possiamo usare la funzione apc_exists.
La funzione accetta come unico parametro la chiave da verificare. La chiave può essere sia una stringa che un array, contenete chiavi.
Ritorna true o false a seconda se la chiave esiste o meno. Nel caso fosse passato un array ritorna un array contenente le chiavi esistenti o un array vuoto nel caso non ne esista nessuna.

Conclusioni

Alternative PHP Cache è una cache opcode in grado di accelerare significativamente le applicazioni PHP, mettendo in cache sia il codice intermedio PHP che le variabili utente.
Aggiungere APC ad un’applicazione in genere si traduce in un sensibile miglioramento dei suoi tempi di risposta, il carico del server viene ridotto e gli utenti (nonchè gli sviluppatori) sono più felici 🙂

Risorse

www.php.net/manual/en/book.apc.php

Lascia un commento