首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

cassandra学习札记4-Cassandra Java客户端

2012-12-26 
cassandra学习笔记4--Cassandra Java客户端Cassandra在设计的时候,就是支持Thrift的,这意味着我们可以使用

cassandra学习笔记4--Cassandra Java客户端

Cassandra在设计的时候,就是支持Thrift的,这意味着我们可以使用多种语言开发。

对于Cassandra的开发本身而言,这是使用Thrift的好处:支持多语言。坏处也是显而易见的:Thrift API功能过于简单,不具备在生产环境使用的条件。

在Cassandra Wiki页面上,也有基于Thrift API开发的更加高级的API,各个语言都有,具体信息可以参考:http://wiki.apache.org/cassandra/ClientExamples。

这次只谈谈下面两类Java的客户端:

1 Thrift Java API

2 hector

Thrift Java API

这个是Cassandra自带的最简单的一类API,这个文件在apache-cassandra-0.5.1.jar(现在已经升级到0.6.1版本)中包含了。可以直接使用。我们也可以自己安装一个Thrift,然后通过cassandra.thrift文件自动生成。

如果你要使用Cassandra,那么我们必须要了解Thrift API,毕竟所有的其他更加高级的API都是基于这个来包装的。

提供的功能插入数据

插入数据需要指定keyspace,ColumnFamily, Column,Key,Value,timestamp和数据同步级别。

/**
 * Insert a Column consisting of (column_path.column, value, timestamp) at the given column_path.column_family and optional
 * column_path.super_column. Note that column_path.column is here required, since a SuperColumn cannot directly contain binary
 * values -- it can only contain sub-Columns.
 * 
 * @param keyspace
 * @param key
 * @param column_path
 * @param value
 * @param timestamp
 * @param consistency_level
 */
public void insert(String keyspace, String key, ColumnPath column_path, byte[] value, long timestamp, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;
?
/**
 * Insert Columns or SuperColumns across different Column Families for the same row key. batch_mutation is a
 * map<string, list<ColumnOrSuperColumn>> -- a map which pairs column family names with the relevant ColumnOrSuperColumn
 * objects to insert.
 * 
 * @param keyspace
 * @param key
 * @param cfmap
 * @param consistency_level
 */
public void batch_insert(String keyspace, String key, Map<String,List<ColumnOrSuperColumn>> cfmap, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;
读取数据

获取一个查询条件精确的值。

/**
 * Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is
 * the only method that can throw an exception under non-failure conditions.)
 * 
 * @param keyspace
 * @param key
 * @param column_path
 * @param consistency_level
 */
public ColumnOrSuperColumn get(String keyspace, String key, ColumnPath column_path, int consistency_level) throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, TException;
?
/**
 * Perform a get for column_path in parallel on the given list<string> keys. The return value maps keys to the
 * ColumnOrSuperColumn found. If no value corresponding to a key is present, the key will still be in the map, but both
 * the column and super_column references of the ColumnOrSuperColumn object it maps to will be null.
 * 
 * @param keyspace
 * @param keys
 * @param column_path
 * @param consistency_level
 */
public Map<String,ColumnOrSuperColumn> multiget(String keyspace, List<String> keys, ColumnPath column_path, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;

获取某一个keyspace,Key,ColumnFamily,SuperColumn(如果有的话需要指定)下面的相关数据:只查询Column的name符合条件的相关数据(SlicePredicate)。

/**
 * Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name
 * pair) specified by the given SlicePredicate. If no matching values are found, an empty list is returned.
 * 
 * @param keyspace
 * @param key
 * @param column_parent
 * @param predicate
 * @param consistency_level
 */
public List<ColumnOrSuperColumn> get_slice(String keyspace, String key, ColumnParent column_parent, SlicePredicate predicate, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;
?
/**
 * Performs a get_slice for column_parent and predicate for the given keys in parallel.
 * 
 * @param keyspace
 * @param keys
 * @param column_parent
 * @param predicate
 * @param consistency_level
 */
public Map<String,List<ColumnOrSuperColumn>> multiget_slice(String keyspace, List<String> keys, ColumnParent column_parent, SlicePredicate predicate, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;

查询Key的取值范围(使用这个功能需要使用order-preserving partitioner)。

/**
 * @deprecated; use get_range_slice instead
 * 
 * @param keyspace
 * @param column_family
 * @param start
 * @param finish
 * @param count
 * @param consistency_level
 */
public List<String> get_key_range(String keyspace, String column_family, String start, String finish, int count, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;
?
/**
 * returns a subset of columns for a range of keys.
 * 
 * @param keyspace
 * @param column_parent
 * @param predicate
 * @param start_key
 * @param finish_key
 * @param row_count
 * @param consistency_level
 */
public List<KeySlice> get_range_slice(String keyspace, ColumnParent column_parent, SlicePredicate predicate, String start_key, String finish_key, int row_count, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;

查询系统的信息。

/**
 * get property whose value is of type string.
 * 
 * @param property
 */
public String get_string_property(String property) throws TException;
?
/**
 * get property whose value is list of strings.
 * 
 * @param property
 */
public List<String> get_string_list_property(String property) throws TException;
?
/**
 * describe specified keyspace
 * 
 * @param keyspace
 */
public Map<String,Map<String,String>> describe_keyspace(String keyspace) throws NotFoundException, TException;

通过这些操作,我们可以了解到系统的信息。

其中一个比较有意思的查询信息是:token map,通过这个我们可以知道哪些Cassandra Service是可以提供服务的。

删除数据
/**
 * Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note
 * that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire
 * row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.
 * 
 * @param keyspace
 * @param key
 * @param column_path
 * @param timestamp
 * @param consistency_level
 */
public void remove(String keyspace, String key, ColumnPath column_path, long timestamp, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException;

这里需要注意的是,由于一致性的问题。这里的删除操作不会立即删除所有机器上的该数据,但是最终会一致。

程序范例(0.5.1)
import java.util.List;
import java.io.UnsupportedEncodingException;
?
import org.apache.thrift.transport.TTransport;
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 TSocket("localhost", 9160);
????????TProtocol proto = new TBinaryProtocol(tr);
????????Cassandra.Client client = new Cassandra.Client(proto);
????????tr.open();
?
????????String key_user_id = "逖靖寒的世界";
?
????????// insert data
????????long timestamp = System.currentTimeMillis();
????????client.insert("Keyspace1",
??????????????????????key_user_id,
??????????????????????new ColumnPath("Standard1", null, "网址".getBytes("UTF-8")),
??????????????????????"http://gpcuster.cnblogs.com".getBytes("UTF-8"),
??????????????????????timestamp,
??????????????????????ConsistencyLevel.ONE);
????????client.insert("Keyspace1",
??????????????????????key_user_id,
??????????????????????new ColumnPath("Standard1", null, "作者".getBytes("UTF-8")),
??????????????????????"逖靖寒".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();
????}
}
优点与缺点

优点:简单高效

缺点:功能简单,无法提供连接池,错误处理等功能,不适合直接在生产环境使用。

热点排行