Cassandra客户端



Cassandra客户端。

1. 前言
关系数据库中允许client通过dirver(JDBC,ADO等)数据访问和检索,如,在java中,JDBC API封装了关系数据库中供应商的实现,提供了数据访问和检索的统一接口(使用Statements, Prepared-Statements, ResultSets等)。然而,在Cassandra中,不存在这样的dirver,它使用Thrift API和Avro RPC框架提供了一个client代码生成层,用户可根据Cassandra提供的.thrift和.genavro文件使用Thrift API(关于thrift介绍,可参见这篇文章:“Thrift框架介绍”)和Avro工具生成需要的语言的client代码。 另外,Cassandra中还有第三方实现的更高层的各种语言的client库(基于Thrift API实现),包括Java, Scala, Ruby, C#, Python, Perl,PHP, C++语言等。
在Cassandra Wiki页面上,有很多的Thrift API或者高层API的实现实例,具体信息可以参考:http://wiki.apache.org/cassandra/ClientExamples 。
本文主要介绍了Thrift API和java高层Hector API,它们的优缺点为:
Thrift API:优点:简单高效,缺点:功能简单,无法提供连接池,错误处理等功能,不适合直接在生产环境使用。
Hector API:优点:提供连接池;1) 提供错误处理,如果连接的节点挂掉了,它会自动寻找下一个可用节点。2) 支持连接池。Cassandra是为高扩张性应用设计的,因而当Cassandra性能下降时,客户端应该支持pool以避免自己的应用程序成为瓶颈,Cassandra采用了apache的3) 支持JMX,这便于进行监控。缺点:1) 不支持多线程的环境 2) keyspace封装过多(数据校验和数据重新封装),如果进行大量的数据操作,这里的消耗需要考虑。3) 错误处理不够人性化:如果所有的Cassandra Service都非常繁忙,那么经过多次操作失败后,最终的结果失败。
2. Thrift API
Thrift API是最原始的API,要知道它的使用方法,先要了解它的thrift文件描述,位置是cassandra安装目录下的interface文件夹中的cassandra.thrift文件。更多关于thrift接口的介绍,可参考:http://wiki.apache.org/cassandra/API。
编译cassandra.thrift生成相应的客户端代码(在源代码的interface文件夹下有预先生成java代码)后,用户可调用这些代码完成自己的功能。
下面是client的JAVA代码实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.util.List;

import java.io.UnsupportedEncodingException;

import org.apache.thrift.transport.TTransport;

import org.apache.thrift.transport.TFramedTransport;

import org.apache.thrift.transport.TSocket;

import org.apache.thrift.protocol.TProtocol;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.TException;

import org.apache.cassandra.service.*;

public class CClient

{

public static void main(String[] args)

throws TException, InvalidRequestException, UnavailableException, UnsupportedEncodingException, NotFoundException

{

TTransport tr = new TFramedTransport(new TSocket(“localhost”, 9160));

TProtocol proto = new TBinaryProtocol(tr);

Cassandra.Client client = new Cassandra.Client(proto);

tr.open();

 

String key_user_id = “1″;

// insert data

long timestamp = System.currentTimeMillis();

client.insert(“Keyspace1″,

key_user_id,

new ColumnPath(“Standard1″, null, “name”.getBytes(“UTF-8″)),

“Chris Goffinet”.getBytes(“UTF-8″),

timestamp,

ConsistencyLevel.ONE);

client.insert(“Keyspace1″,

key_user_id,

new ColumnPath(“Standard1″, null, “age”.getBytes(“UTF-8″)),

“24″.getBytes(“UTF-8″),

timestamp,

ConsistencyLevel.ONE);

// read single column


ColumnPath path = new ColumnPath(“Standard1″, null, “name”.getBytes(“UTF-8″));

System.out.println(client.get(“Keyspace1″, key_user_id, path, ConsistencyLevel.ONE));

// read entire row

SlicePredicate predicate = new SlicePredicate(null, new SliceRange(new byte[0], new byte[0], false, 10));

ColumnParent parent = new ColumnParent(“Standard1″, null);

List<ColumnOrSuperColumn> results = client.get_slice(“Keyspace1″, key_user_id, parent, predicate, ConsistencyLevel.ONE);

for (ColumnOrSuperColumn result : results)

{

Column column = result.column;

System.out.println(new String(column.name, “UTF-8″) + ” -> ” + new String(column.value, “UTF-8″));

}

tr.close();

}

}
3. Hector API
下面是从博客http://prettyprint.me/中摘录的一个Hector应用实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Create a cluster

Cluster c = HFactory.getOrCreateCluster(“MyCluster”, “cassandra1:9160″);

// Choose a keyspace

KeyspaceOperator ko = HFactory.createKeyspaceOperator(“Keyspace1″, c);

// create an string extractor.

StringExtractor se = StringExtractor.get();

// insert value

Mutator m = HFactory.createMutator(keyspaceOperator);

m.insert(“key1″, “ColumnFamily1″, createColumn(“column1″, “value1″, se, se));

// Now read a value

// Create a query

ColumnQuery<String, String> q = HFactory.createColumnQuery(keyspaceOperator, se, se);

// set key, name, cf and execute

Result<HColumn<String, String>> r = q.setKey(“key1″).

setName(“column1″).

setColumnFamily(“ColumnFamily1″).

execute();

// read value from the result

HColumn<String, String> c = r.get();

String value = c.getValue();

System.out.println(value);
4. 参考资料
(1) 博客:http://prettyprint.me/
(2) “谈谈cssandra的客户端”:

http://blog.csdn.net/gpcuster/archive/2010/03/23/5410173.aspx

(3) Cassandra各种客户端库汇总:http://wiki.apache.org/cassandra/ClientOptions06
原创文章,转载请注明: 转载自董的博客