Php info test Memcached

Memcache è un modulo del PHP che fornisce un’interfaccia procedurale e orientata agli oggetti per il daemon di memorizzazione per la cache, serve a ridurre il carico del database nelle applicazioni Web dinamiche.

 

Quindi si tratta di  un sistema autonomo di caching in Ram per gli oggetti. Serve per sollevare le query al database e fornire i dati agli utenti appunto dalla memoria Ram.

E’ stato ideato proprio per gestire siti come LiveJournal con 20 milioni di richieste e relative query al database al giorno.

Viene rilasciato su licenza open source BSD e al momento che vi stiamo scrivendo siamo arrivati alla versione 1.5.4

Uno schema grafico del suo funzionamento potrebbe essere il seguente

 

Giusto per farvi comprendere le potenzialità di questo sistema, sappiate che è utilizzato anche da wikipedia.

Memcache schema di immagazzinamento cache
E per essere piu’ precisi ad oggi i siti che utilizzano Memcached come sistema di cache sono

  • LiveJournal
  • Wikipedia
  • Flickr
  • Bebo
  • WordPress.com
  • Craigslist
  • Mixi

Che insomma non hanno certo bisogno di tante presentazioni.

Installazione Memcached

In primis sappiate che questo modulo funziona per le principali distribuzioni di Linux.

Per Debian 

apt-get install memcached

Per Redhat/Fedora:

yum install memcached

Questo sistema di cache dipende da l’ API libevent , la quale fornisce un meccanismo per eseguire una funzione di callback quando si verifica un evento specifico su un descrittore di file o dopo che è stato raggiunto un timeout. Inoltre, libevent supporta anche i callback a causa di segnali o timeout regolari .
libevent ha lo scopo di sostituire il ciclo di eventi trovato nei server di rete basati su eventi. Un’applicazione deve solo chiamare event_dispatch () e quindi aggiungere o rimuovere eventi dinamicamente senza dover modificare il ciclo degli eventi.

Fortunamente dal 2010 libevent è già presente nelle vostre distribuzioni linux e quindi per richiamarlo non dovrete fare altro che scrivere

  • Per Debian e Ubuntu apt-get install libevent-dev
  • Per Redhat/Fedora: yum install libevent-devel

Altrimenti dovete seguire queste istruzioni

wget https://memcached.org/latest
[you might need to rename the file]
tar -zxf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure --prefix=/usr/local/memcached
make && make test && sudo make install

Installare MemCached su Ubuntu

Ma siccome è ovvio che la distribuzione europea maggiormente installata è Ubuntu vediamo quindi come mettere il modulo MemCached proprio su questa distribuzione. Per installare dovrete eseguire da terminale le due seguenti istruzioni

sudo apt-get update
sudo apt-get install mysql-server php5-mysql php5 php5-memcached memcached

 

Come potete vedere installa due versione , la seconda a oggi è ritenuta piu’ stabile. Ovviamente con mysql già installato, altrimenti il sistema vi chiederà una psw e nick name per installarne uno.

A questo punto bisognerà verificare che il modulo sia funzionante. Non dovrete fare altro che controllare nella root predefinita /var/www/html il funzionamento con un semplice file php. Con la seguente istruzione

sudo nano /var/www/html/info.php

Dove il file php è un semplicissimo file di informazioni di default

<?php
phpinfo();
?>

A questo punto se il webserver apache è visibile dall’esterno dovreste potere vedere il tutto con il semplice url nella barra degli indirizzi.

http://nome_dominio_o_IP /info.php

Se l’estensione è abilitata correttamente ci dovrebbe essere presente un riguadro simile al seguente scorrendo verso il basso la pagina.

Per interrogare il funzionamento del servizio in tempo reale abbiamo le istruzioni

ps aux | grep memcached
memcache 6584 0.0 0.0 327448 3004 ? Sl 14:07 0:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1
demouser 6636 0.0 0.0 11744 904 pts/0 S+ 14:29 0:00 grep --color=auto memcached

Per riavviare singolarmente il servizio di memcache dovremo utilizzare le seguenti istruzioni

sudo service memcached restart

A questo punto vediamo come cachare i vostri dati. Creiamo un file di cache chiamato cache_prova.php e richiamiamolo con il comando

sudo nano /var/www/html/cache_prova.php

A questo punto create questo file nel seguente modo che vi commento direttamente dentro il file

