Usa Memcached per le prestazioni aziendali Java, Parte 1: Architettura e configurazione

Sviluppata da Danga Interactive per migliorare le prestazioni del sito su LiveJournal.com, l'architettura distribuita di Memcached oggi supporta la scalabilità esponenziale delle applicazioni web sociali come Twitter, Facebook e Wikipedia. In questo tutorial in due parti, Sunil Patil introduce l'architettura hashtable distribuita di Memcached e inizia a utilizzarla per memorizzare nella cache i dati per le proprie applicazioni aziendali Java basate su database.

Questo tutorial ti introduce all'uso di Memcached per migliorare le prestazioni delle applicazioni aziendali Java. La prima metà inizia con una panoramica delle architetture di caching Java tradizionali rispetto all'architettura di Memcached. Inoltre installeremo Memcached sulla tua macchina e ti presenterò la configurazione e i comandi per lavorare con Memcached tramite Telnet. Nella seconda metà svilupperemo un programma client "Hello Memcached" in Java, che useremo per guardare sotto il cofano di un client spymemcached. Imparerai anche come usare Memcached per ridurre il carico sul tuo server di database e come usarlo per memorizzare nella cache il markup della pagina generato dinamicamente. Infine, considereremo alcune opzioni avanzate per la configurazione dei client spymemcached.

Ulteriori informazioni sul caching Java su JavaWorld

  • Vedere "Architetture di bilanciamento del carico del server, Parte 1: Bilanciamento del carico a livello di trasporto" per una discussione più approfondita sul caching distribuito con Memcached.
  • Vedere anche "Progetti Java open source: Java Caching System" per informazioni sul caching Java tradizionale.

Panoramica delle architetture di memorizzazione nella cache Memcached e Java

I framework di memorizzazione nella cache Java come EHCache e OSCache sono essenzialmente HashMapoggetti nel codice dell'applicazione. Ogni volta che aggiungi un nuovo oggetto alla cache, verrà archiviato nella memoria della tua applicazione. Questa strategia funziona bene per l'archiviazione di piccole quantità di dati, ma non funziona per la memorizzazione nella cache di più di pochi gigabyte (GB). I progettisti del server Memcached hanno adottato un approccio architettonico distribuito, che consente la scalabilità del sistema. Di conseguenza, puoi utilizzare Memcached per memorizzare nella cache un'enorme quantità di dati.

L'architettura di Memcached è composta da due pezzi. Il primo è un server Memcached che viene eseguito nel proprio processo. Se vuoi scalare la tua applicazione, puoi installare ed eseguire il server Memcached su macchine aggiuntive. Le istanze del server Memcached non sono a conoscenza l'una dell'altra. Il cliente Memcached, il secondo pezzo del sistema Memcached, non sa di ciascuno dei server. Il client è responsabile della raccolta del server per ogni voce della cache e della memorizzazione o dell'ottenimento della voce della cache, un processo che discuterò in dettaglio più avanti nell'articolo.

Se hai una certa esperienza lavorando su applicazioni web Java EE, è probabile che tu abbia utilizzato in precedenza un framework di memorizzazione nella cache Java open source come EHCache o OSCache. Potresti anche aver utilizzato un framework di memorizzazione nella cache commerciale fornito come parte del server delle applicazioni, come DynaCache (fornito con IBM WebSphere Application Server) o JBoss Cache (fornito con JBoss AS). Prima di entrare nella parte di apprendimento pratico di questo tutorial, è importante capire come Memcached differisce da questi tradizionali framework di cache Java.

Utilizzando una cache Java tradizionale

L'utilizzo di un tradizionale framework di cache Java è abbastanza semplice, indipendentemente dal fatto che si scelga un'opzione open source o commerciale. Per un framework open source come EHCache o OSCache, è necessario scaricare i file binari e aggiungere i file JAR necessari al percorso di classe dell'applicazione. Potrebbe anche essere necessario creare un file di configurazione da utilizzare per configurare la dimensione della cache, l'offload del disco e così via. Per un framework di memorizzazione nella cache fornito in bundle con un server delle applicazioni, in genere non è necessario scaricare alcun JAR aggiuntivo perché verrebbe fornito in bundle con il software.

Dopo aver aggiunto il supporto per il framework di memorizzazione nella cache nella tua applicazione, puoi iniziare a usarlo creando un CacheManageroggetto e ottenendo e impostando le voci della cache in esso. Dietro le quinte, il framework di cache creerebbe gli CacheManageroggetti nella stessa JVM in cui era in esecuzione l'applicazione. Ogni volta che si aggiungeva una voce di cache, quell'oggetto sarebbe stato aggiunto anche a qualche tipo di tabella hash gestita dal framework di cache.

