Please download the
Sample
Code and Eclipse Project if you're interested in making a
more substantial program that you can run in the Eclipse
development environment. The program will create a user specified
number of threads, that each try to create (or read) 100 random
numbers from Membase. The code creates a MemcachedClient object
instance for each thread, and then proceeds to perform a
gets() operation looking for specific keys. The
gets() operation will return null if the key
has not been set. In this case the thread will create the value
itself and set it into Membase and it will incur a 100 millisecond
penalty for doing so. This simulates an expensive database
operation. You can find the full source code for the small
application attached to the end of this article.
Let's discuss a few parts of the program, so you can understand the fundamentals of connecting to Membase servers, testing for the existence of particular key-value pairs, and setting a value to a key. These few operations will give you more of an idea of how to begin.
Listing 2. Connecting to a set of Membase servers:
65: MemcachedClient client = new MemcachedClient( 66: AddrUtil.getAddresses(addresses));
You can see, from these lines that you'll need to obtain an
instance of a MemcachedClient. There are
numerous ways to construct one, but one constructor that is quite
useful involved the AddrUtil class which parses
comma or space separated lists of server addresses and ports of
the form:
host-or-ip:port host-or-ip:portThe port you will be connecting to will be the MOXI port, 11211 which is effectively a proxy that knows about all of the other servers in the cluster and will provide quick protocol access. So in the case of this cluster, providing an addresses string as follows, worked very well:
String addresses = "10.0.0.33:11211 10.0.0.57:11211";Listing 3 is an abridged excerpt that shows the creation of an IntegerTranscoder, which is a useful class for converting objects in Membase back to integers when needed. This is for convenience and reduces type casting. You can then see a line 82 that a the gets() method is called. This returns a CASValue<T> of type integer which is useful for checking and setting a value. If the value is null it means that membase hasn't been given a value for this key. The code then sets a value. Otherwise, we can get its value and do something with it.
Listing 3. Check And Set operations
67: IntegerTranscoder intTranscoder = new IntegerTranscoder(); 68: 82: CASValue<Integer> value = client.gets(key, 83: intTranscoder); 84: 85: if (value == null) { 86: // The value doesn't exist in Membase 87: client.set(key, 15, rand.nextInt(), intTranscoder); 88: 89: // Simulate the value taking time to create. 90: Thread.sleep(100); 91: 92: created++; 93: 94: } else { 95: 99: int v = value.getValue(); 100: 107: }
Setting values in Membase are done asynchronously, and the
application does not have to wait for these to be completed.
Sometimes, though, you may want to ensure that Membase has been
sent some values, and you can do this by calling
client.waitForQueues() and giving it a timeout
for waiting for this to occur, as shown in Listing 4.
Listing 4. Waiting for the data to be set into Membase.
109: client.waitForQueues(1, TimeUnit.MINUTES);