Memcached – 2

Come già accennato nel precedente post, memcached è un daemon piuttosto semplice da configurare e istallare.

Sui sistemi Debian e derivati memcached può essere istallato con

sudo aptitude install memcached

altrimenti si può ricorrere ai sistemi di pacchettizzazione delle altre architetture o direttamente ai sorgenti rilasciati dagli sviluppatori.

Se si istalla da pacchetto debian a valle dell’istallazione verrà lanciato un daemon che, come risulta da ps aux, sarà:

/usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1

La configurazione completa sarà invece in

/etc/memcached.conf

Analizziamo i parametri di avvio

  • -l: l’ip su cui il demone è in ascolto
  • -p: la porta TCP su cui il demone è in ascolto
  • -m: la quantità di memoria (in MB) che viene assegnata al demone memcached

e non visibili perché con impostazioni di default (ma riportati sul file di configurazione)

  • -d: memcached viene lanciato in modalità demone e quindi rilascia il controllo all’ambiente che lo ha avviato
  • logfile: path del file di log
  • -c: numero massimo di connessioni contemporanee accettate
  • -M: ritorna errore nel caso non ci sia memoria disponibile
  • -v: incremento del livello di dettaglio nei log
  • -vv: ulteriore incremento del livello di dettaglio nei log

I più imprtanti per il tooning sono ovviamente -m, -c e -M. Nel determinare il primo bisogna tener conto che se l’uso di memcached fa si che il server debba appoggiarsi sullo swap l’effetto complessivo sarà con ogni probabilità quello di peggiorare le prestazioni.

Vale la pena spendere due parole su -M; di default memcached quando non ha più spazio disponibile sovrascrive i valori più vecchi e meno utilizzati. Questo viene indicato come evictions nei report e nella documentazione. Se questo sia accettabile o no dipende da considerazione sull’applicazione che si sta realizzando ma è in genere molto ragionevole per della cache. -M permette di cambiare questo comportamento nel caso dovesse essere necessario.

Per connettersi ad un server memcached è possibile utilizzare un semplice telnet:

telnet localhost 11211

Una volta connessi si possono in teoria eseguire tutte le operazioni; ad esempio salvare una variabile

set pluto 123 0 3
o

dove viene detto di salvare nella variabile pluto il valore o. 123 è un numero arbitrario usato nel protocollo di comunicazione, 0 il tempo di expire del valore (in questo caso infinito) e 3 la dimensione dei dati che verranno inviati.

Si può poi rileggere lo stesso valore con un

get pluto

Attenzione che anche un solo spazio in più fa fallire l’esecuzione del comando.

Questo uso con telnet è paragonabile all’invio della posta con lo stesso strumento ma rimane utile per test e troubleshooting. Qualsiasi uso applicativo deve passare attraverso un’apposita libreria in un qualche linguaggio (php, perl…). Oltretutto a questa libreria sono completamente demandate le funzionalità necessarie per l’uso in cluster.

Il telnet inoltre permette di accedere a ben quattro report molto dettagliati sullo stato interno del daemon:

stats
stats items
stats slabs
stats sizes

Questi quattro comandi sono alla base di report più ad alto livello. Decisamente più maneggevole è ad esempio memcache-top. Questo permette di avere un’istantanea molto comprensibile  dello stato di un pool e dell’efficacia dell’uso che se ne fa:

memcache-top --commands --instance=serv1:port1[,serv2:port2...]

il report sarà qualche cosa come:

memcache-top v0.5       (default port: 11211, color: on, refresh: 3 seconds)

INSTANCE                USAGE   HIT %   CONN    TIME    EVICT   READ    WRITE
serv1:port1             90%     80%     800     0.6ms   20      10G     20G    
serv2:port2             90%     80%     700     0.5ms   10      15G     30G  
...

AVERAGE:                90%     80%     750     0.5ms   15      12.5G   25G  

TOTAL:                  2GB            1500     11.0ms  30      25G     50G    
(ctrl-c to quit.)

Questo report, se non specificato diversamente, viene rigenerato ogni 3s e si riferisce a questo intervallo temporale.

Memcached – 1

Sui sistemi che devono fornire contenuti web dinamici la cache diventa rapidamente un aspetto cruciale al crescere del traffico; su web infatti si possono raggiungere frequenze di accessi ai dati veramente notevoli. Per fortuna, anche se questo è sempre meno vero, c’è una fortissima sproporzione tra gli accessi in lettura e quelli in scrittura e questo permette notevoli semplificazioni nelle soluzione di questo problema.

Di fatto il modo migliore per gestire la massa degli accessi in lettura è l’utilizzo di un qualche sistema di cache. Cache che dovrà essere quanto possibile veloce e semplice. Memcached nasce proprio per questo scopo: permette di riservare su un server un’area di memoria, renderla accessibile via TCP e di salvare su memoria dei valori recuperabili successivamente sulla base di una chiave.

Per rimanere semplice e veloce, memcached mantiene i dati solo in memoria e non li scrive su disco, ne consegue che ogni volta che viene riavviato perde tutti i propri dati. Questo però è un compromesso assolutamente ragionevole per della cache.

Supponiamo ora di dover gestire un sito ad alto traffico e di renderci conto che il nostro database sta divenendo un collo di bottiglia per il nostro sistema. Decidiamo quindi di introdurre memcached e di riuscire in questo modo sia a migliorare le prestazioni del sito sia a ridurre notevolmete gli accessi al database. Nei mesi successivi il traffico sul nostro sito potrà quindi crescere ancora. Si è venuto a creare in questo modo un problema piuttosto insidioso: se il daemon memcached si dovesse riavviare, perderemmo la nostra cache e ci troveremmo con un database non più sufficiente a supportare il nostro sito: sarebbe quindi molto difficile far ripartire il sistema nel suo insieme.

In pratica, se si vogliono sfruttare veramente i vantaggi di memcached bisogna distribuire la cache su diversi server (tutti i server apache ad esempio) in modo tale che al riavvio di un demone memcached si perderebbe solo una parte della cache e il sovraccarico sui database sarebbe quindi contenuto.

I cluster di server memcached sono peculiari in quanto ogni server è un’ entità a se che si preoccupa solamente di immagazzinare e restituire i dati dalla propria memoria e non ha conoscenza del fatto di essere parte di un pool. La logica della gestione del pool è demandata completamente ai client.

Ogni client suddivide la cache in tante parti sulla base della conoscenza deila lista dei server del pool e si andrà a poi a connettere sul server corretto per il salvataggio o il recupero dei dati. L’algoritmo utilizzato per questa operazione è piuttosto interessante e sarà argomento di un altro post.

Un altro problema che si può presentare con questi sistemi deriva dal fatto che su molti siti web ci sono pagine molto accedute e pagine a basso traffico: su un portale probabilmente gran parte degli accessi saranno sulla homepage. Oggetti della cache che vengono utilizzati in queste pagine saranno quindi particolarmente critici e la perdita di uno di questi potrebbe essere un problema anche se percentualmente gran parte della cache è comunque disponibile.

Come detto gà più volte il daemon è piuttosto semplice e semplice è anche la sua configurazioni. La configurazione si riduce di fatto a scegliere:

    • la memoria da riservare
    • il numero massimo di connessioni accettabili
    • se salvare dei log su file