Cassandra – 数据库启动和访问

使用最新的2.0.3版本,解压后进入文件目录启动Cassadra,注意:如果不带-f参数,在MAC OS X系统中Cassandra会在后台运行,Ctrl+C也无法关闭。

$ bin/cassandra -f
>> Startup completed! Now serving reads.

Cassandra的文件包中,bin下有自带的数据库操作命令行工具cassandra-cli,lib中有可供Java编程访问的Driver.我们先介绍命令行工具的基本数据库操作:

$ bin/cassandra-cli
>> Connected to: "Test Cluster" on 127.0.0.1/9160
Welcome to Cassandra CLI version 2.0.3

The CLI is deprecated and will be removed in Cassandra 3.0.  Consider migrating to cqlsh.
CQL is fully backwards compatible with Thrift data; see http://www.datastax.com/dev/blog/thrift-to-cql3

Type 'help;' or '?' for help.
Type 'quit;' or 'exit;' to quit.

>> [default@unknown]

Key space类似于数据库的概念,首先需要创建一个Key space.

$ create keyspace testkeyspace;
>> cd74ab35-72c3-3c72-a9ef-51a8a17bca18

Cassandra是列数据库,创建Column family

$ use testkeyspace;
>> Authenticated to keyspace: testkeyspace
$ create column family testcolumnfamily;
>> adc59964-8f3a-3a80-bc65-f692405b5278

写入数据,在此之前先设置Cassandra的字符类型,否则行列名称会无法识别:

$ assume testcolumnfamily keys as utf8;
$ assume testcolumnfamily comparator as utf8;
$ assume testcolumnfamily validator as utf8;
$ set testcolumnfamily['row']['column1'] = 'avalue';
>> Value inserted.
Elapsed time: 35 msec(s).

Cassandra有一个很有趣的功能,自动删除数据,下面是设置10秒后删除数据:

$ set testcolumnfamily['row']['column2'] = 'bvalue' with ttl = 10;
>> Value inserted.
Elapsed time: 35 msec(s).

查看数据

$ list testcolumnfamily
>> RowKey: row
=> (name=column1, value=avalue, timestamp=1385639319712)
$ get testcolumnfamily['row']
=> (name=column1, value=avalue, timestamp=1385639319712)

使用Java启动Cassandra服务时,注意要引用所有cassandra/lib下的文件,否则会连续遇到yaml解析错误等问题。
先创建一个Cassandra客户端:

/**
 * User: Justina Chen
 * Date: 11/28/13
 * Time: 5:57 PM
 */
import org.apache.cassandra.thrift.Cassandra;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;

public class FramedConnWrapper {

    private TTransport transport;
    private TProtocol protocol;
    private TSocket socket;

    public FramedConnWrapper(String host, int port) {
        socket = new TSocket(host, port);
        transport = new TFramedTransport(socket);
        protocol = new TBinaryProtocol(transport);
    }

    public void open() throws Exception {
        transport.open();
    }

    public void close() throws Exception {
        transport.close();
        socket.close();
    }

    public Cassandra.Client getClient() {
        Cassandra.Client client = new Cassandra.Client(protocol);
        return client;
    }
}

在单元测试中启动Cassandra内置服务,并测试访问:

/**
 * User: Justina Chen
 * Date: 11/28/13
 * Time: 7:02 PM
 */
import junit.framework.Assert;
import org.apache.thrift.TException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.apache.cassandra.service.*;

public class UtilTest {

    private static EmbeddedCassandraService cassandraService;
    private FramedConnWrapper connWrapper;

    @Before
    public void setUp() throws Exception {
        cassandraService = new EmbeddedCassandraService();
        cassandraService.start();
        connWrapper = new FramedConnWrapper("localhost", 9160);
        connWrapper.open();
    }

    @After
    public void tearDown() throws Exception {
        connWrapper.close();
    }

    @Test
    public void testEmbeddedCassandra() throws TException {
        Assert.assertEquals("Test Cluster", connWrapper.getClient().describe_cluster_name());
    }
}

数据写入:

/**
 * User: Justina Chen
 * Date: 11/28/13
 * Time: 7:11 PM
 */
import java.nio.ByteBuffer;
import java.util.*;
import org.apache.cassandra.thrift.*;

public class GetVMultiGet {

    public static void main (String[] args) throws Exception {
        FramedConnWrapper fcw = new FramedConnWrapper("localhost", 9160);
        fcw.open();

        ColumnParent parent = new ColumnParent();
        parent.setColumn_family("testcolumnfamily");
        ColumnPath path = new ColumnPath();
        path.setColumn_family("testcolumnfamily");
        path.setColumn("column1".getBytes("UTF-8"));

        Column c = new Column();
        fcw.getClient().set_keyspace("testkeyspace");
        c.setName("column1".getBytes());
        c.setTimestamp(System.currentTimeMillis());
        for (int j = 0; j < inserts; j++) {
            byte[] key = (j+"").getBytes();
            ByteBuffer keyBuf = ByteBuffer.wrap(key);
            c.setValue(key);
            fcw.getClient().insert(keyBuf, parent, c, ConsistencyLevel.ALL);
            fcw.getClient().get(keyBuf, path, ConsistencyLevel.ALL);
        }
        long getNanos = System.nanoTime();
        for (int j = 0; j < inserts; j++) {
            byte[] key = (j+"").getBytes();
            c.setValue(key);
            fcw.getClient().get(ByteBuffer.wrap(key), path, ConsistencyLevel.ONE);
        }
        long endGetNanos = System.nanoTime() - getNanos;
        System.out.println("get time " + endGetNanos);
        fcw.close();
    }

}

对Cassandra初次印象是,操作和访问都比较复杂,出错时没有一个清楚的提示,加上文档很少,和其它NoSQL数据库尤其是MongoDB比起来,可用性还比较低。

One thought on “Cassandra – 数据库启动和访问

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>