Se il server delle applicazioni era in esecuzione su più nodi, potrebbe essere necessario anche il supporto per la memorizzazione nella cache distribuita. In un sistema di cache distribuita, quando aggiungi un oggetto nella cache su AppServer1, quell'oggetto è disponibile anche su AppServer2 e AppServer3. Le cache Java tradizionali utilizzano la replica per la memorizzazione nella cache distribuita, il che significa che quando aggiungi una voce cache su AppServer1, questa viene automaticamente replicata sugli altri server app nel tuo sistema. Di conseguenza, la voce sarà disponibile su tutti i tuoi nodi.

Utilizzando Memcached

Per utilizzare Memcached per la memorizzazione nella cache è necessario prima scaricare e installare il server Memcached per la piattaforma scelta. Una volta installato, il server Memcached ascolterà su una porta TCP o UDP per le chiamate in cache.

Successivamente, scaricherai un client Java per Memcached e aggiungerai i JAR client alla tua applicazione. Successivamente, è possibile creare un oggetto client Memcached e iniziare a chiamare il suo metodo per ottenere e impostare le voci della cache. Quando aggiungi un oggetto alla cache, il client Memcached prenderà quell'oggetto, lo serializzerà e invierà un array di byte al server Memcached per l'archiviazione. A quel punto, l'oggetto memorizzato nella cache potrebbe essere sottoposto a Garbage Collection dalla JVM in cui è in esecuzione l'applicazione.

Quando hai bisogno di quell'oggetto memorizzato nella cache, puoi chiamare il get()metodo del client Memcached . Il client prenderà la getrichiesta, la serializzerà e la invierà al server Memcached. Il server Memcached utilizzerà la richiesta per cercare l'oggetto dalla cache. Una volta che ha l'oggetto, restituirà la matrice di byte al client Memcached. L'oggetto client Memcached prenderà quindi l'array di byte e lo deserializzerà per creare l'oggetto e restituirlo all'applicazione.

Anche se la tua applicazione è in esecuzione su più di un application server, tutti possono puntare allo stesso server Memcached e usarlo per ottenere e impostare le voci della cache. Se hai più di un server Memcached, i server non si conosceranno l'un l'altro. Invece, configurerai il tuo client Memcached in modo che conosca tutti i server Memcached disponibili. Ad esempio, se la tua applicazione crea un oggetto Java su AppServer1 e chiama il set()metodo di Memcached, il client Memcached capirà a quale server Memcached va quella voce. Inizierà quindi a comunicare solo con quel server Memcached. Allo stesso modo, quando il codice in AppServer2 o AppServer3 tenta di getimmettere una voce, il client Memcached capirà prima su quale server è archiviata quella voce, quindi comunicherà solo con quel server.

Logica client memcached

Nella sua configurazione predefinita, il client Memcached utilizza una logica molto semplice per selezionare il server per un'operazione di recupero o impostazione. Quando si effettua una chiamata get()o set(), il client prende la chiave della cache e chiama il suo hashCode()metodo per ottenere un numero intero come 11. Quindi prende quel numero e lo divide per il numero di server Memcached disponibili, diciamo due. Quindi prende il valore del resto, che in questo caso è 1. La voce della cache andrà al server Memcached 1. Questo semplice algoritmo garantisce che il client Memcached su ciascuno dei server delle applicazioni scelga sempre lo stesso server per una determinata chiave di cache.

Installazione di Memcached

Memcached funziona su Unix, Linux, Windows e MacOSX. Puoi scaricare il sorgente Memcached e compilarlo oppure puoi scaricare i binari compilati da qualcun altro e usarli per installare Memcached. Qui illustrerò il processo di download dei binari per la piattaforma di tua scelta; vedi Risorse se preferisci compilare dal sorgente.

Le seguenti istruzioni di installazione si riferiscono a una macchina Windows XP a 32 bit. Vedi Risorse per le istruzioni di installazione per altre piattaforme come Linux. Si noti inoltre che il codice di esempio per questo articolo è stato sviluppato su un computer Windows XP a 32 bit, sebbene dovrebbe funzionare su qualsiasi altra piattaforma.

  1. Il codice Jellycan ha una versione modificata di Memcached con cui è facile ed efficiente lavorare. Inizia qui scaricando il file ZIP binario di win32
  2. Espandi Memcached--win32-bin.zipsul tuo disco rigido. Nota che tutto ciò che contiene è memcached.exe. Esegui questo file per avviare il server Memcached.
  3. Ora esegui memcached.exe -d installper registrare memcached.exe come servizio. Sarai in grado di utilizzare la console dei servizi per avviare e arrestare il server Memcached.

