Membase Java 教程


Membase 是一个NOSQL数据库。它被设计为在MEMCACHED(一个流行的内存缓存工具)之后的一个持久化存储。Membase相对比较新但是已经在高性能NOSQL世界有了一个扎实的落脚点。

本文是一个通过JAVA使用Membase数据库的快速教程。


安装MEMBASE


参考Membase.org的说明


客户端


与Membase的交互类似与Memcached的交互。我们将会使用SpyMemcached Java 客户端。请从 这儿下载。


代码


本项目中所有用到的代码都提供在GitHub : https://github.com/sujee/membase-tutorial
这一个elipse工程,并且已经可以运行。


让我们开始


这儿的JAVA代码-它将一串key,value写入Membase并且再将他们读取出来。

// MembaseTest1 package tutorial;import java.net.InetSocketAddress;import net.spy.memcached.MemcachedClient;/*** Write / Read from Membase* * @author sujee**/public class MembaseTest1{    static int MAX = 100;    static String server = "localhost";    static int port = 11211;     public static void main(String[] args) throws Exception    {        MemcachedClient cache = new MemcachedClient(new InetSocketAddress(server, port));        cache.flush(); // 清除所有         long t1 = System.currentTimeMillis();        for (int i = 0; i < MAX; i++)        {            String s = new Integer(i).toString();            // key : integer converted to String (keys are always string)            // time to live : in seconds, 3600 seconds (1h), 0 means no expiration            // value : actual integer. This can be an object. Our integer will be converted to 'Integer'            // class by 'auto boxing' proess            Object o = cache.set(s, 0, i);            System.out.println("cache put : " + s + " : " + i + ", result " + o);        }        long t2 = System.currentTimeMillis();        System.out.println("Time for " + MAX + " puts is " + (t2 - t1) + " ms");         t1 = System.currentTimeMillis();        int nulls = 0;        for (int i = 0; i < MAX; i++)        {            String s = new Integer(i).toString();            Object o = cache.get(s);            System.out.println("Cache get : " + s + " : " + o);            if (o == null)                nulls++;        }        t2 = System.currentTimeMillis();        cache.shutdown();        System.out.println("Time for " + MAX + " gets is " + (t2 - t1) + " ms. nulls " + nulls);    }} 你可以在eclipse中运行这个文件(MembaseTest1)。或者从命令行执行
         sh compile.sh          sh run.sh              or           java -cp classes/:lib/memcached-2.5.jar tutorial.MembaseTest1
Membase运行在本地,端口为11211(默认的memcached端口)

我们在一开始就清洗了整个数据集,这样我们就可以有个干净的初始环境。

Set

cache.set (string_key,   expiration_time,   object_value)

我们的键是一串字符型的数字,我们的对象是是整数型对象。

下面是输出样例:


2010-11-29 23:36:33.234 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=localhost/127.0.0.1:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2010-11-29 23:36:33.240 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@b34bed0
cache put : 0 : 0,  result net.spy.memcached.internal.OperationFuture@578088c0
cache put : 1 : 1,  result net.spy.memcached.internal.OperationFuture@37922221
cache put : 2 : 2,  result net.spy.memcached.internal.OperationFuture@5afec107
cache put : 3 : 3,  result net.spy.memcached.internal.OperationFuture@b32e13d
cache put : 4 : 4,  result net.spy.memcached.internal.OperationFuture@39617189
cache put : 5 : 5,  result net.spy.memcached.internal.OperationFuture@2c64f6cd
...
...



Spy Memcache 客户端缓存了很多操作,这样可以提升性能。你可以看到cache.set方法返回了一个 'OperartionFuture' 对象。key-value最终将会在Membase中持久化。

Get

现在我们试着看看我们刚写的读取语句。 我们用了同样的客户端。输出结果就像下面所示:

Cache get : 96 : 96
Cache get : 97 : 97
Cache get : 98 : 98
Cache get : 99 : 99
Time for 100 gets is 77 ms.  nulls 0

我们密切注意NULL值。我们这次不应该获得NULL,如我们所希望的null个数为0。

代码也记录了时间戳,我们可以看到操作是多么得快。



模拟多个客户端


在上面的例子中我们从同一个客户端进行读写。但在实际场景中,多个客户端都会对Membase进行读写。现在我们用两个不同的客户端连接模拟这种情况。
在这个版本中,我们使用一个连接进行写操作另一个连接进行读操作。

// MembaseTest2package tutorial; import java.net.InetSocketAddress;import net.spy.memcached.MemcachedClient; /*** simulates writing / reading from two different clients*/public class MembaseTest2{    static int MAX = 1000;    static String server = "localhost";    static int port = 11211;     public static void main(String[] args) throws Exception    {        MemcachedClient cache = new MemcachedClient(new InetSocketAddress(server, port));        cache.flush(); // clear all         long t1 = System.currentTimeMillis();        for (int i = 0; i < MAX; i++)        {            String s = new Integer(i).toString();              // key : integer converted to String (keys are always string)            // time to live : in seconds, 3600 seconds (1h), 0 means no expiration            // value : actual integer. This can be an object. Our integer will be converted to 'Integer'            // class by 'auto boxing' proess            Object o = cache.set(s, 0, i);            System.out.println("cache put : " + s + " : " + i + ", result " + o);        }        long t2 = System.currentTimeMillis();        cache.shutdown(); // close the client        System.out.println("Time for " + MAX + " puts is " + (t2 - t1) + " ms");         // open another connection        cache = new MemcachedClient(new InetSocketAddress(server, port));         t1 = System.currentTimeMillis();        int nulls = 0;        for (int i = 0; i < MAX; i++)        {            String s = new Integer(i).toString();            Object o = cache.get(s);            System.out.println("Cache get : " + s + " : " + o);            if (o == null)                nulls++;        }        t2 = System.currentTimeMillis();        cache.shutdown();         System.out.println("Time for " + MAX + " gets is " + (t2 - t1) + " ms. nulls " + nulls + "\n");    }}
  java -cp classes/:lib/memcached-2.5.jar tutorial.MembaseTest2

Cache get : 0 : 0
Cache get : 1 : 1
.......
.....
Cache get : 997 : null
Cache get : 998 : null
Cache get : 999 : null
Time for 1000 gets is 540 ms.  nulls 42


现在就能看到一个情况,当我们读取刚刚设置的值的时候,就会有NULL产生的情况了。

那么这儿到底发生了些什么了?

请记住,Spy Memcache客户端为了提高性能缓存了不少操作。当我们调用“shutdown”的时候客户端没有把所有的缓存值写入数据库就退出了。所以这些键值就很简单的丢失了。

让我们修正这个问题。

当我们做完SET操作, 让我们更优雅的关闭这个客户端。我们给他10秒的时间再退出。希望这样可以让客户端有机会把所有的缓存操作都执行完成。

......long t2 = System.currentTimeMillis();cache.shutdown(10, TimeUnit.SECONDS); // graceful shutdownSystem.out.println("Time for " + MAX + " puts is " + (t2 - t1) + " ms"); // open another connectioncache = new MemcachedClient(new InetSocketAddress(server, port));......

java -cp classes/:lib/memcached-2.5.jar tutorial.MembaseTest3

output: 
...
...
Cache get : 998 : 998
Cache get : 999 : 999
Time for 1000 gets is 500 ms.  nulls 0

没有任何NULL值。我们获得了所有写入的值。

所以现在我们很成功的模拟了多个客户端的情况。有一件事情需要记住,客户端做了缓存所以需要优雅的关闭它保证没有数据丢失。

相关内容