<?php
$mem = new Memcached(); // Istanzia un oggetto di tipo Mem
$mem->addServer("127.0.0.1", 11211); // Aggiunge all'istanza il metodo add server localhost con parta 11211 di default

$result = $mem->get("blah"); // fissa la chiave a blah cookie session

if ($result) {
 echo $result;
} else {
 echo "No matching key found. I'll add that now!";
 $mem->set("blah", "I am data! I am held in memcached!") or die("Couldn't save anything to memcached...");
}
?>

La prima volta che il file viene richiamato nei cookie di sessione non è presente il valore blah e quindi il file stampa a video

No matching key found. I'll add that now!

e fissa la variabile blah al valore di I am held in memcached! La seconda volta che l’utente carica il file php, trova la variabile di sessione blah presente e quindi stampa a video

I am held in memcached!

Ecco questo è un primissimo esempio dell’applicazione memcache. Diciamo un suo possibile utilizzo.

Questo è un primo esempio di come funziona questa estensione memcached . Ovviamente si tratta di un esempio puramente didattico. Vediamo adesso un esempio più concreto dove sia presente anche un database.

Quindi accedete al vostro database mysql e immettete la passord di amministrazione di mysql

CREATE DATABASE prova_cache;
USE prova_cache;

Creiamo un utente chiamato testcache una password testing123 che abbia accesso al database che abbiamo creato:

GRANT ALL ON prova_cache.* TO test@localhost IDENTIFIED BY ‘testing123’;

Ora creeremo una tabella molto semplice e inseriremo un record. La tabella verrà chiamata sample_datae avrà solo un indice e un campo stringa:

CREATE TABLE sample_data (id int, name varchar(30));
INSERT INTO sample_data VALUES (1, “some_data”);

Ora, abbiamo creato la nostra struttura e inserito i dati. Possiamo uscire da MySQL:

exit

Crea lo script PHP in cache Dati MySQL per Memcached

 

Ora che abbiamo i nostri dati in MySQL, possiamo creare un altro script PHP che funzionerà in modo simile a un’applicazione PHP di produzione.

Cercherà i dati in memcached e restituirà se trova i dati. Se non trova i dati, interrogherà dal database stesso e quindi memorizzerà i risultati in memcached per le query future.

Per iniziare, create un altro script PHP nella nostra root dei documenti. Chiameremo questo script database_test.php:

sudo nano /var/www/html/database_test.php

Inizia in modo simile al nostro ultimo script. Creeremo un’istanza memcached PHP e poi diremo dove si trova il servizio memcached in esecuzione sul nostro server, proprio come abbiamo fatto l’ultima volta:

<?php
$mem = new Memcached();
$mem->addServer(“127.0.0.1”, 11211);
?>

Successivamente, nella nostra prima partenza dal nostro ultimo script, dovremo definire in che modo PHP può connettersi al nostro database MySQL. Abbiamo bisogno di specificare le credenziali di accesso per l’utente che abbiamo creato e quindi avremo bisogno di dirgli quale database utilizzare:

<?php
$mem = new Memcached();
$mem->addServer(“127.0.0.1”, 11211);

mysql_connect(“localhost”, “test”, “testing123”) or die(mysql_error());
mysql_select_db(“mem_test”) or die(mysql_error());
?>

Successivamente, dovremo progettare la query di cui abbiamo bisogno per recuperare i dati che abbiamo inserito nella nostra tabella. Lo memorizzeremo in una $queryvariabile.

Creeremo quindi una $querykey variabile per memorizzare la chiave che memcached userà per fare riferimento alle nostre informazioni.

Creiamo questa chiave utilizzando la stringa “KEY” e quindi aggiungendo il checksum md5 (un metodo di hashing) della nostra query fino alla fine. Ciò assicurerà che ogni chiave sia unica se dovessimo utilizzare questa tecnica su un set di dati più grande. Garantisce inoltre che una query corrispondente produrrà la stessa chiave per le richieste successive.

<?php
$mem = new Memcached();
$mem->addServer(“127.0.0.1”, 11211);

mysql_connect(“localhost”, “test”, “testing123”) or die(mysql_error());
mysql_select_db(“mem_test”) or die(mysql_error());

$query = “SELECT name FROM sample_data WHERE id = 1”;
$querykey = “KEY” . md5($query);

 

?>