Avvio / arresto CL

Prova ad avviare e arrestare il server Memcached dalla riga di comando anziché da un pannello dei servizi. Ciò ti darà maggiore flessibilità per provare diverse opzioni della riga di comando e capire la migliore configurazione possibile per le tue esigenze.

Quando si esegue memcached.exesenza alcuna opzione della riga di comando, per impostazione predefinita il server Memcached si avvierà sulla porta 11211 con 64 MB di memoria. In alcuni casi potresti voler avere un controllo più granulare della configurazione. Ad esempio, supponiamo che la porta 11211 sia utilizzata da un altro processo sulla tua macchina e desideri che il server Memcached utilizzi la porta 12000; oppure, se avvii il server Memcached in un ambiente di QA o di produzione, dovresti dargli più memoria rispetto ai 64 MB predefiniti. In questi casi è possibile utilizzare le opzioni della riga di comando per personalizzare il comportamento del server. L'esecuzione del memcache.exe -helpcomando produrrà un elenco completo di opzioni della riga di comando come quelle mostrate nella Figura 3.

Connettiti con Memcached tramite Telnet

Dopo che il server Memcached è stato avviato, ascolta sulla porta a cui è stato assegnato. Il client Memcached si connette al server sulla porta TCP o UDP, invia comandi e riceve risposte e alla fine chiude la connessione. (Vedere Risorse per i dettagli del protocollo che il client utilizza per comunicare con il server.)

Puoi connetterti al tuo server Memcached in molti modi. Se stai utilizzando un client Java, come faremo nella seconda metà di questo tutorial, sarai in grado di accedere a una semplice API per archiviare e ottenere oggetti dalla cache. In alternativa, è possibile utilizzare un client Telnet per connettersi direttamente al server. Sapere come utilizzare il client Telnet per comunicare con il server Memcached è importante per il debug del client Java, quindi inizieremo da lì.

Comandi Telnet

Per prima cosa dovrai utilizzare il client Telnet di tua scelta per connetterti al server Memcached. Su una macchina Windows XP, puoi semplicemente eseguire telnet localhost 11211assumendo che il server Memcached sia in esecuzione sulla stessa macchina e in ascolto sulla porta 11211 predefinita. I seguenti comandi sono essenziali per lavorare con Memcached tramite Telnet:

  • setaggiunge un nuovo elemento alla cache. La chiamata è: Set . È possibile digitare il valore effettivo che deve essere memorizzato nella riga successiva. Se non si desidera che la voce della cache scada, immettere 0 come valore.
  • getrestituisce il valore della chiave della cache. Utilizzare get per ottenere il valore di keyName.
  • addaggiunge una nuova chiave solo se non esiste già. Per esempio:add
  • replacesostituirà un valore solo se la chiave esiste. Per esempio:replace
  • deleteelimina la voce della cache per la chiave. È possibile utilizzare la chiamata delete per eliminare il valore di keyName.

Lo screenshot nella Figura 4 rappresenta un esempio di interazione con il server Memcached tramite Telnet. Come si può vedere, il server Memcached fornisce un feedback ad ogni comando, come ad esempio STORED, NOT_STOREDe così via.

Conclusione alla parte 1

Finora abbiamo discusso brevemente le differenze tra l'architettura distribuita di Memcached ei più tradizionali sistemi di cache Java. Abbiamo anche impostato un'implementazione Memcached nel tuo ambiente di sviluppo e hai praticato la connessione a Memcached tramite Telnet. Nella parte successiva di questo tutorial utilizzeremo il client Java spymemcached per configurare una soluzione di cache distribuita per un'applicazione Java di esempio. Durante il processo, imparerai molto di più su Memcached e su come può migliorare le prestazioni delle tue applicazioni Java EE.

Sunil Patil è un architetto Java EE che lavora per Avnet Technology a San Francisco, California. È autore di Java Portlets 101 (SourceBeat, aprile 2007) e ha scritto numerosi articoli pubblicati da JavaWorld, IBM developerWorks e O'Reilly Media. Oltre ad essere uno sviluppatore e amministratore di applicazioni WebSphere Portal Server certificato da IBM, è un programmatore Java certificato da Sun Microsystems, uno sviluppatore di componenti Web e uno sviluppatore di componenti aziendali. È possibile visualizzare il blog di Sunil su //www.webspherenotes.com.