
This is continued tutorial on Memcached which is distributed memory object caching server. Here are previous two tutorials before you go over this one.
- How to Install and Configure Memcached
- Memcached Java Client Tutorial using net.spy.spymemcached Library
In this tutorial we will go over Memcached Java Client using below two approaches:
com.whalin.Memcached-Java-Client Library
<dependency> <groupId>com.whalin</groupId> <artifactId>Memcached-Java-Client</artifactId> <version>3.0.2</version> </dependency>
com.googlecode.xmemcached Library
<dependency> <groupId>com.googlecode.xmemcached</groupId> <artifactId>xmemcached</artifactId> <version>2.4.5</version> </dependency>
Just add these two maven dependencies to your project’s pom.xml file to get library in your Eclipse workspace.
Here is a complete CrunchifyComWhalinXMemcachedClient.java program with all details.
package crunchify.java.tutorials;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.whalin.MemCached.MemCachedClient;
import com.whalin.MemCached.SockIOPool;
import net.rubyeye.xmemcached.XMemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;
/**
 * @author Crunchify.com 
 * Version: 1.2.4 
 * Details: Use dependency com.whalin.Memcached-Java-Client and com.googlecode.xmemcached to retrieve, store Key Value pair
 *         from MemCached Server
 */
public class CrunchifyComWhalinXMemcachedClient {
	public static void main(String[] args) {
		log("===================================== Approach-1: Using SpyMemcahed: https://crunchify.com/memcached-java-client-net-spy-spymemcached/ ===================================== \n");
		log("===================================== Approach-2: Using com.whalin.Memcached-Java-Client =====================================\n");
		implementWhalinMemcachedJavaClient();
		log("===================================== Approach-3: Using com.googlecode.xmemcached Method =====================================\n");
		implementXMemCachedClient();
		log("===================================== Program Completed ===================================== \n");
	}
	// Approach-1: Using SpyMemcahed: https://crunchify.com/memcached-java-client-net-spy-spymemcached/
	// Approach-2: Using com.whalin.Memcached-Java-Client
	private static void implementWhalinMemcachedJavaClient() {
		String[] servers = { "localhost:11211" };
		// This class is a connection pool for maintaning a pool of persistent connections to memcached servers.
		// The pool must be initialized prior to use. This should typically be early on in the lifecycle of the JVM instance.
		SockIOPool crunchfiyPool = SockIOPool.getInstance("Crunchify");
		// Sets the minimum number of spare connections to maintain in our available pool.
		crunchfiyPool.setMinConn(2);
		// Sets the maximum number of spare connections allowed in our available pool.
		crunchfiyPool.setMaxConn(20);
		// Sets the list of all cache servers.
		crunchfiyPool.setServers(servers);
		// Sets the failover flag for the pool. If this flag is set to true, and a socket fails to connect, the pool will attempt to return a socket from
		// another server if one exists.
		// If set to false, then getting a socket will return null if it fails to connect to the requested server.
		crunchfiyPool.setFailover(true);
		// Sets the initial number of connections per server in the available pool.
		crunchfiyPool.setInitConn(30);
		// Set the sleep time between runs of the pool maintenance thread. If set to 0, then the maint thread will not be started.
		crunchfiyPool.setMaintSleep(90);
		// Sets the socket timeout for reads.
		crunchfiyPool.setSocketTO(2000);
		// Sets the aliveCheck flag for the pool. When true, this will attempt to talk to the server on every connection checkout to make sure the connection is
		// still valid.
		crunchfiyPool.setAliveCheck(true);
		crunchfiyPool.initialize();
		// Creates a new instance of MemCachedClient accepting a passed in pool name.
		MemCachedClient crunchifyWhalinClient = new MemCachedClient("Crunchify");
		// Adds data to the server; only the key and the value are specified.
		crunchifyWhalinClient.add("Java", "Crunchify.com");
		crunchifyWhalinClient.add("WordPress", "WordPress.com");
		crunchifyWhalinClient.add("Social", "Facebook.com");
		log("==> Total 3 Records added to MemCached using com.whalin.Memcached-Java-Client Method\n");
		// Retrieve a key from the server, using a specific hash. 
		// If the data was compressed or serialized when compressed, it will automatically be decompressed or serialized, as appropriate..
		log("Key: Java, Value: " + crunchifyWhalinClient.get("Java"));
		log("Key: WordPress, Value: " + crunchifyWhalinClient.get("WordPress"));
		log("Key: Social, Value: " + crunchifyWhalinClient.get("Social"));
		log("==> Total 3 Records Retrieved from MemCached using com.whalin.Memcached-Java-Client Method\n");
		// Deletes an object from cache given cache key.
		crunchifyWhalinClient.delete("Social");
		log("==> Record deleted using com.whalin.Memcached-Java-Client Method\n");
		log("Key: Social, Value: " + crunchifyWhalinClient.get("Social"));
		log("==> Failure to get record Social as we deleted that before\n");
	}
	// Approach-3: Using com.googlecode.xmemcached
	private static void implementXMemCachedClient() {
		String city = "New York";
		String city2 = "San Francisco";
		try {
			// XMemcached constructor,default weight is 1
			XMemcachedClient xMemCachedclient = new XMemcachedClient("localhost", 11211);
			// Set a value
			xMemCachedclient.set("Crunchify", 3600, city);
			xMemCachedclient.set("Twitter", 3600, city2);
			// Get a value for specify key
			Object myCity = xMemCachedclient.get("Twitter");
			log("=====> Key: Twitter, Value: " + xMemCachedclient.get("Twitter") + "\n");
			// Get a value for specify key (set timeout of three seconds)
			myCity = xMemCachedclient.get("Crunchify", 3000);
			log("=====> Key: Crunchify, Value: " + xMemCachedclient.get("Crunchify", 3000) + "\n");
			// Set a new expiration time for an existing item,using default opTimeout second.
			xMemCachedclient.touch("key", 30);
			xMemCachedclient.delete("Crunchify");
			log("=====> Key: Crunchify, Value: " + xMemCachedclient.get("Crunchify") + "\n");
			// delete value
			xMemCachedclient.delete("key");
			// let's catch all exceptions
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MemcachedException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	// Simple log utility
	private static void log(Object object) {
		System.out.println(object);
	}
}
Make sure you have Memcached server up and running.
bash-3.2$ memcached -d -p 11211
Just run above command in Eclipse to see below result.
===================================== Approach-1: Using SpyMemcahed: https://crunchify.com/memcached-java-client-net-spy-spymemcached/ ===================================== ===================================== Approach-2: Using com.whalin.Memcached-Java-Client ===================================== SLF4J: The requested version 1.7.16 by your slf4j binding is not compatible with [1.6] SLF4J: See http://www.slf4j.org/codes.html#version_mismatch for further details. ==> Total 3 Records added to MemCached using com.whalin.Memcached-Java-Client Method Key: Java, Value: Crunchify.com Key: WordPress, Value: WordPress.com Key: Social, Value: Facebook.com ==> Total 3 Records Retrieved from MemCached using com.whalin.Memcached-Java-Client Method 18:27:35.433 [main] DEBUG com.whalin.MemCached.MemCachedClient - ++++ deletion of key: Social from cache was a success ==> Record deleted using com.whalin.Memcached-Java-Client Method Key: Social, Value: null ==> Failure to get record Social as we deleted that before ===================================== Approach-3: Using com.googlecode.xmemcached Method ===================================== 18:27:35.456 [main] INFO net.rubyeye.xmemcached.XMemcachedClient - XMemcachedClient is using Text protocol 18:27:35.491 [main] INFO com.google.code.yanf4j.nio.impl.SelectorManager - Creating 8 reactors... 18:27:35.496 [main] INFO com.google.code.yanf4j.core.impl.AbstractController - The Controller started at localhost/127.0.0.1:0 ... 18:27:35.509 [Xmemcached-Reactor-0] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - session started 18:27:35.510 [Xmemcached-Reactor-0] INFO com.google.code.yanf4j.core.impl.AbstractController - Add a session: 127.0.0.1:11211 18:27:35.513 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingset Crunchify 0 3600 8 New York 18:27:35.514 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:set Crunchify 0 3600 8 New York 18:27:35.514 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=34,capacity=34 ] 18:27:35.515 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 8 bytes from channel 18:27:35.515 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingset Twitter 0 3600 13 San Francisco 18:27:35.515 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:set Twitter 0 3600 13 San Francisco 18:27:35.515 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=38,capacity=38 ] 18:27:35.515 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 8 bytes from channel 18:27:35.516 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingget Twitter 18:27:35.517 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:get Twitter 18:27:35.517 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=13,capacity=13 ] 18:27:35.518 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingget Twitter 18:27:35.518 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 40 bytes from channel 18:27:35.518 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:get Twitter 18:27:35.518 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=13,capacity=13 ] =====> Key: Twitter, Value: San Francisco 18:27:35.518 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 40 bytes from channel 18:27:35.519 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingget Crunchify 18:27:35.519 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:get Crunchify 18:27:35.519 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=15,capacity=15 ] 18:27:35.519 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 36 bytes from channel 18:27:35.519 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingget Crunchify 18:27:35.519 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:get Crunchify 18:27:35.519 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=15,capacity=15 ] =====> Key: Crunchify, Value: New York 18:27:35.520 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 36 bytes from channel 18:27:35.520 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingtouch key 30 18:27:35.520 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:touch key 30 18:27:35.520 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=14,capacity=14 ] 18:27:35.520 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 11 bytes from channel 18:27:35.520 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingdelete Crunchify 18:27:35.520 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:delete Crunchify 18:27:35.521 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=18,capacity=18 ] 18:27:35.521 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 9 bytes from channel 18:27:35.521 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingget Crunchify 18:27:35.521 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:get Crunchify 18:27:35.521 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=15,capacity=15 ] =====> Key: Crunchify, Value: null 18:27:35.521 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 5 bytes from channel 18:27:35.521 [main] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - After encodingdelete key 18:27:35.521 [Xmemcached-Reactor-2] DEBUG net.rubyeye.xmemcached.impl.Optimizer - Optimieze merge buffer:delete key 18:27:35.521 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - send buffers: [ buffer:position=0,limit=12,capacity=12 ] ===================================== Program Completed ===================================== 18:27:35.522 [Xmemcached-Reactor-2] DEBUG com.google.code.yanf4j.core.impl.AbstractSession - read 11 bytes from channel
As you see in above result, it’s easy to retrieve and save value and it’s a fastest way to have central caching solution for your production Java application.
