当前位置: 首页 > 工具软件 > Membase > 使用案例 >

Membase Java 教程

颛孙正卿
2023-12-01
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进行读写。现在我们用两个不同的客户端连接模拟这种情况。
在这个版本中,我们使用一个连接进行写操作另一个连接进行读操作。

// MembaseTest2
package 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 shutdown
System . out . println ( "Time for " + MAX + " puts is " + ( t2 - t1 ) + " ms" );
// open another connection
cache = 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值。我们获得了所有写入的值。

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