Successivamente, creeremo una $result variabile, proprio come il nostro ultimo script. Ciò manterrà il risultato dalla nostra query memcached, proprio come prima. Stiamo chiedendo memcached per la chiave di query che abbiamo generato per vedere se ha un record identificato da quella chiave nel suo sistema.

<?php
$mem = new Memcached();
$mem->addServer(“127.0.0.1”, 11211);

mysql_connect(“localhost”, “test”, “testing123”) or die(mysql_error());
mysql_select_db(“mem_test”) or die(mysql_error());

$query = “SELECT name FROM sample_data WHERE id = 1”;
$querykey = “KEY” . md5($query);

$result = $mem->get($querykey);

?>

Ora siamo pronti a fare la vera logica di test che determinerà cosa accadrà quando il risultato verrà trovato in memcached. Se i risultati vengono trovati, vogliamo stampare i dati che abbiamo estratto e comunicare all’utente che siamo stati in grado di recuperarli direttamente da memcached:

<?php
$mem = new Memcached();
$mem->addServer(“127.0.0.1”, 11211);

mysql_connect(“localhost”, “test”, “testing123”) or die(mysql_error());
mysql_select_db(“mem_test”) or die(mysql_error());

$query = “SELECT name FROM sample_data WHERE id = 1”;
$querykey = “KEY” . md5($query);

$result = $mem->get($querykey);

if ($result) {
print “<p>Data was: ” . $result[0] . “</p>”;
print “<p>Caching success!</p><p>Retrieved data from memcached!</p>”;
}
?>

Ora, aggiungiamo la logica per lo scenario alternativo. Se i risultati non vengono trovati, vogliamo utilizzare la query che abbiamo creato per chiedere a MySQL i dati. Lo memorizzeremo nella $result variabile che abbiamo creato. Questo sarà sotto forma di un array.

Dopo aver ottenuto il risultato della query, è necessario aggiungere quel risultato alla memcached in modo che i dati siano lì la prossima volta che lo facciamo. Possiamo farlo inserendo memcached la chiave che vogliamo usare per fare riferimento ai dati (abbiamo già creato questo con la $querykeyvariabile), i dati stessi (memorizzati nella $resultvariabile dalla query MySQL) e il tempo di memorizzare i dati in cache secondi.

Inseriremo nella cache il nostro contenuto per 10 secondi. Nel mondo reale, molto probabilmente sarebbe utile memorizzare i contenuti a lungo. Forse qualcosa di più vicino a 10 minuti (600 secondi) se il contenuto non cambia molto. Per il test, un valore inferiore ci consente di vedere cosa sta succedendo più velocemente, senza riavviare il nostro servizio memcached.

Successivamente, stamperemo un messaggio simile con i risultati della query e diremo all’utente cosa è successo. Dovremmo aggiungere questo intero blocco come un elsenostro precedente if:

<?php
$mem = new Memcached();
$mem->addServer("127.0.0.1", 11211);

mysql_connect("localhost", "test", "testing123") or die(mysql_error());
mysql_select_db("mem_test") or die(mysql_error());

$query = "SELECT name FROM sample_data WHERE id = 1";
$querykey = "KEY" . md5($query);

$result = $mem->get($querykey);

if ($result) {
    print "<p>Data was: " . $result[0] . "</p>";
    print "<p>Caching success!</p><p>Retrieved data from memcached!</p>";
} else {
    $result = mysql_fetch_array(mysql_query($query)) or die(mysql_error());
    $mem->set($querykey, $result, 10);
    print "<p>Data was: " . $result[0] . "</p>";
    print "<p>Data not found in memcached.</p><p>Data retrieved from MySQL and stored in memcached for next time.</p>";
}
?>

Questa è la nostra sceneggiatura completa. Tenterà di ottenere dati da memcached e di restituirli. In caso contrario, eseguirà direttamente query da MySQL e memorizzerà i risultati per 10 secondi.

Prova lo script

Ora che abbiamo scritto lo script, possiamo eseguirlo andando nella nostra posizione file nel nostro browser web:

http: // server_domain_name_or_IP /database_test.php

La prima volta che visitiamo la pagina troveremo ovviamente l’if del result, la seconda l’else.

 

 

E’ un sistema ovviamente non completo, ma che rende abbastanza bene come affrontare la problematica della cache di un sito web o di un sitema distribuito.