Jul 142012
 

Se sei un amministratore di sistema e vuoi spingere le prestazioni del tuo sito web PHP come Drupal, WordPress o scritto da voi o da altri programmatori, ci sono buone possibilità che abbiate sentito parlare della Cache alternativa di PHP o semplicemente APC.

Alternative PHP Cache (APC) è una cache opcode libera ed open source per PHP. Il suo obiettivo è quello di fornire un framework aperto e robusto per il caching e ottimizzare il codice intermedio di PHP.

Questo è più o meno tutto ciò che leggerete su APC sul sito php.net, e credo che non sia sufficiente in confronto all’enorme aumento di prestazioni che questo piccolo componente è in grado di dare, per alcuni dati veloci controllare i test eseguiti da Guillermo Garron sul suo sito web.

Come funziona APC

La prima cosa che dovete sapere, è come un programma PHP viene eseguito dal motore Zend, questi sono i passi per andare dallo script PHP al codice realmente utilizzato dal motore, questo è comunemente noto come “codice operativo” o opcodes, che rappresenta la funzione del codice.

  1. Il primo passo è la lettura del codice PHP dal filesystem ed il suo spostamento in memoria.
  2. Lexing: L’interno del codice php viene convertito in token o lexicons.
  3. Parsing: Durante questa fase, i token vengono elaborati per ricavare delle espressioni significative.
  4. Compilazione: Le espressioni derivate vengono compilate in opcodes.
  5. Esecuzione: L’opcodes viene eseguito per ottenere il risultato finale.

L’obiettivo di APC è bypassare i passaggi da 1 a 4, facendo da cache in un segmento di memoria condivisa i codici operativi generati e poi copiandoli nel processo di esecuzione in modo da Zend possa effettivamente eseguirli.

Da lampzone.wordpress.com

Ecco i passaggi dettagliati di ciò che fa realmente APC

1. Durante l’inizializzazione del modulo ( MINIT), APC usa mmap per mappare file in memoria condivisa.

2. Durante il momento della richiesta, APC rimpiazza zend_compile_file() con i propri my_compile_file().

Cosa fa my_compile_file ?

1. Se APC non riesce a trovare il file nella cache, APC chiamerà zend_compile_file per compilare il file

2. Prende l’opcodes che viene restituito e lo metto nella memoria condivisa che viene letta/scritta dai vari processi child di Apache. ( In questo esempio stiamo parlando di Apache MPM prefork.)

3. Conserva nella memoria condivisa anche classi e function tables.

4. Copia l’opcodes nella memoria dei child di Apache in modo che Zend possa eseguirlo nella fase di esecuzione.

Quindi questa è la teoria, vediamo ora come installarlo e configurarlo

Installazione di APC

APC è una estensione di PHP, quindi si hanno 2 metodi per installarlo :

1) Installare APC da un repository della vostra distribuzione.
Suggerisco di usare questo metodo, quando possibile, mantenendo tutto quello che avete sul vostro computer/server installato da un repository è una buona pratica che cerco sempre di seguire.

Su Debian e Ubuntu APC è disponibile sul repository principale con questo nome:

root@xubuntu-home:~# apt-cache search apc php
php-apc - APC (Alternative PHP Cache) module for PHP 5

E’ possibile quindi installarlo con il comando:

sudo aptitude install php-apc

Mentre se usate Red Hat Enterprise, Centos o Fedora potete usare questo comando :

sudo yum install php-pecl-apc

2) Il secondo modo per installare APC è con PECL con questo metodo potrete scaricare l’ultima versione sorgente e compilarla sul vostro computer.

Su Debian e Ubuntu dovrebbe funzionare (il nome dei pacchetti potrebbe cambiare a seconda della versione di Ubuntu/Debian che usate)

$ sudo apt-get install php-pear php5-dev apache2-threaded-dev build-essential
$ sudo pecl install apc

Come detto suggerisco il numero metodo 1, nel secondo si potrebbero avere dei problemi durante la compilazione e nel corso del tempo alcuni aggiornamenti potrebbero “rompere” l’installazione locale di APC.

Configurazione APC

APC Una volta installato deve essere abilitato nel file di configurazione di PHP: php.ini, se APC è stato installato da pacchetto tutto dovrebbe già essere fatto e quindi basta riavviare il Apache (o il demone FastCGI come FPM) per vedere una nuova sezione APC nel phpinfo () che conferma che è abilitato.

Altrimenti dovrete includere nel vostro file php.ini questa direttiva:

extension=apc.so

Questo è sufficiente per avere APC installato con tutti i parametri di default, ma probabilmente si desidera modificare alcuni dei valori di default.
Tra i parametri c’è apc.shm_size, che specifica la quantità di memoria da utilizzare per APC, il valore predefinito è 30 MB, a seconda dell’applicazione e la RAM sul server aumentate questo numero a 64, 128 o addirittura 512 MB.

Questa è una configurazione suggerita per una macchina con 1GB di RAM

# cat /etc/php5/conf.d/apc.ini
extension=apc.so
apc.enabled=1
apc.shm_size=128
apc.cache_by_default="1"
apc.shm_segments="1"
apc.ttl="7200"
apc.user_ttl="7200"
apc.gc_ttl="1800"
apc.optimization = 0
apc.num_files_hint="1024"
apc.use_request_time = 1
apc.mmap_file_mask="/tmp/apc.XXXXXX"
apc.enable_cli="0"
apc.slam_defense="0"
apc.file_update_protection="2"
apc.max_file_size="1M"
apc.stat="1"
apc.write_lock="1"
apc.report_autofilter="0"
apc.include_once_override="0"
apc.rfc1867="0"
apc.rfc1867_prefix="upload_"
apc.rfc1867_name="APC_UPLOAD_PROGRESS"
apc.rfc1867_freq="0"
apc.localcache="0"
apc.localcache.size="512"
apc.coredump_unmap="0"

Per una spiegazione completa di queste impostazioni, fare riferimento alla documentazione online .

APC include una pagina web dove è possibile vedere l’utilizzo della cache, comprese la frammentazione e altre informazioni utili. Copiate il file apc.php (che si trova in /usr/share/doc/php-apc/apc.php per Debian e Ubuntu) nella vostra document root e puntate il browser a questo indirizzo per vedere una schermata simile a questa.

apc.php

Da qua si possono vedere le % di hit/miss e un dato importante: Cache full count, questo numero dice quante volte la cache è stata completamente riempita, se questo numero si alza troppo in fretta è probabile che dobbiate alzare la dimensione della cache.

Una parola di avvertimento: se non si riavvia periodicamente Apache o PHP-FPM, la cache potrebbe diventare frammentata, come potrete vedere visitando quella pagina web. Per evitarlo potete periodicamente svuotare la cache. Io uso un cron che una volta al giorno chiama una pagina web sul mio sito, che ho chiamato apc-clear.php, che svuota la cache. Inoltre, controlla che l’indirizzo che l’invoca sia locale in modo che non possa essere chiamato dall’esterno. Ecco il contenuto di APC-clear.php:

<?php
if (in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1')))
{
  apc_clear_cache();
  apc_clear_cache('user');
  apc_clear_cache('opcode');
  echo json_encode(array('success' => true));
}
else
{
  die('SUPER TOP SECRET');
}

E questo è il mio cron:

0 6 * * * /usr/bin/curl --silent http://myserver.com/subdir/apc-clear.php

Conclusioni

Come avete visto in questo articolo, la configurazione di APC è davvero facile e migliora il throughput delle vostre pagine php molte volte, quindi perché non si dovrebbe usarlo?

Popular Posts:

Flattr this!

  12 Responses to “Tutto quello che c’è da sapere su APC (Alternate PHP cache)”

  1. Hi,
    I installed APC to server for my project but I have a problem about caching file. Server caching php files but after refresh on project page server caching same files again and reset the hit number of files.
    I didn’t solve this situation, what is the problem is there any missing configuration for APC?

    • Hello Mert,
      What the configuration of your APC ?
      In general the defaults are good enough once you have put the correct size of your APC cache.

  2. Okay, I just enabled APC Support. When I visit mydomain/info.php I can see that it is ENABLED. Do I have to do anything else? Do I have to incorporate any PHP code into my PHP files?

    Thank you!
    Richard

  3. Hi,

    Great post.

    However, and IMHO, you should call your php script from the command line rather than through curl, then the webserver. So you can get rid of the test on localhost.
    0 6 * * * /usr/bin/php /subdir/apc-clear.php

    And by the way, it seems important to me to specify that it’s a reasonably good practice to set apc.stat to 0 (Off) for a production server as it increase dramatically the performances of the caching (without forgetting a cache-clearing after an app update). It means that when a file is cached, apc doesn’t check every time if the file has changed before executing it, plus it’s better to avoid problem during the upload when you update your app for a busy site.

    Regards,

    • Thanks for the feedback,

      I’ve used curl mainly because APC it’s disabled for CLI on my setup, if it’s enabled in your you can probably use cron without any problem.

      Regarding apc.stat, all correct just remember that you’ll have to restart apache/php-fpm or clean the cache by hand any time you want to update your website.

  4. Hello!

    I tried to use your apc-clear.php, but is resulting in HTTP 500 Forbidden Error. Do you know what’s happened?

    Thanks a lot and congratulations for your article.

  5. I am using APC with Drupal 7 with the following configuration:
    apc.max_file_size=2M
    apc.ttl=7200
    apc.user_ttl=7200
    apc.gc_ttl=3600
    apc.shm_segments=1
    apc.shm_size=1028M
    apc.stat=0

    For the first 30 minutes after I restart Apache, the site works very good, but it gets slower gradually..I don`t know what I am missing.Any help would be appreciated..thanks

    • I suggest to enable the apc.php utility page on your webserver, in this way it will be easier for you to see at a glance if there are problems (fragmentation or full memory used)

  6. I am using APC with Magento. It uses the assigned memory untill it has used around 80%, then it stops caching new pages. Pages in cache are served fast, pages that aren’t in cache are slower and don’t get cahced anymore. It’s been tested with les memory configured in pac.shm.size, but the problem remains the same. Any ideas about what might be wrong?

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*